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
Syntax:
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.
run
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}
Examples:
print i
print j
print num
(gdb) p i
$1 = 1
(gdb) p j
$2 = 3042592
(gdb) p num
$3 = 3
(gdb)
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.
Gets()
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.
(gdb) x win
0x80491f6 <win>: 0xfb1e0ff3
(gdb) p win
$1 = {<text variable, no debug info>} 0x80491f6 <win>
(gdb)
(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)
(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
共有 0 条评论