🔥

picoCTF 2021 Write-Up

2021/07/12に公開

今年はチームで参加して、1940point獲得しました。
結果はなんとも言えない感じとなりましたが・・・
そもそも2019年より難しい?2020のminiも参加したが、それよりも難しい気が・・・

個人で解いた問題について、wrire-upを書こうと思います。

Web Exploitation

Web Gauntlet2 170 points

これ解けなかった・・・
SQLインジェクションでフィルターがかかっている。

Super Serial 130 points

サイト上にフラグがあるとのことで、ディレクトリトラバーサルかな?と想定した
../flag、../../../flagなどをBurpのIntruder機能を使用して片っ端から投げてみた。
URLに../flagが入ったときにフラグゲットできた。
想定解は違うみたい・・・
Cookieにシリアライズされているフラグがいるとか?
SuperSirial.png

picoCTF{th15_vu1n_1s_5up3r_53r1ous_y4ll_9d0864e2}

Cryptography

Mind your Ps and Qs 20 points

素因数分解ができるタイプのRSA問題
素因数分解はfactordbに任せます。

http://factordb.com/
あとはpythonでコードを書くだけ

import gmpy2
from Crypto.PublicKey import RSA
import binascii
n = 1584586296183412107468474423529992275940096154074798537916936609523894209759157543
e = 65537
c = 964354128913912393938480857590969826308054462950561875638492039363373779803642185
p = 2434792384523484381583634042478415057961
q = 650809615742055581459820253356987396346063

d = gmpy2.invert(e,(p-1)*(q-1))
m = pow(c,d,n)
print(m)
flag = binascii.unhexlify(format(m, 'x')).decode()

print("FLAG: {}".format(flag))

picoCTF{sma11_N_n0_g0od_73918962}

Mini RSA 70 points

eの値が小さい場合のRSA暗号問題
解けなかった・・・
暗号文をe乗根するだけではダメ?

Dachshund Attacks 80 points

秘密鍵dが小さいパターンのRSA暗号問題
どうやって求めるかわからなかったが調べるとWiener's Attackというものがある。

https://en.wikipedia.org/wiki/Wiener's_attack

ふむふむ・・・難しい・・・

# wieners_attack.py


import sys
import gmpy2
import binascii

def continued_fraction(n, d):
    """
    415/93 = 4 + 1/(2 + 1/(6 + 1/7))

    >>> continued_fraction(415, 93)
    [4, 2, 6, 7]
    """
    cf = []
    while d:
        q = n // d
        cf.append(q)
        n, d = d, n-d*q
    return cf

def convergents_of_contfrac(cf):
    """
    4 + 1/(2 + 1/(6 + 1/7)) is approximately 4/1, 9/2, 58/13 and 415/93

    >>> list(convergents_of_contfrac([4, 2, 6, 7]))
    [(4, 1), (9, 2), (58, 13), (415, 93)]
    """
    n0, n1 = cf[0], cf[0]*cf[1]+1
    d0, d1 = 1, cf[1]
    yield (n0, d0)
    yield (n1, d1)

    for i in range(2, len(cf)):
        n2, d2 = cf[i]*n1+n0, cf[i]*d1+d0
        yield (n2, d2)
        n0, n1 = n1, n2
        d0, d1 = d1, d2

def wieners_attack(e, n):
    cf = continued_fraction(e, n)
    convergents = convergents_of_contfrac(cf)

    for k, d in convergents:
        if k == 0:
            continue
        phi, rem = divmod(e*d-1, k)
        if rem != 0:
            continue
        s = n - phi + 1
        # check if x^2 - s*x + n = 0 has integer roots
        D = s*s - 4*n
        if D > 0 and gmpy2.is_square(D):
            return d


if __name__ == '__main__':
    n = 89151474814942071327097771942135491722936846692798388440347610026970569180340191480570246995178373601005383752945067605239254817193426405428154520934114285540633003149920246085462912655884144575743520048355350394902876872594144714915105861169838025110023259365467219286397738766462780104090737032311487423801
    e = 36773469691091333526521866573249781598396947711809368370755494421795444255422943324007203983992605995292754319921491236575819247338195057379210755346780833950685614879858794452274663306387794987636833680093160636970987128220540979359655531754697201941686135264297774518407065695373401759358066400363732770269
    c = 47173434529085217822755166519769934295349256492562526124710225636092180584456416434368062367156116655667384943871402612466129307666835696259589514353252826357054395804935365032251869512841815528675793629056845460837650641945476874546653462003148199832652417810108984639402604960331092405689290318254184050536

    d = wieners_attack(e, n)
    print("found d: %d" % d)
    m = pow(c, d, n)
    print(m)
    flag = binascii.unhexlify(format(m, 'x')).decode()
    print(flag)

picoCTF{proving_wiener_6907362}

Play Nice 110 points

問題文の通りncコマンドでアクセス

picopico2-picoctf@webshell:~$ nc mercury.picoctf.net 21003
Here is the alphabet: 0uxtb3w4kj26q9m8gioe7nvahplr5dy1fzcs
Here is the encrypted message: xj5c181ropf5xjmyujnv0wlqrjdrbz
What is the plaintext message? 

全然わからなくて、playfair.pyを読む
playfair?調べてみた
プレイフェア暗号というものがあるのか!ソースコードを読むと、プレイフェア暗号の6×6バージョンであることがわかった。2文字ずつに分割して復号していく。

フラグなくした・・・

Pixelated 200 points

解説難しいので後回し

Reverse Engineering

Shop 50 points

ncコマンドで接続すると、shopがあり商品を全て購入するとフラグがゲットできそう

picopico2-picoctf@webshell:~$ nc mercury.picoctf.net 37799
Welcome to the market!
=====================
You have 40 coins
        Item            Price   Count
(0) Quiet Quiches       10      12
(1) Average Apple       15      8
(2) Fruitful Flag       100     1
(3) Sell an Item
(4) Exit
Choose an option: 

40コインしかないため100コインの商品が購入できない。
ソースコードが提供されており、確認すると入力値チェックがされていないため、40コインしか持っていないが、15コインの商品を8個購入できて所持金がマイナスになる。
ここから地味に時間かかった・・・
-20個商品を購入すると所持金が増えた。マイナスにする発想が抜けてた・・・

2の商品を購入したところ

Flag is:  [112 105 99 111 67 84 70 123 98 52 100 95 98 114 111 103 114 97 109 109 101 114 95 53 57 49 97 56 57 53 97 125]

が表示された。Asciiから文字列に変換する。

picoCTF{b4d_brogrammer_591a895a}

Forensics

Disk, disk, sleuth! 110 points

sakuraEditorでgrepしたらフラグいた

Disk, disk, sleuth! II 130 points

問題文に

All we know is the file with the flag is named `down-at-the-bottom.txt

と記載されているので、The Sleuth Kitを使用してdown-at-the-bottom.txtを検索するとすぐ見つかった。

General Skills

Magikarp Ground Mission 30points

sshで接続
lsコマンドでtxtファイルあるの確認ファイルが3分割されていて、上位階層見ろと言われるので上の階層のtxtを3つ合わせるとフラグになった

Binary Exploitation

What's your input? 50 points

ソース読んで、2018とcityで分岐してそうだから、様子見で入力して挙動確認してみたらフラグ表示された。
実際は、python2の脆弱性?を使用したものらしい。
入力値をパラメータとして認識することで起こるみたい。

Discussion