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.