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. Linux挂载U盘报错:mount: unknown filesystem type 'ntfs'

    原因:由于Linux上无法识别NTFS格式的分区的原因 解决方法:安装 ntfs-3g 1.下载:wget https://tuxera.com/opensource/ntfs-3g_ntfsprog ...

  2. ubuntu手动创建快捷方式

    新建document,重命名为XXX.desktop,打开文件 以sublime为例,填写 [Desktop Entry] Version=1.0 Type=Application Name=Subl ...

  3. Vue父子组件传值.sync

    <template> <div class="content"> <btn :btnName.sync='num' ></btn> ...

  4. zabbix 告警说明及触发cpu告警

    1. https://www.cnblogs.com/caonw/p/12766454.html 1.内存检测:Template OS Linux:vm.memory.size[available]. ...

  5. Python从零到壹丨详解图像平滑的两种非线性滤波方法

    摘要:本文将详细讲解两种非线性滤波方法中值滤波和双边滤波. 本文分享自华为云社区<[Python从零到壹] 五十六.图像增强及运算篇之图像平滑(中值滤波.双边滤波)>,作者: eastmo ...

  6. Spring源码分析之注册BeanDefinition

    测试代码 public class ContextApplication { public static void main(String[] args) { ClassPathXmlApplicat ...

  7. AC自动机模板题 HDU - 2222

    Keywords Search  HDU - 2222 贴个vj的链接https://vjudge.net/problem/HDU-2222 题意:T组数据,n个单词,再给你一个串,看有几个单词在这个 ...

  8. Flink基本概念及架构

    1.基本概念 无界和有界数据.任何类型的数据都可以形成一种事件流.信用卡交易.传感器测量.机器日志.网站或移动应用程序上的用户交互记录,所有这些数据都形成一种流.数据可以被作为 无界 或者 有界 流来 ...

  9. 如何单机部署多个 MySQL 8.0 实例 ?

    在服务器资源有限的情况下,可利用该方案快速搭建各类 mysql 架构方案.各 MySQL 实例共享一个 mysqld 主程序,但各实例数据目录是独立的,存放在不同的文件夹中:好了.废话不多说,直接上干 ...

  10. vite vue使用Markdown

    下载插件: npm i vite-plugin-md highlight.js github-markdown-css 配置插件: import Markdown from 'vite-plugin- ...