Pen Test Practices - Binary Exploitation - NETSEC


Learning, Sharing, Creating

Cybersecurity Memo

Thursday, March 31, 2022

Pen Test Practices - Binary Exploitation

Binary Exploitation is a broad topic within Cyber Security that comes down to finding a vulnerability in the program and exploiting it to gain control of a shell or modifying the program’s functions. The portion of the language that a computer can understand is called a “binary.” Computers operate in binary, meaning they store data and perform calculations using only zeros and ones. A single binary digit can only represent True (1) or False (0) in boolean logic. Each language, has its distinct features, though many times there are commonalities between programming languages. It works on the principle of turning a weakness into an advantage which involves, taking advantage of a bug or vulnerability to cause unintended or unanticipated behavior.

Buffer Overflow

There are two different types of buffer-overflow attacks. These are stack-based and heap-based buffer overflow. In both cases, this type of exploit takes advantage of an application that waits for the user’s input. It can cause the program to crash or execute arbitrary code. A buffer overflow happens when a program tries to fill a block of memory (a memory buffer) with more data than is supposed to hold. Attackers exploit buffer overflow issues by overwriting the memory of an application. Buffer overflows are common vulnerabilities in software applications that can exploit to achieve remote code execution (RCE) or perform a Denial-of-Service (DoS) attack. The simplest and most common buffer overflow is one where the buffer is on the Stack. The most significant cause of buffer overflows is the use of programming languages that do not automatically monitor limits of memory buffer or stack to prevent (stack-based) buffer overflow.

GDB Usage

What is GDB?

GDB, the GNU Project debugger, allows you to see what is going on `inside' another program while it executes -- or what another program was doing at the moment it crashed.

GDB can do four main kinds of things (plus other things in support of these) to help you catch bugs in the act:

  • Start your program, specifying anything that might affect its behavior.
  • Make your program stop on specified conditions.
  • Examine what has happened, when your program has stopped.
  • Change things in your program, so you can experiment with correcting the effects of one bug and go on to learn about another.
Those programs might be executing on the same machine as GDB (native), on another machine (remote), or on a simulator. GDB can run on most popular UNIX and Microsoft Windows variants, as well as on Mac OS X.

What Languages does GDB Support?

GDB supports the following languages (in alphabetical order):
  • Ada
  • Assembly
  • C
  • C++
  • D
  • Fortran
  • Go
  • Objective-C
  • OpenCL
  • Modula-2
  • Pascal
  • Rust

$ chmod +x gdbme
$ gdb gdbme
(gdb) layout asm
(gdb) break *(main+99)
(gdb) run
(gdb) jump *(main+104)

Launch gdb. Launch the C debugger (gdb) as shown below.

$ gdb a.out

Set up a break point inside C program


break line_number
Places break point in the C program, where you suspect errors. While executing the program, the debugger will stop at the break point, and gives you the prompt to debug.

Execute the C program in gdb debugger

run [args]

You can start running the program using the run command in the gdb debugger. You can also give command line arguments to the program via run args. The example program we used here does not requires any command line arguments so let us give run, and start the program execution.

Starting program: /home/sathiyamoorthy/Debugging/c/a.out

Once you executed the C program, it would execute until the first break point, and give you the prompt for debugging.

Printing the variable values inside gdb debugger

Syntax: print {variable}

print i
print j
print num
(gdb) p i
$1 = 1
(gdb) p j
$2 = 3042592
(gdb) p num
$3 = 3

Continue, stepping over and in – gdb commands

There are three kind of gdb operations you can choose when the program stops at a break point. They are continuing until the next break point, stepping in, or stepping over the next program lines.

  • c or continue: Debugger will continue executing until the next break point.
  • n or next: Debugger will execute the next line as single instruction.
  • s or step: Same as next, but does not treats function as a single instruction, instead goes into the function and executes it line by line.

By continuing or stepping through you could have found that the issue is because we have not used the <= in the ‘for loop’ condition checking. So changing that from < to <= will solve the issue.

gdb command shortcuts

Use following shortcuts for most of the frequent gdb operations.

  • l – list
  • p – print
  • c – continue
  • s – step
  • ENTER: pressing enter key would execute the previously executed command again.

Miscellaneous gdb commands

  • l command: Use gdb command l or list to print the source code in the debug mode. Use l line-number to view a specific line number (or) l function to view a specific function.
  • bt: backtrack – Print backtrace of all stack frames, or innermost COUNT frames.
  • help – View help for a particular gdb topic — help TOPICNAME.
  • quit – Exit from the gdb debugger.


Why the gets() is dangerous ??

It’s unsafe because it assumes consistent input. NEVER USE IT! You should not use gets since it has no way to stop a buffer overflow. It doesn’t perform bounds checking on the size of its input. An attacker can easily send arbitrarily-sized input to gets() and overflow the destination buffer. If the user types in more data then will most likely end up with corruption or worse.

Using exam or print to get address of function win.

(gdb) x win
0x80491f6 <win>:        0xfb1e0ff3
(gdb) p win
$1 = {<text variable, no debug info>} 0x80491f6 <win>

(gdb) set disassembly-flavor intel
(gdb) disassemble main
Dump of assembler code for function main:
   0x080492c4 <+0>:     endbr32
   0x080492c8 <+4>:     lea    ecx,[esp+0x4]
   0x080492cc <+8>:     and    esp,0xfffffff0
   0x080492cf <+11>:    push   DWORD PTR [ecx-0x4]
   0x080492d2 <+14>:    push   ebp
   0x080492d3 <+15>:    mov    ebp,esp
   0x080492d5 <+17>:    push   ebx
   0x080492d6 <+18>:    push   ecx
   0x080492d7 <+19>:    sub    esp,0x10
   0x080492da <+22>:    call   0x8049130 <__x86.get_pc_thunk.bx>
   0x080492df <+27>:    add    ebx,0x2d21
   0x080492e5 <+33>:    mov    eax,DWORD PTR [ebx-0x4]
   0x080492eb <+39>:    mov    eax,DWORD PTR [eax]
   0x080492ed <+41>:    push   0x0
   0x080492ef <+43>:    push   0x2
   0x080492f1 <+45>:    push   0x0
   0x080492f3 <+47>:    push   eax
   0x080492f4 <+48>:    call   0x80490b0 <setvbuf@plt>
   0x080492f9 <+53>:    add    esp,0x10
   0x080492fc <+56>:    call   0x8049070 <getegid@plt>
   0x08049301 <+61>:    mov    DWORD PTR [ebp-0xc],eax
   0x08049304 <+64>:    sub    esp,0x4
   0x08049307 <+67>:    push   DWORD PTR [ebp-0xc]
   0x0804930a <+70>:    push   DWORD PTR [ebp-0xc]
   0x0804930d <+73>:    push   DWORD PTR [ebp-0xc]
   0x08049310 <+76>:    call   0x80490d0 <setresgid@plt>
   0x08049315 <+81>:    add    esp,0x10
   0x08049318 <+84>:    sub    esp,0xc
   0x0804931b <+87>:    lea    eax,[ebx-0x1f60]
   0x08049321 <+93>:    push   eax
   0x08049322 <+94>:    call   0x8049080 <puts@plt>
   0x08049327 <+99>:    add    esp,0x10
   0x0804932a <+102>:   call   0x8049281 <vuln>
   0x0804932f <+107>:   mov    eax,0x0
   0x08049334 <+112>:   lea    esp,[ebp-0x8]
   0x08049337 <+115>:   pop    ecx
   0x08049338 <+116>:   pop    ebx
   0x08049339 <+117>:   pop    ebp
   0x0804933a <+118>:   lea    esp,[ecx-0x4]
   0x0804933d <+121>:   ret
End of assembler dump.

(gdb) info register
eax            0x41                65
ecx            0xffffffff          -1
edx            0x41                65
ebx            0x61616161          1633771873
esp            0xffb36250          0xffb36250
ebp            0x61616161          0x61616161
esi            0xf7f03000          -135254016
edi            0xf7f03000          -135254016
eip            0x61616161          0x61616161
eflags         0x10282             [ SF IF RF ]
cs             0x23                35
ss             0x2b                43
ds             0x2b                43
es             0x2b                43
fs             0x0                 0
gs             0x63                99
k0             0x0                 0
k1             0x0                 0
k2             0x0                 0
k3             0x0                 0
k4             0x0                 0
k5             0x0                 0
k6             0x0                 0
k7             0x0                 0


root@ubuntu1:~# python
Python 2.7.18 (default, Mar  8 2021, 13:02:45)
[GCC 9.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> chr(0x6c)

No comments:

Post a Comment