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

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!

 

 

Officially OSCP Certified

Today I received the wonderful news that I passed the Offensive Security Certified Professional (OSCP) examination and I am now an OSCP. It was definitely the highlight of the day.

The examination consisted of a 24-hour limited to root/system five different machines. After this, you had to submit a penetration test report, and optionally, a lab and course report.

The labs consisted of over 50 machines and various subnets, and came along with the Penetration Testing with Kali Linux (PWK) course and one exam attempt.

I ended up owning 32 machines in the labs and gaining access to the subnets. Although I paid for the 90 days option, I was able to complete everything within 60 days. Having said that, I still recommend the 90 days option as a precaution.

My plan for the exam was the same as for the labs, which you can find here.

The battle plan was as follows:

  • Write the report as I go along
  • Pick the low hanging fruit first
  • Take a break whenever I feel a machine is “too hard”
  • Avoid using Metasploit
  • Build/execute attack tools/exploits that I can reuse
  • Identify the attack vectors and determine which is best, before compromising the system; the best being a balance between reliability, speed, and efficiency
  • Have fun; take a break when things don’t feel very fun anymore

This battle plan worked perfectly for me for both the labs and the exam. With regards to the scripts I wrote, you can find some of them scattered throughout my Github page.

I wrote many little (but very useful) intelligence gathering scripts and many exploit ports to Python. In the Github you will find the intel gathering scripts along with other goodies, though not the particular exploit scripts.

The journey was extremely fun and very rewarding. As many others have stated, one learns the value of proper enumeration/intelligence gathering. A great additional for me was learning about KeepNote, which is a great EverNote-like software available in Kali Linux. Thanks to journey not only did I learn a lot in the technical realm, but also in the report-writing realm. Expect my future write-ups to include proper explanations and screenshots.

I am now officially OSCP certified, and officially looking for penetration testing jobs and other offensive security positions. If you feel you can help me land a job, feel free to reach out! The beer’s on me.

I tried harder.

 

OSCP: Nine Days In, 21 Machines Rooted

It has been nine days since I started the OSCP labs.

I have been having a ton of fun, and have compromised 21 machines so far.

I have been following the battle plan I established when I started the labs, and it was been working beautifully. So that being said, I recommend others considering taking the OSCP to follow my strategy. It has allowed me to have a lot of fun, minimize stress, and learn a ton.

Before starting the OSCP journey, I used to go into CTFs and war games and try out the most common attack vectors (which isn’t such a bad tactic) and just kept on attacking. Now, I have learned the value of proper enumeration and understanding the underlying services and systems. If before my weapon of choice was the machine gun, now it is the sniper rifle. Of course, both have their uses.

Onwards and upwards.

OSCP: Done with the course, Unto the Labs

Two days ago, I completed the PWK course along with the proper reporting of the challenges. The course was a nice introduction to what it takes to perform a penetration test, and it served as a good base to build on with the experience in the labs.

I started the OSCP labs yesterday. I have put in around four hours so far, and I have been able to root three machines already. I am close to rooting another two, having already compromised them, and I plan on “dealing the killing blow” later today. I actually started off by performing a network-wide intelligence-gathering effort. This expedites my attacks going forward, as I have a good information base with which to proceed.

My plan going into the labs is as follows:

  • Write the report as I go along
  • Pick the low hanging fruit first
  • Take a break whenever I feel a machine is “too hard”
  • Avoid using Metasploit
  • Build/execute attack tools/exploits that I can reuse
  • Identify the attack vectors and determine which is best, before compromising the system; the best being a balance between reliability, speed, and efficiency
  • Have fun; take a break when things don’t feel very fun anymore

I will keep you updated on my progress.

OSCP: 80% Done with the PWK Course

I’m currently 80% done with the “Penetration Testing with Kali Linux (PWK)” course that comes as part of the OSCP certification.

Here are my thoughts so far:

  • While I already knew everything that I’ve covered so far, the reporting process has made me gain a deeper understanding of the techniques I use – which is a great plus.
  • Automation is awesome – I already knew this, but I have written scripts to take care of many enumeration tasks and attacks that are necessary yet repetitive.
  • I have become more proficient at file transfers that don’t get tripped by Anti Viruses and firewalls.
  • I have become more proficient at web application attack techniques and processes – such as leveraging local file inclusion vulnerabilities, code execution, uploading files and getting a shell.
  • I have written some very handy privilege escalation shell-related scripts thanks to being encouraged to look for more ways to exploit the systems.
  • I have been able to exercise my Powershell skills in order to compromise systems – which are a set of very handy skills to have.

I will very likely start attacking the lab machines next week, and I’m extremely excited about it.

 

Side-Notes:

  • I have uploaded some of my “everyday” Python scripts to my Github account. Check them out. The recent additions include: key loggers, screen grabbers, format conversion scripts, and more.
  • I encourage everyone to follow me on Twitter. I constantly post interest research papers and PoCs which you might be interested in.

 

Until next time.

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.