if(!$_GET['id'])
{
header('Location: hello.php?id=1');
exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
echo 'no no no no no no no';
return ;
}
$data = @file_get_contents($a,'r');
if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
$flag = "flag{***********}";
}
else
{
print "never never never give up !!!";
} ?>

2023年2月23日遇到的一个php代码审计的题目,这个题目的考察知识点非常多,写个wp记录一下。

if(!$_GET['id'])
{
header('Location: hello.php?id=1');
exit();
}

如果id=0或者没有设置id的值,则跳转id=1,程序退出

$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
echo 'no no no no no no no';
return ;
}

三个参数 id a b ,其中a参数的值不能有'.',如果有,则输出'no no no',并返回。

$data = @file_get_contents($a,'r');

file_get_contents从$a里读取数据,然后将数据给变量$data存储。

if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
$flag = "flag{***********}";
}
else
{
print "never never never give up !!!";
}

这个判断非常有意思,有很多矛盾的地方。首先data的值必须是"bugku is a nice plateform!",id必须为0(第一段代码就表示过id!=0),b的长度必须大于5,在正则匹配时,“111”和b的第一个字符拼接必须匹配到”1114“,但是b的第一个字符又不能是4。整个过程都非常矛盾,但是这正是考察php的知识点。

首先,data的值必须是"bugku is a nice plateform!",这个怎么办到?我们知道file_get_contents的参数是文件名,本质上是打开一个文件流,从流里读出文件内容。但我们并不知道哪个文件里有这个字符串信息,也没有上传接口,无法自己上传一个文件上去。这时,需要观察到本质,file_get_contents本质上是打开一个文件流,流!!!,重点是流。我们可以用php伪协议来完成。

php://input  // 读取post输入流

此时$a=php://input,然后用post传输"bugku is a nice plateform!",当file_get_contents($a)触发时,就是从Post的输入流里获取字符串“bugku is a nice plateform!”。

接着,id==0怎么绕过,毕竟一开始就判断过,id肯定不能是0,要是0,就退出程序了。但仔细看看,==在php中是弱类型比较,0bcde==0这个是成立的。为什么呢?因为数字之间比较时,非数字不参与比较。因此id=0a就可以绕过。

strlen($b) >5 没什么可说的,个数大于5就好。

eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4),按照普遍的思路来说

eregi("111".substr($b,0,1),"1114")   

eregi()匹配函数,匹配到则是True

"111".substr($b,0,1)  ->  拼接 “111”和  $b的第一个字符  (.是拼接字符串的意思)

比如$b=4321    那么  "111".substr($b,0,1) 就是1114

但是,绕过就是不走寻常路。令b=*12345。*号是通配符,匹配所有。因此,直接绕过!!!

整体构造如下:

随机推荐

  1. 118、商城业务---分布式事务---RabbitMQ延时队列定时关单模拟

    1.使用RabbitMq实现延时队列方法1 2.基于我们的业务我们使用下面这种方式实现延时队列 1.导入依赖 <dependency> <groupId>org.springf ...

  2. jquery input标签的禁用和启用disabled

    input框使用disabled后 input 元素既不可用,也不可点击.可以设置 disabled 属性,直到满足某些其他的条件为止(比如选择了一个复选框等等).然后,就需要通过 JavaScrip ...

  3. KVM虚拟机根分区磁盘扩容

    CentOS7.6, libvirt 4.5.0 , KVM虚拟机根分区扩容. 在宿主机执行0, 对LVM磁盘进行扩容 0. qemu-img resize 10.0.0.1_node1.qcow2 ...

  4. python内置函数map()

    map()函数 介绍 map()是python的一个内置函数,其作用是返回一个迭代器,该迭代器将function函数应用于可迭代对象的每个项,并产生结果. map函数的语法: map(function ...

  5. Android进度表示

    在连接上数据库之后,一切都变得简单了呢! 开心,很轻松地就能够将APP里面的相关内容写完啦! 尝试了好久的连接Mysql数据库,最后还是没有成功: 虽然Android studio里面自带的SQLit ...

  6. SpringBoot笔记--自动配置(高级内容)(中集)

    @Enable*注解 使用该注解,需要导入相应的依赖坐标,其中的groupId标签里面写入Bean的Java文件所在的包的路径下面 spring-enable-other 还需要在SpringBoot ...

  7. Spring--事务角色+事务属性

    事务管理员 发起事务方,在Spring中通常指代业务层开启事务的方法 也就是相当于这个: 事务协调员 加入事务方,在Spring中通常指代数据层方法,也可以是业务层方法 也就是相当于这个: 事务相关配 ...

  8. 当基础设施故障后,声网 SD-RTN™ 如何保障 RTE 服务的高可用性

    云计算的出现为企业的管理.业务开展.资源整合等带来了极大的便利性,也是数字化建设的核心基建之一,然而局部宕机或者大面积宕机事件对于云厂商来说却也无法避免,全球领先的计算平台也不例外.例如,美国东部时间 ...

  9. 【CS231n assignment 2022】Assignment 2 - Part 2,优化器,批归一化以及层归一化

    前言 博客主页:睡晚不猿序程 首发时间:2022.7.23 最近更新时间:2022.7.23 本文由 睡晚不猿序程 原创 作者是蒻蒟本蒟,如果文章里有任何错误或者表述不清,请 tt 我,万分感谢!or ...

  10. 如果您喜欢我的博客可以进行RSS订阅

    如果喜欢我的博客,你也可以订阅我的博客 http://www.cnblogs.com/yhm138/rss 有时间的话我会写一篇菜鸟玩转RSS的介绍,或者你看这篇推送 2020-12-15填坑 我理解 ...