PHP代码审计 -- 以ctfshow php特性 93-104为例

web93

(intval()特性)

PHP代码审计 -- 以ctfshow php特性 93-104为例_第1张图片

PHP代码审计 -- 以ctfshow php特性 93-104为例_第2张图片

来看源码 

首先是弱比较(不能等于4476)然后是正则比较不能出现大小写的字母最后就是等于4476;

PHP代码审计 -- 以ctfshow php特性 93-104为例_第3张图片

 过滤了字母,所以不能用16进制,可以用8进制或者小数绕过

/?num=010574 或 /?num=4476.1

PHP代码审计 -- 以ctfshow php特性 93-104为例_第4张图片

web94

(intval()特性)

来看源码 

函数分析:

strpos()函数返回匹配的字符位置,默认从0开始

strpos(string,find,start)
string     必需。规定要搜索的字符串。
find     必需。规定要查找的字符串。
start     可选。规定在何处开始搜索。

 if(!strpos($num, "0")){ die("no no no!"); }

如果不出现0的话会返回-1,第一个为0的话会返回0,都会die

PHP代码审计 -- 以ctfshow php特性 93-104为例_第5张图片

过滤了0-9,意味着不能再用进制过滤了,发现第一个判断句if中的“4476”是个字符,而在intval函数里,4476.0会被转换成int,所以会相等.那么我们就使用num=4476.0来绕过

PHP代码审计 -- 以ctfshow php特性 93-104为例_第6张图片

web95

(intval()特性)

来看源码 

发现点也被过滤了,那么我们就不能使用小数绕过

PHP代码审计 -- 以ctfshow php特性 93-104为例_第7张图片

根据intval()的特性可以通过8进制绕过但是前面必须多加一个字节,几个payload:

?num= 010574

?num=%0a010574

?num=%20010574

?num=+010574 

PHP代码审计 -- 以ctfshow php特性 93-104为例_第8张图片

web96

(路径问题)

这题很简单,highlight_file里面表示的是文件路径,参数不能等于flag.php

PHP代码审计 -- 以ctfshow php特性 93-104为例_第9张图片

 可以用./表示当前目录,或者用绝对路径,或者使用php伪协议

u=./flag.php     相对路径

u=/var/www/html/flag.php   绝对路径,猜

u=php://filter/resource=flag.php   php伪协议

PHP代码审计 -- 以ctfshow php特性 93-104为例_第10张图片

web97

(md5强碰撞)

看源码要求POST提交的a和b的值不相等,但是md5加密后的值相等

PHP代码审计 -- 以ctfshow php特性 93-104为例_第11张图片

 三个=号,是属于强碰撞

md5()函数无法处理数组,如果传入的值为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是强相等的

使用POST提交  a[]=1&b[]=2

PHP代码审计 -- 以ctfshow php特性 93-104为例_第12张图片

web98

(变量覆盖)

&是引用符号,意思是:不同的名字访问同一个变量内容。php的引用是在变量或者函数、对象等前面加上&符号,PHP 的引用允许你用两个变量来指向同一个内容

三元运算符
条件表达式?表达式1:表达式2
条件表达式为true时调用表达式1,为false时调用表达式2

PHP代码审计 -- 以ctfshow php特性 93-104为例_第13张图片

 $_GET=&$_POST就相当于$_GET指向了$_POST的地址,如果$_GET改变了$_POST也要跟着变,同理,$_POST变了$_GET也会跟着变。关键的就是HTTP_FALG=flag,这样才就能回显flag了

第一句存在变量覆盖的效果,所以GET请求不管给什么东西都会被POST请求覆盖掉

直接GET型提交flag会被flag的COOKIESERVER覆盖,但最后需要GET型提交HTTP_FLAG=flag

GET传参:/?    //随便传,不能没有
POST传参:HTTP_FLAG=flag  

PHP代码审计 -- 以ctfshow php特性 93-104为例_第14张图片

web99

(in_array()和file_put_contents())

array_push() 函数向第一个参数的数组尾部添加一个或多个元素

rand() 函数返回随机整数

isset() 函数用于检测变量是否已设置并且非 NULL

in_array()函数搜索数组中是否存在指定的值

file_put_contents() 函数把一个字符串写入文件中。如果文件不存在,将创建一个文件;如果成功,该函数将返回写入文件中的字符数。如果失败,则返回 False。

重点是array_push()将随机数(必定有1)添加到数组$allow

in_array()函数搜索数组中是否存在指定的值

PHP代码审计 -- 以ctfshow php特性 93-104为例_第15张图片

$array数组里面的是int,我们传入的是字符串,在php字符串和int比较,字符串会被转换成int,因为是弱类型转换,所以 字符串中数字后面的字符串会被忽略

由于in_array没有设置type,我们可以输入1.php,转换之后也就是1,肯定是in_array的,满足条件

利用in_array()的弱比较类型,构造?n=1.php

同时POST:content=

访问1.php即可 

PHP代码审计 -- 以ctfshow php特性 93-104为例_第16张图片

或者?n=1.php content=

访问1.php一步一步来即可

web100

(is_numeric())

is_numeric()用来检测变量是否为数字或数字字符串。如果指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE,注意浮点型返回空值,即 FALSE

$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);

因为是用and连接,所以只要一个为true,v0就为true。如果用&&连接,必须都为true,v0才为true

所以只需要v1为数字就行

PHP代码审计 -- 以ctfshow php特性 93-104为例_第17张图片

法一: 

看过滤$v2不能有;但是$v3要有;

eval("$v2('ctfshow')$v3");字符串拼接,然后用eval执行

构造?v1=1&v2=var_dump($ctfshow)&v3=;

 PHP代码审计 -- 以ctfshow php特性 93-104为例_第18张图片

仔细看看,里面有个0x2d,对应ASCII码就是-,我们替换一下成功提交flag

法二:

eval()执行里有一段('ctfshow'),可以用/**/注释掉,或者--注释

所以注释掉v3也可以?v1=1&v2=var_dump($ctfshow)/*&v3=*/;

var_dump()用于判断一个变量的类型与长度,并输出变量的数值

PHP代码审计 -- 以ctfshow php特性 93-104为例_第19张图片

web101

(类反射)

PHP反射机制 - 知乎 (zhihu.com)

在web100的基础上,增加了更多的过滤

PHP代码审计 -- 以ctfshow php特性 93-104为例_第20张图片

 

这里我们用到了类反射

PHP Reflection API是PHP5才有的新功能,它是用来导出或提取出关于类、方法、属性、参数等的详细信息,包括注释
$class = new ReflectionClass('Person'); // 建立 Person这个类的反射类
$instance = $class->newInstanceArgs($args);// 相当于实例化Person 类

利用ReflectionClass建立ctfshow类的反射类,new ReflectionClass($class)获得class的反射对象(包含了元数据信息)。反射返回的对象是class的元数据对象(包含class的所有属性/方法的元数据信息)。

payload:?v1=1&v2=echo new Reflectionclass&v3=;

PHP代码审计 -- 以ctfshow php特性 93-104为例_第21张图片

 

web102

(hex2bin)

call_user_func() — 把第一个参数作为回调函数调用

也就是说v1是被调用的回调参数,s是回调参数的参数

file_put_contents()函数把一个字符串写入文件中,如果成功,该函数将返回写入文件中的字符数。如果失败,则返回 False

分析源码,v2必须是数字;call_user_func($method,$a)调用的参数是,v2第3位及之后的数字。那么我们需要在后面的数字着手,必须满足数字,科学计数e是唯一可以在is_numeric中不会影响判断数字的字符,所以可选字符只有0-9和e。

利用进制转换,hex2bin可以把十六进制值转换为 ASCII 字符。我们要写入这串十六进制

file_put_content();可以写入文件,根据已有内容,不能直接写php语句,因为<不能用,那么就需要编码,以实现写入php语句。所以v3的内容是利用伪协议写入,编码形式采取base64。

PHP代码审计 -- 以ctfshow php特性 93-104为例_第22张图片

是echo() 的快捷用法,它会把结果输出出来 

直接用cat *把当前目录下的文件都输出

所以最后的思路是v1是hex2bin;v2里先加上两个随意的数字,如11,然后加上php语句的base64转16进制的内容;v3是php伪协议语句。

$a='

GET:
v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64- decode/resource=1.php
POST:
v1=hex2bin
#访问1.php后查看源代码获得flag 

PHP代码审计 -- 以ctfshow php特性 93-104为例_第23张图片PHP代码审计 -- 以ctfshow php特性 93-104为例_第24张图片

 

web103

(hex2bin)

增加了preg_match(),我们上个题用的是短标签,而且是用*全部输出,并不影响,所以和上题的payload一样

PHP代码审计 -- 以ctfshow php特性 93-104为例_第25张图片

 

web104

(sha1)

来看源码,v1和v2的sha1值要相等,并且没有判断v1和v2

PHP代码审计 -- 以ctfshow php特性 93-104为例_第26张图片

 sha1与md5类似。都无法处理数组,所以可以用数组绕过

get : v2[]=0 post: v1[]=1

 PHP代码审计 -- 以ctfshow php特性 93-104为例_第27张图片

 也可以找加密后0e开头的即可。

aaK1STfY ==>0e76658526655756207688271159624026011393

aaO8zKZF ==>0e89257456677279068558073954252716165668

PHP代码审计 -- 以ctfshow php特性 93-104为例_第28张图片

 并且这里没有判断v1和v2,两个参数输入同样的值也是可以的。 直接构造POST:v1=a GET:v2=a

PHP代码审计 -- 以ctfshow php特性 93-104为例_第29张图片

你可能感兴趣的:(作业,刷题笔记,php,开发语言,安全,经验分享,web安全)