Add the ssrf module
This commit is contained in:
17
ssrf/scripts/exploit.sh
Executable file
17
ssrf/scripts/exploit.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
# Drive the vulnerable endpoint against the four targets that matter, printing the outcome of
|
||||
# each. Run it after ./scripts/run.sh <profile>; the profile decides the answers.
|
||||
set -eu
|
||||
PRIVATE_IP="$(hostname -I | awk '{print $1}')"
|
||||
probe() {
|
||||
printf '%-58s ' "$1"
|
||||
curl -s --max-time 10 -G http://127.0.0.1:8080/preview --data-urlencode "url=$1" \
|
||||
| python3 -c 'import json,sys; d=json.load(sys.stdin); print(d["outcome"], "|", d.get("body", d.get("message",""))[:96])'
|
||||
}
|
||||
echo "target outcome"
|
||||
echo "-----------------------------------------------------------------------------------------"
|
||||
probe "http://127.0.0.1:8080/internal/credentials"
|
||||
probe "http://localhost:8080/internal/credentials"
|
||||
probe "http://[::1]:8080/internal/credentials"
|
||||
probe "http://${PRIVATE_IP}:8080/internal/credentials"
|
||||
probe "http://example.com/"
|
||||
35
ssrf/scripts/run-all.sh
Executable file
35
ssrf/scripts/run-all.sh
Executable file
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
# Regenerate every file under docs/output/. Nothing in the article or the chapters was typed by
|
||||
# hand; it all came from here.
|
||||
set -eu
|
||||
cd "$(dirname "$0")/.."
|
||||
mvn -B -q compile
|
||||
[ -f target/cp.txt ] || mvn -B -q dependency:build-classpath -Dmdep.outputFile=target/cp.txt -Dmdep.includeScope=runtime
|
||||
CP="target/classes:$(cat target/cp.txt)"
|
||||
|
||||
java -cp "$CP" com.ankurm.ssrf.FilterMatrix > docs/output/filter-matrix.txt
|
||||
java -cp "$CP" com.ankurm.ssrf.AndVarargsTrap > docs/output/and-varargs-trap.txt
|
||||
|
||||
{
|
||||
for p in "" docsfilter blocklist negated allowlist; do
|
||||
echo "==================================================================================="
|
||||
echo "PROFILE: ${p:-(none) - no InetAddressFilter bean}"
|
||||
echo "==================================================================================="
|
||||
./scripts/run.sh "$p" >/dev/null 2>&1 || { echo "FAILED TO START"; continue; }
|
||||
./scripts/exploit.sh
|
||||
echo
|
||||
done
|
||||
./scripts/stop.sh
|
||||
} > docs/output/exploit-by-profile.txt 2>&1
|
||||
|
||||
# Two beans of the same type: the context does not start, and the diagnostic blames the wrong
|
||||
# thing. Captured deliberately.
|
||||
{
|
||||
echo "\$ java -cp ... SsrfDemoApplication --spring.profiles.active=twofilters"
|
||||
timeout 90 java -Xmx256m -cp "$CP" com.ankurm.ssrf.SsrfDemoApplication \
|
||||
--spring.profiles.active=twofilters 2>&1 \
|
||||
| grep -E 'expected single matching bean|APPLICATION FAILED|^Description|^Action|required a single bean|^\t- ' | head -20
|
||||
} > docs/output/two-filter-beans.txt 2>&1
|
||||
|
||||
mvn -B test 2>&1 | grep -E 'Tests run:|WhereTheFilterRuns' > docs/output/tests.txt
|
||||
echo "regenerated:"; ls -1 docs/output/
|
||||
23
ssrf/scripts/run.sh
Executable file
23
ssrf/scripts/run.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env bash
|
||||
# Start the application with the given profiles: ./scripts/run.sh docsfilter
|
||||
#
|
||||
# Uses a plain `java -cp` launch rather than `mvn spring-boot:run` so that only one JVM starts
|
||||
# per application. The Maven plugin forks a second JVM, which matters when you are running
|
||||
# several of these at once on a small machine.
|
||||
set -eu
|
||||
cd "$(dirname "$0")/.."
|
||||
PROFILES="${1:-}"
|
||||
[ -f target/cp.txt ] || mvn -B -q dependency:build-classpath -Dmdep.outputFile=target/cp.txt -Dmdep.includeScope=runtime
|
||||
[ -d target/classes ] || mvn -B -q compile
|
||||
./scripts/stop.sh
|
||||
ARGS=""
|
||||
[ -n "$PROFILES" ] && ARGS="--spring.profiles.active=$PROFILES"
|
||||
setsid nohup java -Xmx256m -cp "target/classes:$(cat target/cp.txt)" \
|
||||
com.ankurm.ssrf.SsrfDemoApplication $ARGS > /tmp/ssrf-app.log 2>&1 < /dev/null &
|
||||
for _ in $(seq 1 60); do
|
||||
curl -fs -o /dev/null http://127.0.0.1:8080/diag/filter && exit 0
|
||||
sleep 1
|
||||
done
|
||||
echo "application did not start; see /tmp/ssrf-app.log" >&2
|
||||
tail -30 /tmp/ssrf-app.log >&2
|
||||
exit 1
|
||||
14
ssrf/scripts/stop.sh
Executable file
14
ssrf/scripts/stop.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
# Stop any running instance.
|
||||
#
|
||||
# Match a real JVM whose command line contains this application's main class, and exclude this
|
||||
# shell and its parent explicitly. A bare grep for the class name is not enough: when the
|
||||
# calling shell's own command line contains the class name - which it does whenever you paste a
|
||||
# here-doc - the grep matches the shell and kills it.
|
||||
set -eu
|
||||
self=$$; parent=${PPID:-0}
|
||||
for pid in $(ps -eo pid,ppid,comm,args | awk -v s="$self" -v p="$parent" \
|
||||
'$1 != s && $1 != p && $3 ~ /^java/ && $0 ~ /com\.ankurm\.ssrf\.SsrfDemoApplication/ {print $1}'); do
|
||||
kill -9 "$pid" 2>/dev/null || true
|
||||
done
|
||||
sleep 1
|
||||
Reference in New Issue
Block a user