この大会は2022/9/10 15:00(JST)~2022/9/11 15:00(JST)に開催されました。
今回もチームで参戦。結果は620点で166チーム中50位でした。
自分で解けた問題をWriteupとして書いておきます。
Signals From Space (Hardware 80)
sstvでデコードしてみる。
$ sstv -d signal_from_space.wav -o flag.png [sstv] Searching for calibration header... Found! [sstv] Detected SSTV mode Martin 2 [sstv] Decoding image... [#############################################] 100% [sstv] Drawing image data... [sstv] ...Done!
出力した画像にフラグが書いてあった。
ctf{0ld_5ch00l_73ch}
passWORDLE (Reverse 80)
スクリプト"./js/passwordle.js"を見てみる。
const targetWords = [ 'password', '123456', '12345678', '1234', 'qwerty', '12345', : : 'epson', 'evangeli', 'eeeee1', 'eyphed', ] : : function randomPassword() { const offsetFromDate = new Date(2022, 0, 1) const msOffset = Date.now() - offsetFromDate const dayOffset = msOffset / 1000 / 60 / 60 / 24 const res = targetWords[Math.floor(dayOffset)] return res; } : :
年月日によって、パスワードが決まり、2022/1/1と2022/10/10の日数の差から該当するパスワードを求めることができる。
#!/usr/bin/env python3 import datetime targetWords = [ 'password', '123456', '12345678', '1234', 'qwerty', '12345', : : 'epson', 'evangeli', 'eeeee1', 'eyphed', ] dt1 = datetime.datetime(2022, 1, 1) dt2 = datetime.datetime(2022, 10, 10) td = (dt2 - dt1).days password = targetWords[td] flag = 'ctf{%s}' % password print(flag)
ctf{united}
The searcher (Web 180)
フラグに使われている文字を入力すると、Resultsにその数が表示される。位置もあっていると、regularにその数が表示される。このことから推測していく。
使われている文字は以下の文字であることがわかる。
BRSTacdefghinort{}
あとは先頭から推測していく。最終的には以下を入力すると、本当のフラグが表示された。
ctf{SearchingToBeRedefined}
You rock. Here is the real Flag ctf{SearchIsMakingLifeEasier}
ctf{SearchIsMakingLifeEasier}
Cat Caffee (Network 100)
pcapの通信データは802.11で、WPAで暗号化されてるようなので、クラックする。
$ aircrack-ng -w dict/rockyou.txt traffic.pcap Reading packets, please wait... Opening traffic.pcap Read 41264 packets. # BSSID ESSID Encryption 1 00:1E:42:12:D6:A2 Unknown 2 00:21:29:77:A3:05 CatCaffee WPA (1 handshake) 3 0C:F4:D5:D5:76:43 Recover.Me-157640 Unknown 4 50:C7:BF:79:E4:4A WPA (0 handshake) 5 BA:2E:61:13:FD:CD WEP (0 IVs) 6 D4:68:4D:65:F3:93 Recover.Me-25F390 Unknown 7 D8:97:BA:01:04:AE dbed26 Unknown 8 DA:97:BA:01:04:AF UniFi Unknown 9 F4:17:B8:CD:66:F7 Rumburak Unknown 10 F4:17:B8:CD:66:FB Rumburak WPA (0 handshake) Index number of target network ? 2 Reading packets, please wait... Opening traffic.pcap Read 41264 packets. 1 potential targets Aircrack-ng 1.6 [00:35:26] 10532772/14344392 keys tested (4892.84 k/s) Time left: 12 minutes, 59 seconds 73.43% KEY FOUND! [ THUNDERCATS ] Master Key : D8 FE 43 A0 2E AF 31 BE 52 AC CA ED BE 15 51 96 66 DE EC 25 78 49 2A 1E 72 EE 1D D1 6A B0 CF DB Transient Key : 02 D1 B6 10 D1 5C 94 8E 5D D2 81 AF 00 D4 75 29 7C 33 CB 12 33 88 CD 6E 10 BB 7B 39 D9 A0 D4 C1 30 32 7F 8B 46 56 8E B0 71 0B CB 6A 15 C0 ED 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 EAPOL HMAC : 73 2E CB C8 7B 0B 20 E3 A6 E6 19 32 FF 42 83 DE
Wiresharkで、[設定]>[Protocols]>[IEEE 802.11]の画面の「編集」から以下の設定を行い、通信の復号を行う。
Key type: wpa-pwd Key: THUNDERCATS
httpでフィルタリングすると、途中コマンドインジェクションと思われる通信がある。No.16208のパケットを含むHTTPストリームはこうなっている。
GET /setup.cgi?ping_ipaddr1=1&ping_ipaddr2=1&ping_ipaddr3=1&ping_ipaddr4=1&ping_size=60&ping_number=1&ping_interval=1000&ping_timeout=5000&start=Start+Test&todo=ping_test&this_file=Diagnostics.htm&next_file=Diagnostics.htm&c4_ping_ipaddr=1.1.1.1;/bin/ls HTTP/1.1 Host: 192.168.1.1 Cache-Control: max-age=0 Authorization: Basic YWRtaW46YWRtaW4= Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Referer: http://192.168.1.1/ Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.9 Connection: close HTTP/1.0 200 OK sh: cannot create 1: Unknown error 30 killall: pingmultilang: no process killed killall: 2: no process killed ARARPTable.htm AccessRes.htm Administration.htm AdvancedWSettings.htm AppGaming.htm Backup.htm DHCPClientTable.htm DMZ.htm DSL_status.htm Diagnostics.htm EditList.htm Factorydefaults.htm FirmwareUpgrade.htm HNAP1 LANG_BP.js LANG_DE.js LANG_EN.js LANG_FR.js LANG_GR.js LANG_IT.js LANG_NL.js LANG_PO.js LANG_RU.js LANG_TR.js Language.htm LocalNetwork.htm Log.htm Ping.htm PortRangeTriggering.htm QoS.htm Routercfg.cfg Routing_Table.htm Security.htm Setup.htm Setup_DDNS.htm Setup_MAC.htm Setup_routing.htm SingleForwarding.htm Status.htm Summary.htm UI_02.gif UI_03.gif UI_03_ar.gif UI_04.gif UI_04_ar.gif UI_05.gif UI_06.gif UI_07.gif UI_10.gif UI_11.gif UI_12.gif UI_13.gif UI_Cisco.gif UI_Linksys.gif VPNPassthrough.htm WClientMACList.htm WMACFilter.htm WNetwork.htm WPS.htm WSC.htm WSecurity.htm Wireless.htm Wireless_wifi.htm adsl_driver.htm ajax.js cgi_lang.bp cgi_lang.de cgi_lang.en cgi_lang.fr cgi_lang.gr cgi_lang.it cgi_lang.nl cgi_lang.po cgi_lang.ru cgi_lang.tr cisco_bp.css cisco_de.css cisco_en.css cisco_fr.css cisco_gr.css cisco_it.css cisco_nl.css cisco_po.css cisco_ru.css cisco_tr.css err_msg err_msg.bp err_msg.de err_msg.en err_msg.fr err_msg.gr err_msg.it err_msg.nl err_msg.po err_msg.ru err_msg.tr func.js fw_version.pat gen_page help help_bp.css help_bp.js help_de.css help_de.js help_en.css help_en.js help_fr.css help_fr.js help_gr.css help_gr.js help_it.css help_it.js help_nl.css help_nl.js help_po.css help_po.js help_ru.css help_ru.js help_tr.css help_tr.js index.htm lh_bg.gif lh_cisco.gif linux.js log_data.htm others_de.js others_en.js others_fr.js ppp_log reboot_guage.htm restore_config.cgi rh_bg.gif rh_cisco.gif set_vpn.js setup.cgi upgrade_flash.cgi upload_lang.cgi utility.js wps_mouseover.gif wps_nonselectable.gif wps_selectable.gif Content-type: text/html <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1252"> <meta name="description" content="LINKSYS WAG54G2 Wireless-G ADSL Home Gateway"> <META http-equiv="Pragma" CONTENT="no-cache"> <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache"> <script language="javascript" type="text/javascript" src="LANG_EN.js"></script> <script language="javascript" type="text/javascript" src="others_en.js"></script> <script language="javascript" type="text/javascript" src="func.js"></script> <script language="javascript" type="text/javascript" src="linux.js"></script> <script language="javascript" type="text/javascript"> strHtml='<title>'+vdiag+'</title>'; dw(rmTitleBr(strHtml)); strHtml='<LINK REL="stylesheet" TYPE="text/css" HREF="'+vcss_type+'">'; dw(strHtml); <!-- hide script from old browsers function checkData2(action) { var cf = document.forms[0]; var msg = ""; if( action != "save") if( blankIP(cf.ping_ipaddr1, cf.ping_ipaddr2, cf.ping_ipaddr3, cf.ping_ipaddr4) || badIP(cf.ping_ipaddr1, cf.ping_ipaddr2, cf.ping_ipaddr3, cf.ping_ipaddr4, 255) || isIPMulticast(cf.ping_ipaddr1.value+"."+cf.ping_ipaddr2.value+"."+cf.ping_ipaddr3.value+"."+cf.ping_ipaddr4.value)) msg+= msg_invalid_ip; msg+= checkInt(cf.ping_size, msg_ping_size, 60, 1514, true); msg+= checkInt(cf.ping_number, msg_ping_number, 1, 100, true); msg+= checkInt(cf.ping_interval, msg_ping_interval, 100, 9999, true); msg+= checkInt(cf.ping_timeout, msg_ping_timeout, 1000, 9999, true); if (msg.length > 1) { alert(msg); return false; } dataToHidden(cf); return true; } function doPing() { if (checkData2("ping")){ openDataSubWin('setup.cgi?next_file=Ping.htm', bigsub); return true; } else return false; //no submit } function checkData() { var cf = document.forms[0]; if (checkData2("save")){ cf.todo.value="save"; return true; } else return false; } //--> </script> </head> <body link="#FFFFFF" vlink="#FFFFFF" alink="#FFFFFF" onload="dataToVisible(document.forms[0])"> <form name="diagnostics" method="POST" action="setup.cgi"> <div align="center"> <table border="0" cellpadding="0" cellspacing="0" width="810" bgcolor="#2971b9"> <script language="javascript" type="text/javascript"> showHead('Wireless ADSL2+ Gateway','WAG54G2','V1.00.10',vadmin); </script> <script language="javascript" type="text/javascript"> showMenu(vadmin,admin_diag); </script> </table> <!-- data table--> <table border="0" cellpadding="0" cellspacing="0" width="810" bgcolor="#ffffff"> <tr> <td width="164" height="15" bgColor="#e7e7e7" colspan="2" align="right"><img border="0" src="UI_03.gif" width="8" height="15"></TD> <td width="646" height="14" colspan="2"><img border="0" src="UI_02.gif" width="646" height="15"></TD> </TR> <tr> <td width="164" height="24" colspan="2" class="bwhead"><script language="javascript" type="text/javascript"> dw(va_ping); </script></TD> <td width="454"> </TD> <td width="192" valign="bottom" bgcolor="#2971b9" background="rh_bg.gif"> <A href="setup.cgi?next_file=help/h_Diagnostics.htm" class="submenu" target="_blank"><script language="javascript" type="text/javascript"> dw(vhelp); </script></a></TD> </TR> <tr> <td width="156" bgColor="#e7e7e7" valign="top" class="boldhead"><script language="javascript" type="text/javascript"> dw(va_ping_para); </script></TD> <td width="8" background="UI_04.gif"> </TD> <td valign="top"> <table class="std"> <tr> <TD width=101 height=25><script language="javascript" type="text/javascript"> dw(va_ping_ip); </script></TD> <TD width=296 height=25> <input type="text" class="ipnum" maxlength="3" size="4" name="ping_ipaddr1" value=""> . <input type="text" class="ipnum" maxlength="3" size="4" name="ping_ipaddr2" value=""> . <input type="text" class="ipnum" maxlength="3" size="4" name="ping_ipaddr3" value=""> . <input type="text" class="ipnum" maxlength="3" size="4" name="ping_ipaddr4" value=""></TD> </TR> <tr> <TD width=101 height=25><script language="javascript" type="text/javascript"> dw(va_ping_size); </script></TD> <TD width=296 height=25> <input type="text" class="num" maxlength="4" size="4" name="ping_size" value="60"> <script language="javascript" type="text/javascript"> dw(vBytes); </script> </TD> </TR> <tr> <TD width=101 height=25><script language="javascript" type="text/javascript"> dw(va_ping_num); </script></TD> <TD width=296 height=25> <input type="text" class="num" maxlength="3" size="4" name="ping_number" value="1"> <script language="javascript" type="text/javascript"> dw(va_ping_num_value); </script> </TD> </TR> <tr> <TD width=101 height=25><script language="javascript" type="text/javascript"> dw(va_ping_interval); </script></TD> <TD width=296 height=25> <input type="text" class="num" maxlength="4" size="5" name="ping_interval" value="1000"> <script language="javascript" type="text/javascript"> dw(vmseconds); </script> </TD> </TR> <tr> <TD width=101 height=25><script language="javascript" type="text/javascript"> dw(va_ping_time); </script></TD> <TD width=296 height=25> <input type="text" class="num" maxlength="4" size="5" name="ping_timeout" value="5000"> <script language="javascript" type="text/javascript"> dw(vmseconds); </script> </TD> </TR> <tr> <TD width=101 height=25></TD> <TD width=296 height=25> <script language="javascript" type="text/javascript"> dw('<INPUT type="submit" name="start" value="'); dw(va_ping_start);dw('" onClick="return doPing();">');</script> </TD> </TR> <tr> <TD width=101 height=25><script language="javascript" type="text/javascript"> dw(va_ping_result); </script></TD> <TD width=296 height=25><B><script language="javascript" type="text/javascript"> dw(va_ping_result1); </script>1 <script language="javascript" type="text/javascript"> dw(va_ping_result2); </script>0 <script language="javascript" type="text/javascript"> dw(va_ping_result3); </script>0ms </b></TD> </TR> </table><br> </TD> <td valign="bottom" rowspan="99" bgcolor="#2971b9" background="rh_bg.gif"><img src="rh_cisco.gif" width="192" height="64" alt="Cisco Logo" border="0"></TD> </TR> <tr> <td colspan="2" bgcolor="#5b5b5b"> </TD> <td class="footer" bgcolor="#2971b9" height="33" align="right"> <script language="javascript" type="text/javascript"> showSave(); </script> <script language="javascript" type="text/javascript"> showCancel("Diagnostics.htm"); </script> </TD> </TR> </table> </div> <input type="hidden" name="todo" value="ping_test"> <input type="hidden" name="this_file" value="Diagnostics.htm"> <input type="hidden" name="next_file" value="Diagnostics.htm"> <input type="hidden" name="c4_ping_ipaddr" value=""> <input type="hidden" name="message" value=""> </form> </body> </html>
この後もコマンドが実行され、その結果を取得している。
/bin/whoami の実行結果は以下の通り。
sh: /bin/whoami: not found
/bin/ls /tmp の実行結果は以下の通り。
acl.conf cmd_agent dsl_status etc flag.txt gateway.xml gateways hnap_devready htpasswd lan_uptime mini_httpd nvram ping2file_result rc_cmd_file server_cmd_path sroute syslog.conf udhcpd.conf upgrade_flash.cgi var wlan_uptime wlist www
/bin/cat /tmp/flag.txt の実行結果は以下の通り。
ctf{1_s33_n0_g0d_up_h3r3_0th3r_th4n_m3}
ctf{1_s33_n0_g0d_up_h3r3_0th3r_th4n_m3}
Desert USB (Forensics 180)
添付のzipファイルはパスワードがかかっているので、クラックする。
$ fcrackzip -u -D -p dict/rockyou.txt USBimage.zip PASSWORD FOUND!!!!: pw == bingoboi $ unzip -P bingoboi USBimage.zip Archive: USBimage.zip creating: USBimage/ extracting: USBimage/encrypted_file001 inflating: USBimage/USBimage.zip $ 7z d USBimage.zip 7-Zip [64] 16.02 : Copyright (c) 1999-2016 Igor Pavlov : 2016-05-21 p7zip Version 16.02 (locale=ja_JP.UTF-8,Utf16=on,HugeFiles=on,64 bits,2 CPUs Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz (A0655),ASM,AES-NI) Open archive: USBimage.zip -- Path = USBimage.zip Type = zip Physical Size = 226063 Updating archive: USBimage.zip Items to compress: 0 Files read from disk: 0 Archive size: 22 bytes (1 KiB) Everything is Ok
USBimage.imgをAutopsyで開く。削除されたファイルの中にf0016568.elfというファイルがある。実行すると、flag.txtがencrypted_file002になり、暗号化される。いろいろ暗号化を試してみる。
空 -> jkslficoveaqwciutzrghbncmegwqlirt a -> \x0bkslficoveaqwciutzrghbncmegwqlirt z -> \x10kslficoveaqwciutzrghbncmegwqlirt xb -> \x12\x09slficoveaqwciutzrghbncmegwqlirt
>>> chr(ord('a') ^ 0x0b) 'j' >>> chr(ord('z') ^ 0x10) 'j' >>> chr(ord('x') ^ 0x12) 'j' >>> chr(ord('b') ^ 0x09) 'k'
暗号文と平文のXORがjkslficoveaqwciutzrghbncmegwqlirtになると推測できるので、XORでフラグを復号する。
#!/usr/bin/env python3 from Crypto.Util.strxor import strxor with open('encrypted_file001', 'rb') as f: ct = f.read() key = b'jkslficoveaqwciutzrghbncmegwqlirt' flag = strxor(key, ct).decode() print(flag)
ctf{you_could_have_just_paid_me}