GlacierCTF 2022 Writeup

この大会は2022/11/26 3:00(JST)~2022/11/27 3:00(JST)に開催されました。
今回もチームで参戦。結果は50点で293チーム中228位でした。
自分で解けた問題をWriteupとして書いておきます。

CryptoShop (Crypto)

サーバの処理概要は以下の通り。

・key = RSA.generate(1024)
・user: 入力
・user_shop_state = ShopState(user, priv_key=key)
 ・user_shop_state.name = user
 ・user_shop_state.balance = 5
 ・user_shop_state.priv_key=key
・nを表示
・以下繰り返し
 ・action: メニュー選択
 ・actionが1の場合
  ・SHOP_ITEMのリストを表示
 ・actionが2の場合
  ・ret_val = buy_menu(user_shop_state)
   ・SHOP_ITEMのリストを表示
   ・item_name: 入力(SHOP_ITEMのリストから選択)
   ・shop_transaction = user_shop_state.buy(item_name)
    ・price = SHOP_ITEMS[name]
    ・user_shop_state.balance -= price
    ・nameが"CTF-Flag"の場合、フラグを表示
 ・actionが3の場合
  ・refund_menu(user_shop_state)
   ・refund_code: 数値入力
   ・refund_amount: 数値入力
   ・ret_val = shop_state.refund_item(refund_amount, refund_code)
    ・reference_code = pow(refund_amount, priv_key.d, priv_key.n)
    ・refund_codeとreference_codeが一致していなかったら、エラー
   ・self.balance += refund_amount

refund_codeを適当に決めれば、refund_amountは計算できる。balanceをいくつ増やせるかわからないが、"3. Refund Item"でお金を増やしてから"CTF-Flag"を購入すればよい。

#!/usr/bin/env python3
import socket

def recvuntil(s, tail):
    data = b''
    while True:
        if tail in data:
            return data.decode()
        data += s.recv(1)

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('pwn.glacierctf.com', 13370))

name = 'hoge'
data = recvuntil(s, b'Name: ')
print(data + name)
s.sendall(name.encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)
data = recvuntil(s, b'\n').rstrip()
print(data)
n = int(data.split(' ')[-1])
e = 65537

refund_code = 123
refund_amount = pow(refund_code, e, n)

data = recvuntil(s, b'> ')
print(data + '3')
s.sendall(b'3\n')
data = recvuntil(s, b'> ')
print(data + str(refund_code))
s.sendall(str(refund_code).encode() + b'\n')
data = recvuntil(s, b'> ')
print(data + str(refund_amount))
s.sendall(str(refund_amount).encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)

name = 'CTF-Flag'
data = recvuntil(s, b'> ')
print(data + '2')
s.sendall(b'2\n')
data = recvuntil(s, b'> ')
print(data + name)
s.sendall(name.encode() + b'\n')
data = recvuntil(s, b'\n').rstrip()
print(data)

実行結果は以下の通り。

Welcome to the PWN-Store. Please authenticate:
Your Name: hoge
Welcome back hoge!
Customernumber: 7119721955343994183071926664728781069068259341041962068678026711320632265515328667825548834086402718937206499370165240435106462931401311426817541407394864931964914449993155272219102668079956928713964345093493990223803472192032745331126530815885131855451784184488615697798547817851039593573136752861093826898410784306797981998338207012141328656314133530507195522013331834575215399377349318775598158104520534533323355277030405297034933722514046393086894084789991753796092241591544779576734104012720135162455447401549676796159824422836857182136259358314574596700050458496328999928487581277472975819180410658160779145329271

Accountname: hoge (Balance: 5€)
1. List Items
2. Buy Item
3. Refund Item
4. Exit

> 3
What do you want to refund?
Please provide the refundcode
> 123
Please provide the price
> 2352813905034380768739326772644101336213320691336953895260595710490803047368364690810476725973946740537713893457921344990539821538266773148636467368537535684808228026390702608533660688949344950546652277870802796095301569468119294744479769451101548049119315431746736743587823714475418372912332080712226230694386860795778002435508057291454297876524341486838382148622641835964117225361468881383743005049132917527997338008399214700083224579493541253520390600052347889934774983798319310654016210253931720049134778274053188765666593027187877238291246827829413350668928520165852974362964062036713893826193875481430795607845158
Successfully refunded

Accountname: hoge (Balance: 2352813905034380768739326772644101336213320691336953895260595710490803047368364690810476725973946740537713893457921344990539821538266773148636467368537535684808228026390702608533660688949344950546652277870802796095301569468119294744479769451101548049119315431746736743587823714475418372912332080712226230694386860795778002435508057291454297876524341486838382148622641835964117225361468881383743005049132917527997338008399214700083224579493541253520390600052347889934774983798319310654016210253931720049134778274053188765666593027187877238291246827829413350668928520165852974362964062036713893826193875481430795607845163€)
1. List Items
2. Buy Item
3. Refund Item
4. Exit

> 2
What item do you want to bye?
0. USB Rubber Ducky
1. Malduino
2. WIFI Deauther
3. Bluetooth Jammer
4. GSM Jammer
5. Bad USB
6. CTF-Flag

> CTF-Flag
Take this: glacierctf{RsA_S1gnAtuRe_1ssu3}
glacierctf{RsA_S1gnAtuRe_1ssu3}