As usual, real the description given. It says that “a file” been “transferred” to another “internal computer“.
So we know that this might involving traffic between 2 internal IPs.
Download “artifact.zip“. Open pcap with Wireshark. Then, go to Statistics > Protocol Hierarchy
We can see here protocol UDP is making up large number of the packet captured.
Now, go to Statistics > Conversations
We can see that IP 192.168.48.130 is making large connection to 192.168.0.111. Now we can go investigate this 2 IPs.
Use this Wireshark BPF filter:udp && ip.dst == 192.168.0.111
Why 192.168.0.111? Since the clue mentioned “transferred to another INTERNAL computer”
At first I thought the data within packet stream that possibly resemble file that been exfil.
So I use tshark to extract UDP data & try to decode it:
C:\>"C:\Program Files\Wireshark\tshark.exe" -r artifact.pcapng -Y "udp && ip.dst == 192.168.0.111" -T fields -e data
6a54416b673733434d52624774326a45584a3358594c5931427566315a75314b4d71344775595150513052374366
4f544d65726962666e386a4478564630687948356d704952676e47514c7269756143656e644c55
39786b79345276774839766a
<snip>
I tried to decode it in various ways; base64, dec to unicode, hex to file, etc. But failed. Seems I might looking at wrong place…
After the CTF ended, one of the CTF crew mentioned that to look at the ports! meh…
So, I made a tshark query to extract the port number:
C:\>"C:\Program Files\Wireshark\tshark.exe" -r artifact.pcapng -Y "udp && ip.dst == 192.168.0.111" -T fields -e udp.dstport
30137
30080
30078
30071
30013
<snip>
After that, we minus the port number gathered with 30000.
def process_numbers(file_path):
try:
with open(file_path, 'r') as file:
# Read lines and strip newline characters
numbers = [line.strip() for line in file.readlines()]
# Subtract 30000 from each number and convert to string
processed_numbers = [str(int(number) - 30000) for number in numbers]
# Combine into a single string separated by spaces
result = '\n'.join(processed_numbers)
return result
except Exception as e:
return f"An error occurred: {e}"
# Replace 'udpport.txt' with the path to your text file
file_path = 'udpport.txt'
print(process_numbers(file_path))
It will print out something like this:
137
80
78
71
13
Then, we convert it from decimal to unicode (using Python char()):
# Initialize an empty string to store the characters
output_string = ""
# Open the file "udpportout.txt" in read mode
with open("udpportout.txt", "r") as file:
# Read each line from the file
for line in file:
# Convert the line to an integer
number = int(line.strip())
# Convert the number to its corresponding Unicode character
# and append it to the output string
output_string += chr(number)
# Open a new file in binary write mode
with open("output.png", "wb") as output_file:
# Convert the output string to bytes and write it to the file
output_file.write(output_string.encode('latin1'))
We should see “output.png” with the flag:
That’s all. So close. Yet so far. 🙁
Extra – Scapy
You can also use Scapy to achieve same result. First, load the pcap into Scapy:
$ scapy
INFO: Can't import PyX. Won't be able to use psdump() or pdfdump().
aSPY//YASa
apyyyyCY//////////YCa |
sY//////YSpcs scpCY//Pp | Welcome to Scapy
ayp ayyyyyyySCP//Pp syY//C | Version 2.5.0
AYAsAYYYYYYYY///Ps cY//S |
pCCCCY//p cSSps y//Y | https://github.com/secdev/scapy
SPPPP///a pP///AC//Y |
A//A cyP////C | Have fun!
p///Ac sC///a |
P////YCpc A//A | Craft packets like I craft my beer.
scccccp///pSP///p p//Y | -- Jean De Clerck
sY/////////y caa S//P |
cayCyayP//Ya pY/Ya
sY/PsY////YCc aC//Yp
sc sccaCY//PCypaapyCP//YSs
spCPY//////YPSps
ccaacs
using IPython 8.14.0
>>> ps = rdpcap("/home/kali/Desktop/artifact.pcapng")
Then, try to print UDP dest.port for ip.dst == 192.168.0.111:
>>> for p in ps:
...: if IP in p and UDP in p and p[IP].dst == '192.168.0.111':
...: print(p['UDP'].dport)
...:
30137
30080
30078
30071
30013
30010
30026
30010
30000
<snip>
Now, we can modify based on code/query above to:
1. Create a list of the port numbers you’ve filtered.
2. Subtract 30000 from each port number.
3. Convert each subtracted/modified port number to its corresponding Unicode character using chr().
4. Write the result into a file, assuming it will form a valid PNG image.
>>> # Initialize an empty string for the output
...: output_string = ""
...:
...: # Iterate over packets and process them
...: for p in ps:
...: if IP in p and UDP in p and p[IP].dst == '192.168.0.111':
...: # Subtract the port output with 30000
...: modified_port = str(p[UDP].dport - 30000)
...:
...: # Convert to integer, then to Unicode character, and add to the output string
...: if modified_port:
...: output_string += chr(int(modified_port))
...:
...: # Save the output to a file
...: with open("/home/kali/Desktop/output.png", "wb") as output_file:
...: output_file.write(output_string.encode('latin1'))
...:
>>>
Once finished, it will produced “output.png” file on the Desktop.