ASEAN Cyber Shield 2024

Writeup by Teh Tarik Cendol

Audit/no-name minor

This was a challenge similar to the one I created for Battle of Hackers 2024 so we solved it relatively fast. The challenge provides us with a binary that presents a menu that allows the user to borrow a loan, repay the loan, mining for money, buy a name and change name.

image

The goal is to get a name. But

  • To buy a name, you need to have money.

  • To have money you cannot simply mine, cause it will take a lot of time.

  • So you need to loan and then repay them.

The vulnerability lies in the way the program keeps track of the user's loan.

Source Code

The user's loan is defined as a float, which can be subjected to floating point inaccuracy. A float is 32 bit and it has 1 bit for sign, 23 bit for mantissa and 8 bit for exponent. For integers, the inaccuracy starts at 2^24 (16,777,216). In other words, all integers can be represented as floats up to 2^24 but not beyond that. Specifically, in the range of 2^24 to 2^25, float does not support odd numbers, only even numbers.

Proof of Concept

Proof of Concept

image

Heres a simple C program that demonstrates this

image

This is the output

Exploiting the Program

Now, we just need to borrow money until 16777216, buy the name, and borrow loan of size $1 until we eventually are able to repay our loan.

image

Buying the name

image

After borrowing $1

Buffer Overflow

Source Code

The name in MinerAccount object was assigned to only 0x20 size, but in change_name function we can change up until 0x200. With the help of the printf() in main, we are able to leak the stack canary and libc address after overwriting enough bytes using read(). Putting it all together, we get

  1. We loan 16777216 money

  2. Then we buy name so our money no 16777216 - 1337

  3. Then if we loan 1 dollar each time, our cash increase, but debt stays the same. So we loan 1 dollar for 1337 times

  4. Then can repay all debt

  5. Now start the leaking process through name

  6. Leak canary

  7. Leak libc_start_main address

  8. Proceed will rop chain to system

Exploit Script
image

Rev/CS1338: Script Programming

image
image

Given the lua file, we know that it shows the source code of the instance and we are required to connect to the instance and send the correct string in order to get the flag. From the source code, we can see that it loads a file named library.

image

We tried online decompiler for lua but failed, so ended up using an open source compiler that we learned from https://www.youtube.com/watch?v=nQR1raNkd2s.

image
image

Rev/Secure Chat

We are given server.exe, client.exe and OfficeChat.pcapng. The server.exe act as the server for communication, and the client will be acting as the client who start the conversation. This can be seen in the pcap file

image

The high port number is the client. We can verify this by trying to capture loopback address on our system.

image

Reversing server.exe

image

The communication process of the server

  1. Open socket

  2. Accept session

  3. Generate key

  4. Share key with client

  5. Start secure conversation

Reversing client.exe

image

The communication process of the client

  1. Open socket

  2. Start a session with server

  3. Receive key from server

  4. Start secure communication

Things that we can take note

  1. KEY is generated by the server

  2. KEY will be shared to the client on network

Understanding how the KEY being shared on network

image

Before the key is sent on the network, it is encrypted using XOR with kek variable.

image

This mean, from the given pcap file, we can decrypt the KEY being used by XORing the encrypted key with kek

Decrypted Key

image

The secure conversation is being encrypted using the same XOR method. Now we got the key, we just extract the data, then decrypt using our key.

Extracted Data
Solve Script

Flag : ACS{D0_NoT_uS3_X0r_f0R_eNcRYp71on_4LG0r1ThM}

Web/Can You REDIRECT Me

image
image

We were greeted with a page with almost nothing in it. Except for the provided url parameters: ?url=Report_URL

Let’s take a deeper look into the source code given and perform code analysis/audit.

image

app.js and utils.js seem like the only relevant files for the challenge. Let’s dissect it real quick.

The framework of the web app is very similar to the several other web challenges, of which are based on Express (NodeJS) and includes Puppeteer methods in its codebase.

image

There’s nothing really interesting in the utils.js file, except that now we’ve learned the Puppeteer session will be utilizing the goto method, which navigates the headless Chrome browser to the url fed by the user

image

Route Overview:

The /report route expects a query parameter url. It checks if the URL's hostname is www.google.com. If the condition fails, it responds with I ONLY trust GOOGLE.

Critical Checks:

URLs that don't have the URL protocol; http or https that are being passed onto the parameter will result in the output NOPE!

The trick was to pass the hostname validation but somehow make the bot end up on a different hostname. Immediately, I remembered something about Google AMP (Accelerated Mobile Pages). If you hit a URL like this; https://google.com/amp/facebook.com. It passes the hostname check (www.google.com), but when visited, it redirects to facebook.com. Jackpot!

Execution: Hit the /report endpoint with the payload /report?url=https://www.google.com/amp/facebook.com

The server validated the hostname as www.google.com. The bot visited the URL, got redirected by Google AMP to facebook.com. The final check failed because of facebook.com != www.google.com, so the app returned the flag in the JavaScript alert.

Flag: ACS{It_i5_JU$7_tr1Cky_tRiCK}

Misc/Drone Hijacking

image
image

We are given a pcap file with RTP streams. Since it is a drone, we suspect that there might be video streaming. There’s a way to convert RTP to H264 manually in Wireshark according to this forum. H.264 is a video compression standard. The goal is to convert to H264 so that we can view the video. In Edit -> Preferences, set the payload type to 96

image

Then, we will see that RTP stream has been converted to H264. We can install Wireshark plugin to extract H.264 stream from the RTP stream.

Here’s the plugin that I found: https://github.com/volvet/h264extractor/blob/master/rtp_h264_extractor.lua

Just put into the plugin folder where we install our Wireshark and the plugin will appear in Tools section.

image

We will get .264 file, and we can use ffmpeg to convert it to mp4.

image

Misc/Lutella

image
image

In this challenge, we were tasked with exploiting a Lua-based sandbox environment that had several restrictions, particularly on system calls and sensitive libraries. The goal was to find a way to escape the sandbox and retrieve the flag.

Lua is a lightweight, high-level scripting language commonly embedded in applications to provide extensible scripting capabilities. It is known for its simplicity and flexibility, but in this challenge, we were working with a sandboxed Lua environment, meaning that our access to certain functions and libraries was restricted.

Typically, a sandbox in Lua might restrict access to the following:

System-level functions like os.execute(), os.popen(), and io.popen(). The debug library, which can be used for introspection and manipulation of Lua's internal state. The ability to interact with the file system.

In this environment, we were given limited access to the Lua language but could exploit certain exposed functionalities to break out of the sandbox.

image

The crux of the exploit involved using Lua's debug library and the internal debug.getregistry() function. The sandbox restricted access to system libraries like os and io, but we were able to bypass these restrictions by directly interacting with Lua's internal registry.

We start by calling the debug.getregistry() function, which returns a global registry table that Lua uses to manage all objects internally. This registry is usually inaccessible in a sandboxed environment, but it wasn’t properly restricted here. By accessing the registry, we were able to locate internal functions and libraries that were not otherwise exposed.

Within the registry, there was an exposed popen function, which allows us to execute system commands. This was a critical vulnerability because it provided a way to interact with the underlying operating system, despite the sandbox restrictions. Normally, Lua’s io.popen or os.popen would be restricted, but by leveraging the registry, we could access and use this function to run shell commands.

Considering typical Lua sandbox escape techniques, I first tried to exploit the debug.getregistry() function. The idea was to look for unsafe methods or libraries available in the registry.

debug.getregistry().safe_method.popen("cat ./flag"):

image

However, this command failed, as the prompt did not return the flag or any meaningful output.

After further testing, I adjusted the approach and used the print function to display the result explicitly:

image

Flag: ACS{Toast_and_chocolate_are_a_fantastic_combination}

Misc/Hi Alien

image

In the website given, we are allowed to upload a file. However, the challenge also provides us with YARA rules.

YARA rule
Exe Source Code

This is the code which imports exactly 62 functions, with 3 of it being from acs.dll. Then, there are large arrays of random data to pass the entropy check.

Version.rc

Version.rc is to be compiled with the cpp file to match pe.version_info["CompanyName"] == "acs"

acs.cpp
fake.cpp

A fake dll to match the number of function imports

The code above will pass most of the rules already, the hardest part was adding a section that matches the standard deviation range of 61.8 - 61.9. After a lot of trial and testing, we made a binary file with random data inside, manually modifying bytes until we achieve the desired standard deviation. We also have to match the condition ($acs = { 90 90 90 90 68 ?? ?? ?? ?? C3 }) where $acs must be located at an offset of +0x2f. We can run these commands to add the section to the exe.

Acssection.bin

image

One last step before we match everything, when we compile with the version.res which will make the number of resources into 2. We will use CFF Explorer to just delete the resource

image

Then, just upload the file.

image

Flag : ACS{97d9bad8791993f95050bf4668f3e1351f39b21fafeb986822915ecc71d75f77}

Crypto/Secret Encrypt

image

After analyzing the secret function for a while, we can see that the number of iterations does not change because it uses the same secret3. Since secret1 is also a global variable, it will be updated every time we run this function.

image

This is the equations that we can derive from the script above. We know that k is the fixed number of iterations that we have to find. We know that k multiplied with output 1 we can get output 2 and same goes for output 3.

image

Then we will use simultaneous equation to solve for k and remove S4. Then we can factorize both equations. From the first equation there are 2 unknowns so we cannot solve that but the second equation, we have everything we need to solve for k. After getting the value for k, we can solve for S1 and get the p_rsa and we can RSA decrypt for the flag.

Solve Script

Last updated