前言
比赛结束快一个月过去了,一直想做个ciscn的复盘,现在终于有时间整起来了,那就把初赛的web、misc做一个复盘吧,复盘平台NSSCTF。
misc
ez_usb
是一个usb的流量包,看特征是键盘的usb,直接进行提取是一个rar的压缩包,但是我们发现压缩包的格式是错误的,观察hex发现存在多余字符。
重新观察流量包,发现存在字符的版本有2.8.1和2.10.1两种,因此猜测需要分开导出。
2.8.1,导出后是一个压缩包:
2.10.1,导出后是压缩包密码:
解压压缩包即可得到flag。
everlasting_night
题目的附件只有一张图,给了提示这题存在LSB,且ARGB中存在LSB密码。那么使用stegslove查看颜色通道,最后在Alpha plane2中发现列隐藏数据。那么使用Data Extract进行提取:
找到了LSB的密码,使用cloacked-pixel解密,得到一个压缩包:
发现压缩包是加密的,再翻阅原图片的hex,发现最后有一串奇怪的字符串,经测试是MD5,使用somd5解密得到压缩包密码:
解压出来是一个data文件,直接导入进GIMP中,获得flag:
babydisk
附件里给了一个vmdk文件,直接扔进取证大师里,首先发现存在一个wav文件,导出后进行测试,发现存在deepsound加密,那么爆破密码:
得到密码feedback,使用deepsound解密得到key.txt:
1 | e575ac894c385a6f |
接下来回到取证大师,发现存在被删除文件,同样将该文件导出,这里测试发现应该使用VeraCrypt工具进行加载,密码就是这个key。加载后我们得到了一个名为spiral的文件,hex是一个zip文件。但是里面的图片损坏了,根据文件名螺旋的含义,估计是要将hex进行螺旋操作。我们网上找一个脚本:
1 | def function(n): |
得到一个新的压缩包,里面有一张图:
49个字符,7行7列,将第一行去掉后,进行从最右边开始上到下的螺旋操作,最后得到flag。
web
ezpop
thinkphp的框架,控制器中存在反序列化,再一看原来是学长挖的洞:
ThinkPHP6.0.12LTS反序列漏洞分析
那就比较简单了,有现成的poc:
1 | <?php |
最后在index.php/index/test
中传入即可获取flag。
online_crt
项目的组成是python+go,先看题目源码。
首先是python:
1 | import datetime |
可以看到python这部分有4个路由:
/
:主界面/getcrt
:生成一个证书/createlink
:调用c_rehash创建证书链接/proxy
:访问go语言的内网环境
接着是go:
1 | package main |
可以看到go语言里只有一个admin路由,功能是重命名证书。
这题设计的考点是CVE-2022-1292。我们首先访问/getcrt
路由,生成一个证书,返回证书路径:
1 | static/crt/b9f56972-a301-4ed0-8d46-fbdf41fb064e.crt |
接下来我们将这个证书的名称更改,使用老的证书把flag带到a.txt中去,payload:
1 | `echo "Y2F0IC9mbGFnID4gYS50eHQ=" | base64 -d | bash`.crt |
构造发包:
1 | GET /proxy HTTP/1.1 |
访问/creatlink
,将flag带入,最后访问/static/crt/a.txt
即可获取到flag。
ezpentest
首先进来是一个登录框,题目也给出了waf:
1 | <?php |
这里的payload和虎符杯的那题sql的payload类似:
1 | 0'||case'1'when`password`collate'utf8mb4_bin'like'{}%'then+9223372036854775807+1+''else'0'end||' |
- 利用like去正则匹配password这一列的数据,如果匹配到就返回9223372036854775807+1 这个表达式,而这个表示执行后会导致数据溢出,服务器会报500,否则就返回’0’,服务器会报error
- +’’是因为过滤了空白符号,所以用来连接起sql语句的,这里的数据溢出同样可以用18446744073709551615+1,这个18446744073709551615的值其实就是
0,也就是说这个payload其实就是0+1 - utf8mb4_bin是用来区分大小写的,因为like正则匹配是不区分大小写的
- case用来解决优先级问题
exp:
1 | import requests |
登陆后发现一堆被混淆的php指令,根据页面上的提示访问1Nd3x_Y0u_N3v3R_Kn0W.php:
1 | b; $checker = new ReflectionClass(get_class($b)); if(basename($checker->getFileName()) != 'SomeClass.php'){ if(isset($b->a)&&isset($b->b)){ ($b->a)($b->b.""); } } } } class B { public $a; public $b; public function __toString() { $this->a->see(); return "1"; } } class C { public $a; public $b; public function __toString() { $this->a->read(); return "lock lock read!"; } } class D { public $a; public $b; public function read() { $this->b->learn(); } } class E { public $a; public $b; public function __invoke() { $this->a = $this->b." Powered by PHP"; } public function __destruct(){ //eval($this->a); ??? 吓得我赶紧把后门注释了 //echo "???"; die($this->a); } } class F { public $a; public $b; public function __call($t1,$t2) { $s1 = $this->b; $s1(); } } ?> |
访问SomeClass.php
1 | <?php |
解密花指令
https://github.com/wenshui2008/phpjiami_decode
1 | <?php |
那这里就是利用pop反序列化了,入口点在class E,die方法中是字符串处理,让a为对象会触发__toString方法,在类A中,我们只需要令b为原生类,a参数和b参数都是可控的就可以rce了。
链子的触发点就是1Nd3x_Y0u_N3v3R_Kn0W.php文件,但是如果我们想把可以rce的文件包含进来,就要创建一个SomeClass类,而这里对some进行了过滤。
我们只需要让include $classname.”.php”将文件包含的同时直接进入那个destrust方法销毁,这里可以利用gc回收机制。我们将数组索引置为0,这样就会失去上一个对象的引用从而进入destrust。
exp:
1 | <?php |
传参即可得到flag。