Rating:

I tried the link in my browser and it wasn't loading, so I decided
to statically analyze the webserver in Ghidra.

From the static analysis, I noticed that if "GET / HTTP/1.1" was sent
to the server, that it had a predetermined response. I then pulled up
netcat, connected to the server, and sent "GET / HTTP/1.1" and got this
response (Note that, from here on out, I used netcat to communicate with
the server, since the HTTP requests weren't complicated).

I then noticed that it mentioned to try "GET /echo?message HTTP/1.1",
so I tried that (thanks for making my dynamic analysis easier), and
I did get the string "message" back. Naturally, I was very curious about
how they did that, so I looked more in Ghidra and saw that, if the
header is of the form

"GET /<command>?<arguments> HTTP/1.1"

Then it would do a popen in the code with '<command> <arguments>' as
the string to pass to the function and write the first "few" bytes
from the process output to the HTTP response body.

I tested this with "GET /ls?. HTTP/1.1" to confirm this, and it did
actually list out things in the directory. However, the command acts
kind of funny for some strange reason which I wasn't sure about.

After a bit of toying around, I realized that I could encode spaces in
the command by typing '$' in arguments, since it actually puts a space
whenever it sees '$'

For example, if I write "GET /echo?hello$world$how$are$you HTTP/1.1", the popen
string becomes 'echo hello world how are you'.

I also notice that backticks (`) aren't converted to spaces. That gives me a certain
idea. If I send to the server

GET /echo?`ls$-la` HTTP/1.1

The server should blissfully run "echo `ls -la`" (which it should've done before,
but it never hurts to try different things). Sure enough, running that gives me.

total 104 drwxr-xr-x 1 root root 4096 Mar 27 19:17 . drwxr-xr-x 1 root root 4096 Mar 27 19:17 .. -rw-r--r-- 1 root root 220 Feb 25 2020 .bash_logout -rw-r--r-- 1 root root 3771 Feb 25 2020 .bashrc -rw-r--r-- 1 root root 807 Feb 25 2020 .profile -rwxr-xr-x 1 root root 17704 Mar 27 19:14 a.out -rwxr-xr-x 1 root root 39256 Mar 27 19:14 echo -rw-r--r-- 1 root root 16 Mar 27 19:14 flag.txt -rwxr-xr-x 1 root root 18744 Mar 27 19:14 ynetd

Optionally, you could also do

GET /echo?`ls` HTTP/1.1

to get the simpler output

a.out echo flag.txt ynetd

After that, simply entering

GET /echo?`cat$flag.txt` HTTP/1.1

Gives you the flag

UMASS{f^gJkmvYq}