如何将 ASM 文件 assemble 转换为 Linux 64 位上的 x86 shellcode?

How to assemble an ASM file into an x86 shellcode on a Linux 64 bits?

我有以下 ASM 文件:

; Call to sys_chmod
; eax = 15 (0xf)
; ebx = filepath "/tmp/before"
; ecx = mode: 0777 (0x1ff)
xor eax, eax
mov al, 0xf

xor ebx, ebx
push ebx
push dword 0x65726f66
push dword 0x65622f70
push dword 0x6d742f2f
lea ebx, [esp]

mov cx, 0x1ff

int 0x80

nop

简而言之,此 ASM 代码等同于命令 chmod 777 /tmp/before。我想将此代码转换为 x86 shellcode,即:

\x31\xC0\xB0\x0F\x31\xDB\x53\x68\x66\x6F\x72\x65\x68\x70\x2F\x62\x65\x68\x2F\x2F\x74\x6D\x8D\x1C\x24\x66\xB9\xFF\x01\xCD\x80\x90

我使用 online assembler 进行转换,但我希望能够使用我的 Linux 64 位自行完成。

我查看了不同的答案,但其中 none 符合我的要求。例如,在 Compiling 32 bit Assembler on 64 bit ubuntu 中,它使用 nasm 生成一个 elf32。但是这个文件包含的不仅仅是我想要的 shellcode:

$ nasm -f elf32 chmod.asm -o chmod.o
$ xxd chmod.o 
00000000: 7f45 4c46 0101 0100 0000 0000 0000 0000  .ELF............
00000010: 0100 0300 0100 0000 0000 0000 0000 0000  ................
00000020: 4000 0000 0000 0000 3400 0000 0000 2800  @.......4.....(.
00000030: 0500 0200 0000 0000 0000 0000 0000 0000  ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000060: 0000 0000 0000 0000 0100 0000 0100 0000  ................
00000070: 0600 0000 0000 0000 1001 0000 2000 0000  ............ ...
00000080: 0000 0000 0000 0000 1000 0000 0000 0000  ................
00000090: 0700 0000 0300 0000 0000 0000 0000 0000  ................
000000a0: 3001 0000 2100 0000 0000 0000 0000 0000  0...!...........
000000b0: 0100 0000 0000 0000 1100 0000 0200 0000  ................
000000c0: 0000 0000 0000 0000 6001 0000 3000 0000  ........`...0...
000000d0: 0400 0000 0300 0000 0400 0000 1000 0000  ................
000000e0: 1900 0000 0300 0000 0000 0000 0000 0000  ................
000000f0: 9001 0000 0b00 0000 0000 0000 0000 0000  ................
00000100: 0100 0000 0000 0000 0000 0000 0000 0000  ................
00000110: 31c0 b00f 31db 5368 666f 7265 6870 2f62  1...1.Shforehp/b
00000120: 6568 2f2f 746d 8d1c 2466 b9ff 01cd 8090  eh//tm..$f......
00000130: 002e 7465 7874 002e 7368 7374 7274 6162  ..text..shstrtab
00000140: 002e 7379 6d74 6162 002e 7374 7274 6162  ..symtab..strtab
00000150: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000160: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000170: 0100 0000 0000 0000 0000 0000 0400 f1ff  ................
00000180: 0000 0000 0000 0000 0000 0000 0300 0100  ................
00000190: 0063 686d 6f64 2e61 736d 0000 0000 0000  .chmod.asm......

我可以从从偏移量 0x110 开始的生成的 elf32 文件中检索 shellcode,但是是否有最简单的解决方案来获取 shellcode?

正如@fuz 在他的评论中指出的那样,ASM 文件必须包含 [BITS 32] 指令以指定目标处理器模式。它给出:

; Call to sys_chmod
; eax = 15 (0xf)
; ebx = filepath "/tmp/before"
; ecx = mode: 0777 (0x1ff)
[BITS 32]
xor eax, eax
mov al, 0xf

xor ebx, ebx
push ebx
push dword 0x65726f66
push dword 0x65622f70
push dword 0x6d742f2f
lea ebx, [esp]

mov cx, 0x1ff

int 0x80

nop

默认情况下,nasm命令生成二进制文件,不需要提供-f bin选项:

nasm chmod.asm

然后,hexdump可以用来生成正确格式的shellcode:

$ hexdump -v -e '"\""x" 1/1 "%02x" ""' chmod
\x31\xc0\xb0\x0f\x31\xdb\x53\x68\x66\x6f\x72\x65\x68\x70\x2f\x62\x65\x68\x2f\x2f\x74\x6d\x8d\x1c\x24\x66\xb9\xff\x01\xcd\x80\x90