以下の内容はhttps://yocchin.hatenablog.com/entry/2024/05/28/101504より取得しました。


L3akCTF 2024 Writeup

この大会は2024/5/24 21:00(JST)~2024/5/26 21:00(JST)に開催されました。
今回もチームで参戦。結果は1189点で497チーム中99位でした。
自分で解けた問題をWriteupとして書いておきます。

Sanity Check (MISC)

Discordに入り、#rulesチャネルのトピックを見ると、フラグが書いてあった。

L3AK{W3lc0ME_To_L34k_CTF!}

Geosint-1 (OSINT)

Google Mapのように特定の位置の周囲を見ることができるので、指定されたGeoGuessrのシステムでポイントし、Submitする。正しければ、フラグが表示されるという仕組み。
後方に特徴的な橋が見える。

この画像を取り、画像検索すると、ヴェラザノ=ナローズ・ブリッジであることがわかる。Google Mapでこの橋が渡っている川に沿って行くと、周囲の映像と同じような位置がわかった。

https://www.google.co.jp/maps/@40.6342874,-74.0387092,3a,75y,318.21h,96.75t/data=!3m7!1e1!3m5!1sbYHmJefa0cMQM0jmW5RPlA!2e0!6shttps:%2F%2Fstreetviewpixels-pa.googleapis.com%2Fv1%2Fthumbnail%3Fpanoid%3DbYHmJefa0cMQM0jmW5RPlA%26cb_client%3Dmaps_sv.share%26w%3D900%26h%3D600%26yaw%3D318.2084523544373%26pitch%3D-6.7471125241843595%26thumbfov%3D90!7i16384!8i8192?hl=ja&coh=205410&entry=ttu

Bobby Bello Fieldの3つのグリーンの内一番北にあるものの前あたりが該当する。

L3AK{Verr4zz4n0_Br1dge_1s_pR3tty_c00l}

Layout (HARDWARE-RF)

GDS Viewerで開くと、フラグを確認することができた。

L3AK{w3LcoM3_To_HArDw4R3!}

Hidden (REV)

Ghidraでデコンパイルする。

undefined8 FUN_001013e5(undefined8 param_1,long param_2)

{
  int iVar1;
  char *__s2;
  
  __s2 = (char *)FUN_0010137d();
  if ((*(long *)(param_2 + 8) != 0) && (iVar1 = strcmp(*(char **)(param_2 + 8),__s2), iVar1 == 0)) {
    puts("Correct!");
    return 0;
  }
  puts("Wrong!");
  return 0;
}

void * FUN_0010137d(void)

{
  void *pvVar1;
  
  pvVar1 = malloc(0x200);
  FUN_00101214(pvVar1,0x4c,0x33,0x41,0x4b,0x7b,0x62,0x34,0x62,0x79,0x5f,0x73,0x54,0x33,0x50,0x73,
               0x7d,0);
  return pvVar1;
}

FUN_0010137d関数で引数に渡しているコードをASCIIコードとして結合すると、フラグになりそう。

>>> bytes([0x4c,0x33,0x41,0x4b,0x7b,0x62,0x34,0x62,0x79,0x5f,0x73,0x54,0x33,0x50,0x73,0x7d])
b'L3AK{b4by_sT3Ps}'
L3AK{b4by_sT3Ps}

Really Simple Algorithm (CRYPTO)

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

・e = 1337
・size = 1024
・以下繰り返し
 ・p, q: 1024ビット素数
 ・n = p * q
 ・option: 数値入力
 ・optionが1の場合
  ・message: 入力→数値化
  ・enc_msg = pow(message, e, n)
  ・n, enc_msgを表示
 ・optionが2の場合
  ・enc_flag = pow(フラグの数値化, e, n)
  ・n, enc_flagを表示
 ・optionが3の場合、終了

Hastad's Broadcast Attackで復号する。

#!/usr/bin/env python3
import socket
from Crypto.Util.number import *
from sympy.ntheory.modular import crt
from gmpy2 import iroot

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(('193.148.168.30', 5668))

for _ in range(4):
    data = recvuntil(s, b'\n').rstrip()
    print(data)

e = 1337
ns = []
cs = []
for _ in range(e):
    data = recvuntil(s, b': ')
    print(data + '2')
    s.sendall(b'2\n')
    data = recvuntil(s, b'\n').rstrip()
    print(data)
    ns.append(int(data.split(' ')[-1]))
    data = recvuntil(s, b'\n').rstrip()
    print(data)
    cs.append(int(data.split(' ')[-1]))

me, _ = crt(ns, cs)
m, success = iroot(me, e)
assert success
flag = long_to_bytes(m).decode()
print(flag)

実行結果は以下の通り。

Welcome to the L3ak Really Simple Algorithm (RSA) Encryption Service™!
Here you can encrypt your own message, or choose to receive the encrypted flag.
Good luck!

(1) Encrypt Message
(2) Receive Flag
(3) Exit
Select Option: 2
n = 17174931731156529458002853476994633232360264628689265534723755925243038170232171246118177178249712289804216770145531104090968864923615156475160729564808128170537434703047827764024174531751137320122330629322954497916782089604528822712011950348413544687326766594034027065014122047689089265279290881965084305965509120952780299518704139811795646734104828640841632984098475964491826094865282342891585391556795859726144505657626072648920933815665109844268911666543325990982542327311125913200428638634189502325040956328683809919506334613479182357932207463000567179139242027508841470214302682736622596710545949741700663949103
flag = 11177563111593026837289848116822445170889918216794060058556700252742256468152248455463609727625872611435212349814431875624542569241511097922806051127725167078689847071422441250294253133938045756651455480986578621033484506835994992330097485229317603408936060527619464594196035069900144478805344041858627415660942515209118243920047671369026661170447463000119803969606099280328684520495354222208417441847052255313771854966622246620695420834470395898627505283043136628361601300474790102555909265768841110265456535689573118137319200258450267043814628376190817080861607960182762591450998085243159691124479141773448283815959
(1) Encrypt Message
(2) Receive Flag
(3) Exit
Select Option: 2
n = 16785254444187310479246706237562827469967680899254854206099526794498371043384479379723162575017112722995640076061545136009385657544791520678748600346653791964566686852941536505634338032543219895155748875226656628066397511490941174606333662679458943107272407122782806393212359613986186827499180388468836053103728408297227153482293812419175456791019348142188831941989037358418741803493261864857035178440639883286491714466362151811517374488027531026376403696091975399749429503307799294343132976575740839010968161840615427329210444411933601315010545929562311668802661383890253528457381944578267299583616215025102722142683
flag = 3858395372306622130332404257143424400085915953628333840003764145690002350101610856018582850497248647555389302191981739941146899249276955510912571796667278167458332570407627921340554344385814541058819380987634522982374342582615265025242190474226937369558628849968936734125501660589626968419674643152696859615574678674516557623691258748537541211031352041531164973822305866470290062803689813514924294802305248989013413105385698759374399445784729697382636416985115933618936115423750447793360080689170922620176824388612992918614121775891039084885911529154129480511721924849027003413018469963371957972250501096307442475303
        :
        :
(1) Encrypt Message
(2) Receive Flag
(3) Exit
Select Option: 2
n = 15784330843315732305818840236838315475471499802480233831700652385565351264481198880252255992585167314015109835277865422849530867509752051369722126956642601595057094660675663450955669956945806062930683029322844072135436365471070569260308746156916858644636391982095983543197427743295576949035658598380850177650840501778731960674463820644931363224309578728868553823049144138736351600152622633737316439618022596812657966925566359169374358948838253455028534194740454281678227757875334349279734195134625105664622520121893954779858195743024889091956734573792582661989342486386793906752433573624871782800361047251938036803819
flag = 8805940144413235988602731977332684857126763796125664556819845152455257407351700944804678592146349320189173678418674604009835843622450489542961571633827104230652137426385193280911834504354958733432039356637137941851719413647866813240412946863255650518183085069132326800891167473010224874425799150555024313298492543729139006561799291624460392302484570739309113920014236689387314025004797759385992861926649378255408338403017289241480050980049900963436182104782427198254450923620584737594391152140046055985327395160540836249229400870580388104020797071554011487930425083375122276198270502161739406061844336518249443179997
(1) Encrypt Message
(2) Receive Flag
(3) Exit
Select Option: 2
n = 22119644369512239563954541425398519351333394170915004314891644119900335190380073460368616041039439648607431460336742463934504201225266969814860789994230832420993570885284282828412659320903651401486173205426766581616501650271002366684930277585202761910496717750978323778114933633289750457212725430263444682132082589024671212046677921411838174728819823622110104786919737970358924066450090960159342605181754880306871133548677879047851771766798159207277439620742596258236980681768867676460531371361283469318594321242152176744132964047137339536502943570554843483205086815865703766915556259303151954300105385928990267249107
flag = 1716770341357323972841741286212606919654869453219292498489982600276844456130800630733637266840131006623721925322789509177115192688110807300730462720552820925130467778182770977679815891001621148984327197559729142740566547208534532197661939026204048856532765718661976785435427319537859456208370223473693300304311596495280701792078836047015295238565213502666989983279508139282219319921535348164764110200061964056116456927872876644531496331505724873347792720151122283074944011276016186325781432403424035694620292321536218531809124209833415214881978714289992771405792855999392417109942572098672348267920116058723158864736
L3AK{H4sTAD5_bR0aDc45T_4TtacK_1s_pr3tTy_c0ol!}
L3AK{H4sTAD5_bR0aDc45T_4TtacK_1s_pr3tTy_c0ol!}

暗号の処理概要は以下の通り。

・p, q: 1024ビット素数
・n = p * q
・e = 0x101
・variables, ct1 = encrypt(FLAG)
 ・padded_variables, padded_message = pad(FLAG)
  ・m: FLAGの数値化
  ・a, b: ランダム2以上n以下の整数
  ・(a, b), a * m + bを返却
・a1 = variables[0]
・b1 = variables[1]
・variables, ct2 = encrypt(FLAG)
・a2 = variables[0]
・b2 = variables[1]
・n, a1, b1, ct1, a2, b2, ct2を表示

以下のように式を変形することができる。

m1 = a1 * m + b1
m2 = a2 * m + b2
  ↓
m1 * inverse(a1, n) * a2 % n = (a2 * m + b1 * inverse(a1, n) * a2) % n
m2 % n = (a2 * m + b2) % n

new_m1 = m1 * inverse(a1, n) * a2 % n とすると以下のようになる。

new_m1 = (a2 * m + b1 * inverse(a1, n) * a2) % n
m2     = (a2 * m + b2) % n

new_ct1 = pow(new_m1, e, n) = pow(m1, e, n) * pow(inverse(a1, n) * a2, e, n)
        = ct1 * pow(inverse(a1, n) * a2, e, n)

平文のnew_m1とm2は差がわかり、new_ct1とct2がわかるので、Franklin-Reiter Related Message Attackで復号できる。

#!/usr/bin/env sage
from Crypto.Util.number import *

def related_message_attack(c1, c2, diff, e, n):
    PRx.<x> = PolynomialRing(Zmod(n))
    g1 = x^e - c1
    g2 = (x+diff)^e - c2

    def gcd(g1, g2):
        while g2:
            g1, g2 = g2, g1 % g2
        return g1.monic()

    return -gcd(g1, g2)[0]

e = 0x101

with open('out.txt', 'r') as f:
    params = f.read().splitlines()

n = int(params[0].split(' ')[-1])
a1 = int(params[1].split(' ')[-1])
b1 = int(params[2].split(' ')[-1])
ct1 = int(params[3].split(' ')[-1])
a2 = int(params[4].split(' ')[-1])
b2 = int(params[5].split(' ')[-1])
ct2 = int(params[6].split(' ')[-1])

diff = (b2 - b1 * inverse(a1, n) * a2) % n
new_ct1 = ct1 * pow(inverse(a1, n) * a2, e, n) % n

m2 = int((related_message_attack(new_ct1, ct2, diff, e, n) + diff) % n)
m = (m2 - b2) * inverse(a2, n) % n
FLAG = long_to_bytes(m).decode()
print(FLAG)
L3AK{r3l4teD_m3s54GeS_Ar3_1nS3cuR3_1n_RsA}

Survay (MISC)

アンケートに答えたら、フラグが表示された。

L3AK{thanks_for_the_honest_feedback_hope_to_see_you_next_year}



以上の内容はhttps://yocchin.hatenablog.com/entry/2024/05/28/101504より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14