1

I'm writing a Linux shell code exploit. My target C code is:

 char code[] = "\xb0\x01\x31\xdb\xcd\x80";
 int main(int argc, char **argv)
 {
      int(*func)();
      func = (int (*)()) code;

      (Int)(*func)();
 }

Why does compiling and running this C program raise a segmentation fault error? The string is shell code that exits the program using the system call Int 0x80/EAX=1. The original exploit code in assembly is:

b0 01                   mov    al,0x1
31 db                   xor    ebx,ebx
cd 80                   int    0x80
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
KG96
  • 21
  • 4
  • What is `func`? That's probably where the error is occurring. – ack Feb 18 '18 at 00:09
  • I'm new to C. I am trying to run the String using C. @alexquilliam – KG96 Feb 18 '18 at 00:11
  • 2
    Make sure you are in 32 bit linux and that your data section is executable. – Jester Feb 18 '18 at 00:16
  • 4
    Jester is correct Your exploit code is 32-bit using `int 0x80`. If you ever find yourself passing a stack based pointer to a system call in 64-bit code this will likely fail. You really should consider using `syscall` instruction for 64-bit code. You will need to compile with `-z execstack` to have an executable stack. But as important _EAX_ / _RAX_ register may have garbage in the upper bits. before setting _AL_ to 1,do `xor eax, eax` to zero the entire register first. That would be encoded as an extra `\0x31\0xc0` at the beginning of your string. – Michael Petch Feb 18 '18 at 00:47
  • Nobody *anticipates* segmentation violations :-) – paxdiablo Feb 18 '18 at 01:22
  • `-z execstack` will also make the data segment executable when loaded by the dynamic loader. Usually though exploits like this are intended to be done on the stack. You might consider placing `char code[] = "\xb0\x01\x31\xdb\xcd\x80";` inside `main`. – Michael Petch Feb 18 '18 at 01:22
  • @MichaelPetch: Or for testing, use `const char code[] = "...";` to put the array in `.rodata`, which is part of the text segment, not data. – Peter Cordes Feb 18 '18 at 01:49
  • @PeterCordes : Shell exploits are usually done with the stack in mind which is why I really recommend taking the payload and putting it inside the function. Usually such exploits are ultimately targeting the stack. The fact he has it at global scope to me is suspicious for this kind of work. – Michael Petch Feb 18 '18 at 01:51
  • @MichaelPetch: yeah, that's good advice for cases where the exploit depends on EIP being near ESP or something. Otherwise IDK why it would matter. @ KG96: single step with a debugger to see whether the fault is in the `call` to your machine code, or after execution falls off the end of it with `-ENOSYS` or some other error code in eax because you only set the low byte, and previous code left non-zero in the high bytes. – Peter Cordes Feb 18 '18 at 01:53
  • @PeterCordes : makes a difference because usually these progress to overwriting the return address on the stack. Generally you want to move towards that goal. – Michael Petch Feb 18 '18 at 04:11
  • 1
    `(Int)(*func)();` what is **Int** ? – wildplasser Feb 18 '18 at 23:11
  • @paxdiablo: PatchGuard does, uses traps for ordinary control flow. Similarly stack expansion and memory-mapped files rely on faults that are totally expected. – Ben Voigt Feb 18 '18 at 23:21
  • Your shellcode doesn't **ret**urn after execution. Try to add `ret` to shellcode: `"xC3"` – Prime Ape Feb 19 '18 at 08:56
  • @PrimeApe: shellcode isn't usually supposed to return; (in a real exploit, it gets executed in the first place by corrupting the stack). In this case, it's supposed to be invoking `sys_exit`, which (if done correctly) would cause execution not to continue past the `int 0x80`. Adding a `ret` would just hide the problem by exiting via a different mechanism (return from main). Debugging with `gdb` or `strace` is the right approach. – Peter Cordes Feb 19 '18 at 16:16

1 Answers1

1

You are not setting eax=0x1, you are setting al=0x1, so if you don't know what instructions are executed before that your shellcode, you will have eax=xxxxxx01.

As the comments said you, you have to do a xor eax, eax on the beginning of your shellcode.

sinkmanu
  • 1,034
  • 1
  • 12
  • 24