我有这样的ASM:

section .text
    global _start

_start:
    xor  eax, eax
    push eax         ; 0 to finish the /bin//sh string
    push 0x68732f2f  ; //sh
    push 0x6e69622f  ; /bin
    mov  ebx, esp
    mov  al, 0xb
    int  0x80


如果我这样做的话,可以正常工作:

$ nasm -f elf shellcode.asm && ld -o shellcode shellcode.o
$ ./shellcode
$ # the new shell


但是现在,带有十六进制翻译:

$ objdump -s shellcode

shellcode:     file format elf32-i386

Contents of section .text:
  8048060 31c05068 2f2f7368 682f6269 6e89e3b0  1.Ph//shh/bin...
  8048070 0bcd80                               ...


在这里使用:

const char shellcode[] = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80";

int main(){
    (*(void(*)()) shellcode)();
    return 0;
}


结果是:

$ gcc -o shellcode shellcode.c
$ ./shellcode
Segmentation fault


我尝试练习ASM并重新创建此处提供的ASM。我无法解释的区别是,在他的有效负载上,他将一个额外的0/bin//sh字符串的地址推入了堆栈。

我虽然那是因为我正在使用fastcall约定,我不必设置堆栈,但是显然这里还有更多操作。 />

编辑:

当我尝试从gdb运行程序时,我得到以下结果:

$ gdb ./shellcode
(gdb) run
Program received signal SIGSEGV, Segmentation fault.
0x080484b3 in shellcode ()


这是readelf命令的输出:

$ readelf -l -S shellcode
There are 30 section headers, starting at offset 0x1150:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .interp           PROGBITS        08048154 000154 000013 00   A  0   0  1
  [ 2] .note.ABI-tag     NOTE            08048168 000168 000020 00   A  0   0  4
  [ 3] .note.gnu.build-i NOTE            08048188 000188 000024 00   A  0   0  4
  [ 4] .gnu.hash         GNU_HASH        080481ac 0001ac 000020 04   A  5   0  4
  [ 5] .dynsym           DYNSYM          080481cc 0001cc 000040 10   A  6   1  4
  [ 6] .dynstr           STRTAB          0804820c 00020c 000045 00   A  0   0  1
  [ 7] .gnu.version      VERSYM          08048252 000252 000008 02   A  5   0  2
  [ 8] .gnu.version_r    VERNEED         0804825c 00025c 000020 00   A  6   1  4
  [ 9] .rel.dyn          REL             0804827c 00027c 000008 08   A  5   0  4
  [10] .rel.plt          REL             08048284 000284 000010 08   A  5  12  4
  [11] .init             PROGBITS        08048294 000294 000023 00  AX  0   0  4
  [12] .plt              PROGBITS        080482c0 0002c0 000030 04  AX  0   0 16
  [13] .text             PROGBITS        080482f0 0002f0 000192 00  AX  0   0 16
  [14] .fini             PROGBITS        08048484 000484 000014 00  AX  0   0  4
  [15] .rodata           PROGBITS        08048498 000498 00001c 00   A  0   0  4
  [16] .eh_frame_hdr     PROGBITS        080484b4 0004b4 00002c 00   A  0   0  4
  [17] .eh_frame         PROGBITS        080484e0 0004e0 0000b0 00   A  0   0  4
  [18] .init_array       INIT_ARRAY      08049f08 000f08 000004 00  WA  0   0  4
  [19] .fini_array       FINI_ARRAY      08049f0c 000f0c 000004 00  WA  0   0  4
  [20] .jcr              PROGBITS        08049f10 000f10 000004 00  WA  0   0  4
  [21] .dynamic          DYNAMIC         08049f14 000f14 0000e8 08  WA  6   0  4
  [22] .got              PROGBITS        08049ffc 000ffc 000004 04  WA  0   0  4
  [23] .got.plt          PROGBITS        0804a000 001000 000014 04  WA  0   0  4
  [24] .data             PROGBITS        0804a014 001014 000008 00  WA  0   0  4
  [25] .bss              NOBITS          0804a01c 00101c 000004 00  WA  0   0  1
  [26] .comment          PROGBITS        00000000 00101c 00002b 01  MS  0   0  1
  [27] .shstrtab         STRTAB          00000000 001047 000106 00      0   0  1
  [28] .symtab           SYMTAB          00000000 001600 000430 10     29  45  4
  [29] .strtab           STRTAB          00000000 001a30 00024e 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

Elf file type is EXEC (Executable file)
Entry point 0x80482f0
There are 9 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x08048034 0x08048034 0x00120 0x00120 R E 0x4
  INTERP         0x000154 0x08048154 0x08048154 0x00013 0x00013 R   0x1
      [Requesting program interpreter: /lib/ld-linux.so.2]
  LOAD           0x000000 0x08048000 0x08048000 0x00590 0x00590 R E 0x1000
  LOAD           0x000f08 0x08049f08 0x08049f08 0x00114 0x00118 RW  0x1000
  DYNAMIC        0x000f14 0x08049f14 0x08049f14 0x000e8 0x000e8 RW  0x4
  NOTE           0x000168 0x08048168 0x08048168 0x00044 0x00044 R   0x4
  GNU_EH_FRAME   0x0004b4 0x080484b4 0x080484b4 0x0002c 0x0002c R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0x10
  GNU_RELRO      0x000f08 0x08049f08 0x08049f08 0x000f8 0x000f8 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00
   01     .interp
   02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
   03     .init_array .fini_array .jcr .dynamic .got .got.plt .data .bss
   04     .dynamic
   05     .note.ABI-tag .note.gnu.build-id
   06     .eh_frame_hdr
   07
   08     .init_array .fini_array .jcr .dynamic .got



与该shellcode的比较: br />
Hamza (working)     |   me

ASM

xor    eax, eax     |   xor    eax, eax
push   eax          |   push   eax
push   0x68732f2f   |   push   0x68732f2f
push   0x6e69622f   |   push   0x6e69622f
mov    ebx, esp     |   mov    ebx, esp
push   eax          |
push   ebx          |
mov    esp, ecx     |
mov    al, 0xb      |   mov    al, 0xb
int    0x80         |   int    0x80

Stack before the interrupt (each line is a word)

&(/bin//sh)         | /bin
0                   | //sh
/bin                | 0
//sh                |
0                   |

Registers before the interrupt

eax    0xb          |   0xb
ebx    &(/bin//sh)  |   &(/bin//sh)
ecx    esp          |   ?


如您所见,堆栈通过更改字符串的地址和一个额外的0来改变,并将其ecx寄存器设置为最后一个esp值。这些差异使他的shellcode可以正常工作(直接在nasmld以及C程序内部使用,没有任何更改)。


编辑:

有些进步,当有效载荷在C程序中运行时,还有一条额外的指令:中断,请使用ecx清除寄存器可解决此问题。

这是工作中的asm:

评论

可能您的字符串bin,sh没有空终止符,而push 0满足了它

确实如此,这就是为什么我第一次推eax ...

您的数据部分可执行吗?发布readelf -l -S的输出。当您在其中运行已编译的程序时,gdb会怎么说?

嘿@IgorSkochinsky:看我的编辑。看来我的.data是可写和可分配的,但不能执行。可以吗?同样,当我尝试从asm生成的可执行文件中读取elf时,只有可执行的.text标头。

所以根据gdb它确实可以运行。 “将堆栈设置更改为”正确”意味着什么?”

#1 楼

shellcode的问题以及为什么不从C程序运行而为何与众不同的原因是初始值。 br />

eax = 0x0b

ebx = ptr到文件名

ecx = ptr到argv

edx = ptr到环境变量

,但是实际上重要的只有ebxeax,另外两个我们可以将其无效。是0x0,因此我们免费获得ecxedx的无效。



从C程序执行shellcode并非如此。



如您所见,寄存器已经具有一些初始值,因此需要正确准备它们。这就是为什么添加xor ecx,ecx可以解决此问题的原因。

对于您从ecx取得的示例已分配给堆栈指针,但是在堆栈上有一个指向“ / bin / sh”的值也可以(并且甚至可能比0x00更好)

#2 楼

好的,因此根据gdb,shellcode确实可以运行,因此可能已将其放入.text中。您应该尝试逐步浏览Shellcode(例如使用stepi)以查看错误的指令。

评论


好的,我做到了,并且有效负载上还有一条额外的说明,我将发布更新。

– nobe4
17年9月2日在21:03