ʕ·ᴥ·ʔ






Packet Hero

06/21/2023

By: smashmaster

Tags: misc HSCTF-2023

Problem Description:

Legendary. Ruthless. Weakness?

Hints:

Reveal Hints some heroes can be lazy

Research

Opening the pcap in wireshark we notice that wireshark immediately identiies the protocol used in the tcp stream as “RSYNC”. We can further confirm this with the fact that port 873 is being accessed.

First Attempts

osint attempt

The closest challenge I could find was this, but the task too different.

Protcool Research

Most people might have started by researching the rsync protocol and looking for documentation on how to understand the protocol by hand. We took this one step further by attempting to use scapy to implement an rsync analyzer. Using the following resources, we got through a tiny bit of the overall tcp stream but that’s when our documentation sources went dead.

Replay attack using Python

We finally thought to just play back the packets to our own instance of the rsync client. We used scapy to dump all clientbound data:

from scapy.all import *

pcap_flow = rdpcap("simplified_packethero.pcap")
sessions = pcap_flow.sessions()
print(len(sessions), " sessions ")
user_recv = bytes()
for sess in sessions:
    for packet in sessions[sess]:
        print(packet)
        try:
            tcp = packet["TCP"]
            # print(tcp.dport)
            # rsync decode
            to_user = tcp.dport != 873
            if to_user:
                user_recv += bytes(tcp.payload)
        except Exception as e:
            pass

with open("user_recv.bin", "wb") as f:
    f.write(user_recv)

Replay Server (we deployed this onto our VPS):

from socket import *
import time
# Create a socket server listening on 873 which was the rsync port
with open("user_recv.bin", "rb") as f:
    user_recv = f.read()
    s = socket(AF_INET,SOCK_STREAM)
    s.bind(('127.0.0.1',873))
    s.listen(1)
    while True:
        sock, addr = s.accept()
        sock.setblocking(0)
        print(addr, " begin replay")
        for i in range(0, len(user_recv)):
            try:
                sock.send(bytes([user_recv[i]]))
                # print(bytes([user_recv[i]]).decode(errors="replace"), end="")
                time.sleep(0.001) # slightly slowly replay the data so we aren't lightning fast
                # read from socket if we have stuff
                while True:
                    try:
                        data = sock.recv(1)
                        if len(data) == 0:
                            raise Exception("Socket closed")
                        print(data.decode(errors="replace"), end="")
                    except Exception as e:
                        if "Resource temporarily unavailable" in str(e):
                            break
                        print("UE",e)
                        raise e
            except Exception as e:
                print("DIED EARLY AT ",i)
                print(e)
                break
        print("replay done")
        sock.close()
        print("connection closed")

So on Ubuntu 20.04 my rsync is too old and the program crashes. When I build bleeding edge rsync and disable data integrity protections as needed I get

A, or a, is the first letter and the first vowel of the Latin alphabet, used in the modern English alphabet, the alphabets of other western European languages and others worldwide. Its name in English is a (pronounced /ˈeɪ/), plural aes. It is similar in shape to the Ancient Greek letter alpha, from which it derives. The uppercase version consists of the two slanting sides of a triangle, crossed in the middle by a horizontal bar. The lowercase version can be written in two forms: the double-storey a and single-storey ɑ. The latter is commonly used in handwriting and fonts based on it, especially fonts intended to be read by children, and is also found in italic type.

Which looks a lot like something a challenge author would put in to troll. I do a bit of thinking and because I yeeted the pcap into a bunch of online pcap analyzers I know that there are VMWare MAC Addresses in the pcap so this was done in a vm. I was trying to guess what os they might have used to narrow down rsync versions and decided to try Ubuntu 22.04, because lucky me just so happens to have a single core 1gb ram ubuntu 22.04 vps. You’ll chuckle when you see the hostname.

(base) raymond@homedesktop2021:~$ ssh ubuntu@tiny-machine
Welcome to Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-1035 x86_64)

*** System restart required ***
Last login: Sat Jun  3 22:14:59 2023 from [MY IP]
ubuntu@little-machine-who-could:~$ rsync --ignore-times --no-checksum --partial -vvvvrzd rsync://vps /tmp
opening tcp connection to vps port 873
Connected to vps (0.0.0.0)
msg checking charset: UTF-8
sending daemon args: --server --sender -vvvvrIze.iLsfxCIvu . /  (5 args)
(Client) Protocol versions: remote=31, negotiated=31
receiving incremental file list
recv_file_name(.)
recv_file_name(files)
received 2 names
[Receiver] flist start=1, used=2, low=0, high=1
[Receiver] i=1 0 ./ mode=040755 len=4,096 flags=1005
[Receiver] i=2 1 files/ mode=040755 len=4,096 flags=1004
recv_file_list done
get_local_name count=2 /tmp
generator starting pid=147460
recv_files(2) starting
[receiver] receiving flist for dir 1
recv_file_name(files/a.txt)
delta-transmission enabled
recv_generator(.,0)
recv_generator(.,1)
recv_generator(files,2)
[generator] receiving flist for dir 1
recv_file_name(files/a.txt)
recv_file_name(files/flag.txt)
recv_file_name(files/packet.txt)
recv_file_name(files/flag.txt)
recv_file_name(files/packet.txt)
recv_file_name(files/readme.txt)
recv_file_name(files/secrets.txt)
received 5 names
[receiver] flist start=4, used=5, low=0, high=4
[receiver] i=4 2 files/a.txt mode=0100644 len=678 flags=1000
[receiver] i=5 2 files/flag.txt mode=0100644 len=1,074 flags=1000
[receiver] i=6 2 files/packet.txt mode=0100644 len=459 flags=1000
[receiver] i=7 2 files/readme.txt mode=0100644 len=298 flags=1000
[receiver] i=8 2 files/secrets.txt mode=0100644 len=635 flags=1000
recv_file_list done
[receiver] flist_eof=1
recv_files(files)
files/
recv_files(files/a.txt)
default_perms_for_dir: sys_acl_get_file(files, ACL_TYPE_DEFAULT): No such file or directory, falling back on umask
rsync: [receiver] mkstemp "/tmp/files/.a.txt.xAaO3M" failed: No such file or directory (2)
recv_file_name(files/readme.txt)
recv_file_name(files/secrets.txt)
received 5 names
[generator] flist start=4, used=5, low=0, high=4
[generator] i=4 2 files/a.txt mode=0100644 len=678 flags=1000
[generator] i=5 2 files/flag.txt mode=0100644 len=1,074 flags=1000
[generator] i=6 2 files/packet.txt mode=0100644 len=459 flags=1000
[generator] i=7 2 files/readme.txt mode=0100644 len=298 flags=1000
[generator] i=8 2 files/secrets.txt mode=0100644 len=635 flags=1000
recv_file_list done
recv_generator(files,3)
recv_generator(files/a.txt,4)
touch_up_dirs: . (0)
recv_generator(files/flag.txt,5)
recv_generator(files/packet.txt,6)
recv_generator(files/readme.txt,7)
recv_generator(files/secrets.txt,8)
[generator] flist_eof=1
generate_files phase=1
data recv 678 at 0
got file_sum
recv_files(files/flag.txt)
files/flag.txt
data recv 1074 at 0
got file_sum
renaming files/.flag.txt.t4eaZX to files/flag.txt
recv_files(files/packet.txt)
files/packet.txt
data recv 459 at 0
got file_sum
renaming files/.packet.txt.HtXsjX to files/packet.txt
recv_files(files/readme.txt)
files/readme.txt
data recv 298 at 0
got file_sum
renaming files/.readme.txt.ZNDRTQ to files/readme.txt
recv_files(files/secrets.txt)
files/secrets.txt
data recv 635 at 0
got file_sum
renaming files/.secrets.txt.zTKwnf to files/secrets.txt
touch_up_dirs: files (1)
recv_files phase=1
recv_files phase=2
recv_files finished
generate_files phase=2
generate_files phase=3
rsync: connection unexpectedly closed (2161 bytes received so far) [receiver]
[receiver] _exit_cleanup(code=12, file=io.c, line=231): entered
rsync error: error in rsync protocol data stream (code 12) at io.c(231) [receiver=3.2.7]
[receiver] _exit_cleanup(code=12, file=io.c, line=231): about to call exit(12)
rsync: connection unexpectedly closed (254 bytes received so far) [generator]
[generator] _exit_cleanup(code=12, file=io.c, line=231): entered
rsync error: error in rsync protocol data stream (code 12) at io.c(231) [generator=3.2.7]
[generator] _exit_cleanup(code=12, file=io.c, line=231): about to call exit(12)
ubuntu@little-machine-who-could:~$ ls /tmp
files                                                                         systemd-private-f3e84648862148508d5d0aff31e76fe8-systemd-logind.service-R6ouhf
snap-private-tmp                                                              systemd-private-f3e84648862148508d5d0aff31e76fe8-systemd-resolved.service-01jGnj
systemd-private-f3e84648862148508d5d0aff31e76fe8-ModemManager.service-EkmlwG  systemd-private-f3e84648862148508d5d0aff31e76fe8-systemd-timesyncd.service-g73it8
systemd-private-f3e84648862148508d5d0aff31e76fe8-fwupd.service-Y4gZd5
ubuntu@little-machine-who-could:~$ ls /tmp/files
flag.txt  packet.txt  readme.txt  secrets.txt
ubuntu@little-machine-who-could:~$ cat *.txt
cat: '*.txt': No such file or directory
ubuntu@little-machine-who-could:~$ cd ^C
ubuntu@little-machine-who-could:~$ cat /tmp/files/*.txt
A flag{it_does_not_appear_to_be_a_humorous_matter} is a piece of fabric (most often rectangular or quadrilateral) with a distinctive design and colours. It is used as a symbol, a signalling device, or for decoration. The term flag is also used to refer to the graphic design employed, and flags have evolved into a general tool for rudimentary signalling and identification, especially in environments where communication is challenging (such as the maritime environment, where semaphore is used). The study of flags is known as "vexillology" from the Latin vexillum, meaning "flag" or "banner".

National flags are patriotic symbols with widely varied interpretations that often include strong military associations because of their original and ongoing use for that purpose. Flags are also used in messaging, advertising, or for decorative purposes.

Some military units are called "flags" after their use of flags. A flag (Arabic: لواء) is equivalent to a brigade in Arab countries. In Spain, a flag (Spanish: bandera) is a battalion-equivalent in the Spanish Legion.In telecommunications and computer networking, a network packet is a formatted unit of data carried by a packet-switched network. A packet consists of control information and user data; the latter is also known as the payload. Control information provides data for delivering the payload (e.g., source and destination network addresses, error detection codes, or sequencing information). Typically, control information is found in packet headers and trailers.In software development, a README file contains information about the other files in a directory or archive of computer software. A form of documentation, it is usually a simple plain text file called README, Read Me, READ.ME, README.TXT, README.md (to indicate the use of Markdown), or README.1ST.Secrecy is the practice of hiding information from certain individuals or groups who do not have the "need to know", perhaps while sharing it with other individuals. That which is kept hidden is known as the secret.

Secrecy is often controversial, depending on the content or nature of the secret, the group or people keeping the secret, and the motivation for secrecy.

Secrecy by government entities is often decried as excessive or in promotion of poor operation[by whom?]; excessive revelation of information on individuals can conflict with virtues of privacy and confidentiality. It is often contrasted with social transparency.ubuntu@little-machine-who-could:~$ 

Tiny server carry: flag{it_does_not_appear_to_be_a_humorous_matter}

It turns out that even if the protocol versions is the same, rsync still breaks transfers between different versions sometimes.

Lesson Learned: The ability to spin up linux distros of your choice very quickly is very useful for ctf and I should actually get more storage for podman on my local machines.