🐡

ImaginaryCTF 2022/08

2022/09/11に公開

2022年8月1日〜31日にかけて開催されたImaginaryCTFのwriteupです。

Misc

Sanity Check Round 25

ictf{w3lcome_to_round_25!}

cos1

What is the cosine of 42 radians, rounded to 6 decimal places?
Submit your answer wrapped in ictf{}.

ictf{-0.399985}

escape quikmafs

Answer 100 math questions and I'll give you the flag! There's just one small twist...

pythonスクリプトがあたえられます。

#!/usr/bin/env python3

from random import randint, choice
from time import time

# https://pypi.org/project/console/
from console.utils import wait_key
from console.screen import Screen

def win():
    print(screen.clear, end='')
    with screen.location(0, 0):
        print(f"Great job! {open('flag.txt').read()}")

    with screen.location(2, 0):
        print("Press any key to exit.")

    wait_key()
    exit(0)

def die(msg="Sorry, that's not correct."):
    print(screen.clear, end='')
    with screen.location(0, 0):
        print(msg)

    with screen.location(2, 0):
        print("Press any key to exit.")

    wait_key()
    exit(0)

def draw(n1, n2, op):
    eq = "%d %s %d = ?"%(n1, op, n2)
    ans = eval(eq[:-3])
    y = randint(1, 18)
    x = randint(1, 79-len(eq)-1)

    print(screen.clear, end='')
    for row in range(20):
        with screen.location(row, 0):
            if row == 0:
                print('╔' + '═'*78 + '╗', end='')
            elif row == 19:
                print('╚' + '═'*78 + '╝', end='')
            else:
                print('║' + ' '*78 + '║', end='')
                if row == y:
                    with screen.location(y, x):
                        print(eq, end='')

    with screen.location(22, 0):
        print(" "*80)
    with screen.location(22, 0):
        user_ans = int(input(">>> "))

    return ans == user_ans


def main():
    with screen.fullscreen():
        start = time()
        for i in range(100):
            n1 = randint(10000, 99999)
            n2 = randint(10000, 99999)
            op = choice('*-+^&|')
            if not draw(n1, n2, op):
                die()
            if time() - start > 100:
                die("Out of time!")
        win()

if __name__ == '__main__':
    with Screen(force=True) as screen:
        main()

足し算や引き算などの計算を100回正解すれば良さそうな感じ。
pythonでスクリプトを書きました。

from pwn import *

io = remote('puzzler7.imaginaryctf.org',4006)

for i in range(100):
    re = io.recvuntil('=')[-15:]
    
    n1 = int(re[:5])
    n2 = int(re[8:14])
    op = re[6:7].decode()
    
    e = "%d %s %d = ?"%(n1, op, n2)
    solve = eval(e[:-3])
    
    io.sendline(str(solve))
    
io.interactive()

ictf{congrats_you've_conquered_the_blackboard...for_now...}

Forensics

mixup

Something went wrong here...

$ cat flag.txt
> i‎c‮t‎f‮{‎‎un1c0‮de_m‮4g1c_na‎‮h‎s‮d‮fo‮‎asi‎h‮‮df‎asoh‮‎dfoi‎ashdf‎‮‎j‎‮k‎a‎‮‎d‎s‮‮hf‮‎lj‮ad‮‎‮s‮f‎hdskl‮a‎‮h‎fl‮‮‎k‮hj‎‎‮d‎‎‮‮‮a‎‎fs}

与えられたファイルを確認してみると、フラグっぽい感じはあるけどちょっとおしい、、、

$ file -i flag.txt
> flag.txt: text/plain; charset=utf-8

与えられたファイルはUTF-8で変換されているらしい。んー、とりあえず他の変換方式でも試してみようかなと

$ nkf -w16L0 -l flag.txt
> ictf{un1c0de_m4g1c_nahsdfoasihdfasohdfoiashdfjkadshfljadsfhdsklahflkhjdafs}

運良くUTF-16でflagがでました。
ictf{un1c0de_m4g1c_nahsdfoasihdfasohdfoiashdfjkadshfljadsfhdsklahflkhjdafs}

Crypto

Enormous

I hear that more bits of security is better, so I'm using MASSIVE primes, and a TON of them! I bet you can't recover my flag now...

pythonスクリプトとoutput.txtが配布されます。

#!/usr/bin/env python3

from Crypto.Util.number import *

m = bytes_to_long(open('flag.txt', 'rb').read())

n = 1
for i in range(5):
    n *= getPrime(2025)

e = 31
c = pow(m, e, n)

print(f'{n = }')
print(f'{c = }')
n = 291803461471835548029967773522617765771350293869936352202474825278720037203079126582761195517055393337441548702117740296881683037727672928813574338546415946481976583248116652581196557944379208515379849557208903959136881415277929278949854798024237931268890091008477560536810024512885987056365875451976655685041061567307476564581225633751629621363138947815696306121690184995538414167930734015725366640439645369938523746682075126307100603220423134559397115857296708492139355989095937406415073168747479949371092134873701556328545495456400479495405193756279972004658782475408189585025641505819277077925673695334900236713191922331469670007945415879984668758786665610223439789798214375546410680980683442235218021025215976372242754132940477478408728993116985028306733912194477013321051867704500024616342520287838575375839552875084135772432229149413294380432533743143268579060594509980073144254923676380538357838797628476519470503636727538392293326221896054673794948778257952143474326337234955144876478098752630600927746134626196808185237724150959895921700993985671689787276218491977409950443800149225682113795630552332504004952619477399053219103742133837193866168480669953649964494066888017534621349322438584844756384881305359216958596115238052386689420189458226861633978864646432620132110836770754297086384562270853072519298962385476479869301761383621785222318621201306854098202131486922131567300293859330130962769515935517026489631422656886068186229630258223006684833047809688321362843298049850048526302305175457080852712874501906848203834687269452532674672111135077303202528935822816608612547229714776677161298357980007749334544698155455911782984751127779599045510344930085038624054982145201414246233123815597579302583147041169085302625820240543206702814039468429064024961160403696288636475388432798179348622575416616596660498584921414806447533272237263496191108268914962604350759322278134843256344477715665697069507629272092477112527371006313935780156040584212958154549663363234981080730341044630508652240837192014074955790169192194298119435104568924354781734446534914749601480158889645876224737439717511154355206076336705115742763304668954084456504898364386765064143296380474352710379369338692522064891115596552538797109330579251735034330969865851105628851397031731926651793499033360226446821843504185544154328716719785183357806999155047816431736359882490550923048419234555352161279478407242984715707163307294861304711709346203477359865199980901678783907976621786706266847296286119737497401164377524189197707568924565911584058570117345183256470833488981286971331095107229945553900124115789585129411526064683438180406246914918344456337671900934740227313729020212681061906134397379053692184471039837008926116046967034965277671872122518335972888506407864660599133420704405557724318002121940379059800231596103401873109461507047985158261487833687090154196870319427268386336264078936523908731859981832206513441924170577885564684644417486126018121796087385930741681311819019125337235246299198151106436637821460451583430819222542798910970466234016929862844811
c = 226930369324008404506430665129822599607363575603852919162120583266060503841096845215449850837542305149561600338927114119661251460696499327139957176529329816529721270191210916244477856685216908277164786965592514696226839914244875659319076517558315356771625419496558856490589162500644071477833930756663564789474118682399930460441453389184243891216077282099093040608309336018996001999607804378777688916461360425788926205328424150096034051909616660195338367962715944075422262015953517413557051762509103453392458978208273498438562590307215849951642965795004794034627510875473381435541017212698396608282069420063879979294704473018597265098131904018063045638336304539514249356120536639126440406176682131920666202709416873040296025545675588170167188101050321143515763604977360112398853875935854811777919563324598193504991150103686515910286033304218405898596673422366231606745906059933502082246405148016608529329647781881278472976090154368272290761619490459310416194216982004034487788734832367018517887748097898401525507381806366491661667977442619626223736995461937920878273486909559233659993985592623485669719325763874250803422121180632196849036588606681806804779542977650673644965059641304478487892054477356779339273971259597178303031111140283501709064199430436811542668710546345343441829103999774652299936885473523503009793950905394505839067527152330406049376043739899459809162044962915696399547788486686478589032533842260339084289115269117632962020418999678475193626806742925843561762423017088328632995430074096317560695952243685718370993439935920576217955150699936307124819436288798249076737597129112939696691564055039464675485835224015600323880336127740300585706502138276566411354270875449815373574454780958012435380709513462476775660322560648809380299392885568074034592363611854633574329130489038883130308557866650522882369513797748667234932757559604717587488355500387902038121779580165322861111064918787012060293221646897837406810365496082480818

eが小さくnが非常に大きい場合Low Public exponent Attackが適用できます。

import gmpy2
import binascii

n = 291803461471835548029967773522617765771350293869936352202474825278720037203079126582761195517055393337441548702117740296881683037727672928813574338546415946481976583248116652581196557944379208515379849557208903959136881415277929278949854798024237931268890091008477560536810024512885987056365875451976655685041061567307476564581225633751629621363138947815696306121690184995538414167930734015725366640439645369938523746682075126307100603220423134559397115857296708492139355989095937406415073168747479949371092134873701556328545495456400479495405193756279972004658782475408189585025641505819277077925673695334900236713191922331469670007945415879984668758786665610223439789798214375546410680980683442235218021025215976372242754132940477478408728993116985028306733912194477013321051867704500024616342520287838575375839552875084135772432229149413294380432533743143268579060594509980073144254923676380538357838797628476519470503636727538392293326221896054673794948778257952143474326337234955144876478098752630600927746134626196808185237724150959895921700993985671689787276218491977409950443800149225682113795630552332504004952619477399053219103742133837193866168480669953649964494066888017534621349322438584844756384881305359216958596115238052386689420189458226861633978864646432620132110836770754297086384562270853072519298962385476479869301761383621785222318621201306854098202131486922131567300293859330130962769515935517026489631422656886068186229630258223006684833047809688321362843298049850048526302305175457080852712874501906848203834687269452532674672111135077303202528935822816608612547229714776677161298357980007749334544698155455911782984751127779599045510344930085038624054982145201414246233123815597579302583147041169085302625820240543206702814039468429064024961160403696288636475388432798179348622575416616596660498584921414806447533272237263496191108268914962604350759322278134843256344477715665697069507629272092477112527371006313935780156040584212958154549663363234981080730341044630508652240837192014074955790169192194298119435104568924354781734446534914749601480158889645876224737439717511154355206076336705115742763304668954084456504898364386765064143296380474352710379369338692522064891115596552538797109330579251735034330969865851105628851397031731926651793499033360226446821843504185544154328716719785183357806999155047816431736359882490550923048419234555352161279478407242984715707163307294861304711709346203477359865199980901678783907976621786706266847296286119737497401164377524189197707568924565911584058570117345183256470833488981286971331095107229945553900124115789585129411526064683438180406246914918344456337671900934740227313729020212681061906134397379053692184471039837008926116046967034965277671872122518335972888506407864660599133420704405557724318002121940379059800231596103401873109461507047985158261487833687090154196870319427268386336264078936523908731859981832206513441924170577885564684644417486126018121796087385930741681311819019125337235246299198151106436637821460451583430819222542798910970466234016929862844811
e = 31
c = 226930369324008404506430665129822599607363575603852919162120583266060503841096845215449850837542305149561600338927114119661251460696499327139957176529329816529721270191210916244477856685216908277164786965592514696226839914244875659319076517558315356771625419496558856490589162500644071477833930756663564789474118682399930460441453389184243891216077282099093040608309336018996001999607804378777688916461360425788926205328424150096034051909616660195338367962715944075422262015953517413557051762509103453392458978208273498438562590307215849951642965795004794034627510875473381435541017212698396608282069420063879979294704473018597265098131904018063045638336304539514249356120536639126440406176682131920666202709416873040296025545675588170167188101050321143515763604977360112398853875935854811777919563324598193504991150103686515910286033304218405898596673422366231606745906059933502082246405148016608529329647781881278472976090154368272290761619490459310416194216982004034487788734832367018517887748097898401525507381806366491661667977442619626223736995461937920878273486909559233659993985592623485669719325763874250803422121180632196849036588606681806804779542977650673644965059641304478487892054477356779339273971259597178303031111140283501709064199430436811542668710546345343441829103999774652299936885473523503009793950905394505839067527152330406049376043739899459809162044962915696399547788486686478589032533842260339084289115269117632962020418999678475193626806742925843561762423017088328632995430074096317560695952243685718370993439935920576217955150699936307124819436288798249076737597129112939696691564055039464675485835224015600323880336127740300585706502138276566411354270875449815373574454780958012435380709513462476775660322560648809380299392885568074034592363611854633574329130489038883130308557866650522882369513797748667234932757559604717587488355500387902038121779580165322861111064918787012060293221646897837406810365496082480818926712329359069411884747738664835433270202960934930293501624299923646957173316725913900452048522962309107483401916982942273644258253234270266404355705906353284060421906451579547553536945596143114182089674169040390233403896259650990843716723248382763373947627940237097774346467516704409787940216547116621556170101766022005778473958237584851951344954861454573678221816288918395713861770977183669035942556070546761545743731295074496369509049235313470403093920087296483871093325318582310743131764728865964884228088025170409263061963059341395163695331110078909587683201275928829278515137618074138615962652765840849275249482071226860249873486273492767754112528529082909363770315076153401338000909130399064593162194239842969972233531547178659983688101566357539063657007915493318885261560981584227020995472033268237671253586876466785624983819848898009727296036477735934655396784185145970437264598583023149435320752783415451501056661506420824553646380553999069539369921607338465904854175989857439546309918605715931884872868486467592929171204176835962074595013700782437300593834359405047404582902352876008272897313

def LPA(c, e, n):
    while(True):
        m, b = gmpy2.iroot(c, e)
        if b:
            break
        else:
            c += n
    return int(m)

m = LPA(c, e, n)
flag = binascii.unhexlify(format(int(m), 'x')).decode()
print(flag)
python3 solve.py
ictf{d0nt_f0rget_t0_pad_y0ur_pl@intexts!}

aes

与えられたのはpythonスクリプト

import random
from Crypto.Cipher import AES

key = random.choice(open("rockyou.txt", "rb").readlines()[:10000]).strip()
key = key.zfill(16)
cipher = AES.new(key, AES.MODE_ECB)
cipher.encrypt(open("flag.txt", "rb").read().zfill(48))

# >>> b"\xd6\x19O\xbeA\xb0\x15\x87\x0e\xc7\xc4\xc1\xe9h\xd8\xe6\xc6\x95\x82\xaa#\x91\xdb2l\xfa\xf7\xe1C\xb8\x11\x04\x82p\xe5\x9e\xb1\x0c*\xcc[('\x0f\xcc\xa7W\xff"

フラグがAESによって暗号化されています。
ただ、keyはrockyou.txt内のファイル上位10000個の中から選ばれているので、総当りでデコードできそうです。

import random
from Crypto.Cipher import AES

key_list = open("rockyou.txt", "rb").readlines()[:10000]

for key in key_list:
    key = key.strip()
    key = key.zfill(16)
    cipher = AES.new(key, AES.MODE_ECB)
    
    cipher_text = b"\xd6\x19O\xbeA\xb0\x15\x87\x0e\xc7\xc4\xc1\xe9h\xd8\xe6\xc6\x95\x82\xaa#\x91\xdb2l\xfa\xf7\xe1C\xb8\x11\x04\x82p\xe5\x9e\xb1\x0c*\xcc[('\x0f\xcc\xa7W\xff"
    print(cipher.decrypt(cipher_text))

同じディレクトリにrockyou.txtを用意して、出力をパイプしてgrepで'ictf'とするとフラグが見つかりました。

$ python3 solve.py | grep ictf
b'0000000000000000000ictf{d0nt_us3_w3ak_k3ys!!!!}\n'

same

Something here is the same...

pythonスクリプトとoutput.txtが与えられます。

from Crypto.Util.number import getPrime, bytes_to_long
m = bytes_to_long(open("flag", "rb").read())
n = getPrime(512)*getPrime(512)
e = [1337,31337]
print(n)
print(pow(m,e[0],n))
print(pow(m,e[1],n))
88627598925887227793409704066287679810103408445903546693879278352563489802835708613718629728355698762251810901364530308365201192197988674078034209878433048946797619290221501750862580914894979204943093716650072734138749420932619469204815802746273252727013183568196402223549961607284086898768583604510696483111
45254947860172381004009381991735702721210786277711531577381599020185600496787746985669891424940792336396574951744089759764874889285927022268694128526139687661305707984329995359802337446670063047702309778972385903473896687843125261988493615328641864610786785749566148338268077425756876069789788618208807001704
16054811947596452078263236160429328686151351092304509270058479526590947874445940946506791900760052230887962479603369427120610506778471930164144528718052332194666418267005043709704814833963217926271924910466448499814399455203725279998913865531351070938872586642424346857094632491904168889134624707595846754719

同一の平文を異なるeで暗号化した暗号文が得られる時、Common Modulus Attackが出来よう可能です。

import gmpy2, binascii

n = 88627598925887227793409704066287679810103408445903546693879278352563489802835708613718629728355698762251810901364530308365201192197988674078034209878433048946797619290221501750862580914894979204943093716650072734138749420932619469204815802746273252727013183568196402223549961607284086898768583604510696483111
e1 =1337
c1 = 45254947860172381004009381991735702721210786277711531577381599020185600496787746985669891424940792336396574951744089759764874889285927022268694128526139687661305707984329995359802337446670063047702309778972385903473896687843125261988493615328641864610786785749566148338268077425756876069789788618208807001704
e2 = 31337
c2 = 16054811947596452078263236160429328686151351092304509270058479526590947874445940946506791900760052230887962479603369427120610506778471930164144528718052332194666418267005043709704814833963217926271924910466448499814399455203725279998913865531351070938872586642424346857094632491904168889134624707595846754719

val = gmpy2.gcdext(e1,e2)
m1 = pow(c1, val[1], n)
m2 = pow(c2, val[2], n)
m = (m1 * m2)%n

flag = binascii.unhexlify(format(m, 'x')).decode()
print(flag)
python3 solve.py
ictf{n3ver_r3use_m0dul1}

Web

Replacement

Red flags and fake flags form an equivalence class.

リンクに飛んでみると次のような画面が表示されました。

フラグがフェイクと置き換えられてしまっているよう。
JSを使って置き換えているなら、本物のフラグも送られてきているはずななので、開発者ツールでポチポチ眺めていると、networkタブにありました。

Reversing

I like to MOV it, MOV it!

We'll get there soon ... byte-by-byte.

実行ファイルが配布されます。

chall: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, not stripped

とりあえずghidraに突っ込んでdecompileしてもらうと、フラグが格納されている配列が見つかりました。

ictf{mov_S1d3_ChanN3l_Att4ck}

Discussion

ログインするとコメントできます