> For the complete documentation index, see [llms.txt](https://jesuscries.gitbook.io/home/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jesuscries.gitbook.io/home/ctf-writeups/reverse-engineering/sibersiaga-2023-obstacles.md).

# SiberSiaga 2023: Obstacles

The best satisfaction always comes after overcoming many annoying obstacles. Overcome this challenge to gain the satisfaction of a flag!

## TL;DR

> Bypass anti-debugging techniques via manual patching to circumvent branching controls.

## **Initial Analysis**

Running the executable doesn't seem to be doing anything at all.

```bash
 ┌──(kali💀JesusCries)-[~/…/CTF/SiberSiaga2023 (Finals)/Rev/Obstacles]
 └─$ wine Obstacles.exe                      
 ^C   
```

Importing the executable in any debugger/disassembler of choice shows that it is written in Go Lang. Luckily for us, most of the function names are resolved automatically without needing to rename them.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2F6L4kn8ar4cNttV1OaPft%2Fimage.png?alt=media&amp;token=c9e399d3-5ddb-45b7-9fce-5e5b0a1a28d0" alt=""><figcaption></figcaption></figure>

### **Identifying Anti-Debugging Techniques**

At a glance, there seem to be several anti-debugging techniques such as `time.Sleep` and `main.isDebuggerPresent` implemented. This is then followed by a series of decryption routines.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FMApLFwJ3jiNxXcM6hz4K%2Fimage.png?alt=media&amp;token=966902f2-6c98-43cb-8b4b-cbc3a166fe4e" alt=""><figcaption></figcaption></figure>

Further down, there are even checks to verify if the executable is currently running in a sandbox based on the presence of specific processes.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FOgSHfSbmVCihOGuQNdv2%2Fimage.png?alt=media&amp;token=12dd1cec-8160-48dd-9085-3e155208eeb1" alt=""><figcaption></figcaption></figure>

We can verify the process names by going back a few lines.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FYa7vZOsJ6kQ7O14ANuw6%2Fimage.png?alt=media&amp;token=a52e36b1-7b8f-487d-b14d-905dc96cb455" alt=""><figcaption></figcaption></figure>

`data_50dbb8` is a pointer that points to `0x4dde33`, so we'll take a look at that address instead.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FeDZk0jVdpwoT3LoB1bkz%2Fimage.png?alt=media&amp;token=a02db1f1-af59-47b8-a008-4ba6814d11c9" alt=""><figcaption></figcaption></figure>

This reveals the process `ollydbg.exe` and `procmon.exe`. In the meantime, take note of `notepad.exe` as well.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FwanZ6Z6QmSC8TuyXiW55%2Fimage.png?alt=media&amp;token=7d86ab3c-cdf3-41f2-aa2c-d02e2cc5cf82" alt=""><figcaption></figcaption></figure>

The last anti-debugging technique seems to be checking the current date against a specific point of time.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FVZ1uWyiZxq0racl1f9lr%2Fimage.png?alt=media&amp;token=68f753e3-69e4-4dcc-84e0-a8f729aafdd3" alt=""><figcaption></figcaption></figure>

## **Manual Patching**

As the challenge description suggests, we need to overcome these obstacles, a.k.a anti-debugging techniques via assembly patching, while leaving all the decryption routine untouched. I am going to use `BinaryNinja` for patching due to it's intuitiveness.

### **Sleep**

When trying to run the executable, it will go to sleep indefinitely due to `time.Sleep`. We can patch this out easily with `Skip and Return Zero`:

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FEbLeYKGBqfRORu22W820%2Fimage.png?alt=media&amp;token=94a365ab-8e11-4484-a26b-7892c3fc2cbf" alt=""><figcaption></figcaption></figure>

### **Program Termination**

Next, we will need a way to prevent the program from terminating. Right click on `os.Exit` and select `Patch -> Edit Current Line`:

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FGiKTPsYXUhwMBIB770sE%2Fimage.png?alt=media&amp;token=c74cec6b-27e2-48a8-a5f7-356725d09ea1" alt=""><figcaption></figcaption></figure>

Instead of terminating, we can neutralize it by jumping to the nearest block. Obtain the address of the nearest block with `Copy Address`:

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FtWWV9uV3jNt5DCXsW1bs%2Fimage.png?alt=media&amp;token=2a9b35a9-359c-4e92-aa08-2531fb0a8e44" alt=""><figcaption></figcaption></figure>

This way, it will continue execution on the same block, regardless of the comparison `test rax, rax` made on top.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2F47zCTv82Dga8MitxS7Zp%2Fimage.png?alt=media&amp;token=35f44a3c-fc05-4cac-a226-5d7f6215b11e" alt=""><figcaption></figcaption></figure>

### **Sandbox**

Up until this point, we have defeated `time.Sleep` and `os.Exit`, but we are met with sandbox checks.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2Fh0LOXWYMBbD3QadwYZKe%2Fimage.png?alt=media&amp;token=8c4c6dac-04cc-4218-b69f-ff083b289bae" alt=""><figcaption></figcaption></figure>

To neutralize this, select `Invert Branch` to turn `je` into `jne`. Do note that the sandbox checks are still in place since `main.sandboxFilepath` remains intact. However, any positive detection will not trigger anything since we have flipped the decision tree.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2Fl7IPvlKVqx2ZVbJYhtuf%2Fimage.png?alt=media&amp;token=3dbf05c3-48c2-4375-87bd-a18c2fa4e470" alt=""><figcaption></figcaption></figure>

Sandbox detection is now gone.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2F1fmQYwvWBm3SnA0XvsYq%2Fimage.png?alt=media&amp;token=6fa66826-4061-4016-a62e-97f4363b92d8" alt=""><figcaption></figcaption></figure>

### **Time & Date**

Apply the same technique as patching `time.Sleep` for all date-time equivalent function calls.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FCWDeRKCUhKQPB9b9GFQb%2Fimage.png?alt=media&amp;token=587a10e4-1020-48ac-af68-d9b392b0f9a4" alt=""><figcaption></figcaption></figure>

Recall that we received the error message `panic: time: missing Location in call to Date` on runtime. This matches with the following function call.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FzjqMJT8qoCUSgI1zsWeT%2Fimage.png?alt=media&amp;token=108c77b0-9490-48c5-8586-0050b60b1f66" alt=""><figcaption></figcaption></figure>

We can bypass this with a simple `Invert Patch`:

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2Fophf29eb7fUvgUhDPEBU%2Fimage.png?alt=media&amp;token=3bed8198-a36d-4454-82d1-b802299f148d" alt=""><figcaption></figcaption></figure>

However, we now encounter a different problem.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2F8ad4XoQjuAmvoh0Nq9gz%2Fimage.png?alt=media&amp;token=a044d577-d3de-472c-85e2-b73d3ea16387" alt=""><figcaption></figcaption></figure>

A little below, we can find the culprit for that problem.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2F8JNdPyqqzspWIsaeeB5H%2Fimage.png?alt=media&amp;token=71cb50bd-d1ca-4db8-8f0c-3548c5e6640e" alt=""><figcaption></figcaption></figure>

Patch the instructions with a `Return Zero`and `Invert Patch` respectively.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FzPtmdWb9FFKLNxK6syP8%2Fimage.png?alt=media&amp;token=af14f121-5c54-40a7-89b4-fa7af9928178" alt=""><figcaption></figcaption></figure>

### **Environment**

An environment issue.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FiXUSm2JZ7wPZPgo1mMg9%2Fimage.png?alt=media&amp;token=3ee73530-d0b6-4aca-a5be-c55601a07e5d" alt=""><figcaption></figcaption></figure>

A little below, we can find the code block responsible for this via `data_50c300` strings.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FRmHb03FTVe1bCdjLFe4P%2Fimage.png?alt=media&amp;token=e1400acf-eb7f-4a33-88d7-c48a518f23f0" alt=""><figcaption></figcaption></figure>

Perform an `Invert Patch` on the jump above, so it changes from `jg` to `jle`:

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FqViSe0wuitlMgF4lc4YB%2Fimage.png?alt=media&amp;token=d7151c6c-7a27-4dff-ae10-9b321718efaa" alt=""><figcaption></figcaption></figure>

### **File Check**

Once that is completed, we have a final part to fix before our flag gets fully decrypted.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FdYRKyW1O9gZMPMs4P6tN%2Fimage.png?alt=media&amp;token=2e7decf5-1388-4084-81e8-17e2eb59d59e" alt=""><figcaption></figcaption></figure>

We can either patch `jne` or `os.Exit` here, both methods will lead to the same result.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FJ9qckdT9Sdq2qAGk3RDM%2Fimage.png?alt=media&amp;token=eff5f390-ae7f-4c78-9709-05249e96d747" alt=""><figcaption></figcaption></figure>

## **Solution**

Once the flag is fully decrypted, it will be injected into an existing process, as verified with the usage of API calls:

`OpenProcess` -> `VirtualAllocEx` -> `WriteProcessMemory` -> `CreateRemoteThreadEx`

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2FEmbuEI26qvHcOdDOYpPO%2Fimage.png?alt=media&amp;token=0156e5e1-e770-4801-a483-2758bbbc64a5" alt=""><figcaption></figcaption></figure>

Since `OpenProcess` is invoked (instead of `CreateProcessW`), the process injection must be targeting an existing process on the system. Before this, we knew that `notepad.exe` was somehow involved in this challenge, so it must've been the one! To solve this challenge, open a new instance of `notepad.exe` and run the executable.

<figure><img src="https://80158427-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FkoydBBkDRRSxCLl1Wpgr%2Fuploads%2F8AdT69ZePxynNnvwUdTO%2Fimage.png?alt=media&amp;token=df9d15bd-2674-4f56-8232-afb2a9e45bf9" alt=""><figcaption></figcaption></figure>

**Flag:** sibersiaga{G0\_GO\_G0L4NG\_0BST4ClES}
