php代码审计前奏之ctfshow之php特性(php代码规范)

作者:啊不
围观群众:25
更新于
php代码审计前奏之ctfshow之php特性(php代码规范)

想搞好代码审计,必须要搞懂其中一些危险函数危险应用,以及过滤不足,

故以 CTF 来练习。

web89~数组绕过preg_match

  • preg_match — 执行匹配正则表达式

返回值:

**preg_match()返回 的匹配次数。 它的值将是0次(不匹配)或1次,因为preg_match()在第一次匹配后 将会停止搜索。preg_match_all()不同于此,它会一直搜索直到到达结尾。 如果发生错误preg_match()**返回 。

数组绕过

当匹配数组是返回false绕过。

web90~intval函数

  • intval()函数用于获取变量的整数值。
    intval()函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。

参数说明:

  • $var:要转换成 integer 的数量值。

  • $base:转化所使用的进制。

如果 base 是 0,通过检测 var 的格式来决定使用的进制:

php代码审计前奏之ctfshow之php特性(php代码规范)
  • 如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,

  • 如果字符串以 "0" 开始,使用 8 进制(octal);否则,

    php代码审计前奏之ctfshow之php特性(php代码规范)
  • 将使用 10 进制 (decimal)。

传参一个数既要使其不强等于,又要使得函数处理后的结果强等于,结合上述函数解释

构造

web91~/m之%0a绕过

题目要求,传参 cmd.

但是第一个正则匹配要求多行匹配,但是另一个要求有去掉修饰符要求不匹配.那么就应该能想到是截断。

第一个匹配多行,第二个只匹配单行,那么我们可以构造进行匹配,当多行匹配的时候前后都是,

还可以这里有有两个条件,第一个需要是php,第二个又不可以php,不过有个差距就是m模式,/m代表匹配多行数据,第一个if有匹配到第二行的php,而第二个if匹配不到为假。

CVE-2017-15715

https://blog.csdn.net/qq_46091464/article/details/108278486

web92~intval八十六进制科学计数法绕过

同样考点是,但这道题不同于web90,而是弱比较,所以说等肯定不行的。

这里用到十六进制或者八进制

https://www.runoob.com/php/php-intval-function.html

也可以科学计数法,在第一个if会计数比较,在函数中会被看做字符串。

web93~intval八进制绕过

过滤了字母,但我们可以使用八进制

web94~八进制,小数点绕过

  • 查找 "php" 在字符串中第一次出现的位置:

  • strpos() 函数对大小写敏感。

  • 返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。

比上一关增加条件,strpos函数限制了传参第一位不能为0,如果为0,就die.

但是如果找不到的话又会die.

仔细观察这里时强等于。

我们可以在八进制前加一个空格

或者用小数点

或者再加个 +

web95~空格加八进制绕intval

又增加过滤了

构造

也可以

web96~绝对路径相对路径

可以看到不能直接等于,

但是我们可以构造路劲让其显示

web97~md5数组绕过

这里是强比较。

弱比较的话可以百度有好多md5加密后是0e开头的,弱比较 0=0

强比较

如果传入函数的不是字符串而是数组,那么就会返回, null=null绕过。

构造

还有md5强碰撞

https://blog.csdn.net/EC_Carrot/article/details/109525162

https://www.cnblogs.com/kuaile1314/p/11968108.html

web98~三米运算地址引用

三米符运算,和传址(引用)

那么看最后要求那么我们就可以直接随意get传参一个,然后post传参即可获得flag.

看看wp:

web99~in_array()漏洞

意为当没有设置第三个函数时,比较是会自动转换数据类型,也就是弱比较。

那么我们传入就相当于若等于.

构造

web100~运算符优先级,反射类

这里有问题,又学费了。

php 的运算符竟然比 高。

https://www.jb51.net/article/42425.htm

&& > || >=> and > or

https://www.php.net/manual/zh/language.operators.precedence.php

所以这时候就很清晰明了了。

只需要传入的 值是数字。必须有。

构造

反射类: https://www.php.net/manual/zh/class.reflectionclass.php

反射类用法:

https://blog.csdn.net/miuzzx/article/details/109168454

解出来

有点小坑,仔细看才发现有好多

web101~反射类

跟上道题差不多,过滤的严了一些。过滤掉了和反引号,单引号,括号。

只能用反射类了。

构造

同样结果注意flag格式

web102~hex2bin,base64编码后都为数字

这里要求是数字,并且截取第三位后的字符作为的第二个参数。

作为 的第一个参数。

作为 的文件名。

返回结果作为的第二参数。

is_numeric 函数是又漏洞的,再 php5 版本下是可以识别十六进制的。也就是说,如果传入也是可以识别为数字的。

但此题是 php7 环境。不可以。

要让v2均为数字,首先我们考虑写入1.php时,利用伪协议写入

关键就是什么代码base64编码后再转为十六进制为全数字

同时因为经过substr处理,所以v2前面还要补两位数字。

构造

或者

web103~hex2bin

相比上关过滤了.

用上关payload也可以打通。

web104~sha1弱相等

  • sha1 — 计算字符串的 sha1 散列值. 返回 sha1 散列值字符串。

sha1()函数无法处理数组类型,将报错并返回false,

所以构造

这里没有判断两值是否相等,所以也可以传入两个相等的数。

还有几个弱比较相等的字符串

web105~$$变量覆盖

变量覆盖。

代码审计,直接传入

这里把和 都覆盖成了 ,所以不管die 哪个,都会输出flag.

web106~sha1弱比较

数组绕过。

还有

web107~MD5弱比较

MD5弱类型比较。

  • parse_str() 函数把查询字符串解析到变量中。

注释:如果未设置 array 参数,由该函数设置的变量将覆盖已存在的同名变量。

注释:php.ini 文件中的 magic_quotes_gpc 设置影响该函数的输出。如果已启用,那么在 parse_str() 解析之前,变量会被 addslashes() 转换。

  1. 数组绕过
    md5加密数组会返回NULL,$v2['flag'] 也是NULL。

  1. 弱比较绕过

    php代码审计前奏之ctfshow之php特性(php代码规范)

web108~ereg %00截断漏洞

  • ereg — 正则表达式匹配

  • ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。 ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配

所以构造

当通过和的时候,为 877

web109~反射类,异常处理

payload:

web110~FilesystemIterator类读取文件

考察点:FilesystemIterator类的使用(作用就是获取当前目录文件)

payload:

http://phpff.com/filesystemiterator

web111~全局变量GLOBALS引用

php变量地址引用。可以利用全局变量来进行赋值给ctfshow这个变量

payload:

web112~php伪协议

  • is_file() 函数检查指定的文件名是否是正常的文件。如果文件存在且为正常的文件,则返回 true。

苦苦不知道flag在哪里,原来就在falg.php

payload:

web113~/proc/self/root

压缩过滤器绕过

在linux中/proc/self/root是指向根目录的,也就是如果在命令行中输入ls /proc/self/root,其实显示的内容是根目录下的内容
多次重复后绕过is_file.。

php的一个小 trick. 具体看这里

web114~filter

过滤了,上面的非预期也就不能用了。

但 没过滤。

payload :

web115~fuzz绕is_numeric,trim

trim函数的绕过+is_numeric绕过

测试代码:

输出了

再来看看 trim+is_numeric

输出

而 、、 被过滤。所以构造

web123~php变量命名,_SERVER['argv'];

php变量命名是不允许使用点号的,所以就很难搞。

本地暴破一下:

1.php

python脚本:

成功爆破出。

测试一下:

接下来看看的作用。

2、web网页模式下

设置register_argc_argv=On(默认是Off),重启服务,$_SERVER[‘argv’]才会有效果

这时候的$_SERVER[‘argv’][0]=$_SERVER[‘QUERY_STRING’]

$argv,$argc在web模式下不适用

因为我们是在网页模式下运行的,所以也就是
这时候我们只要通过 将$flag赋值flag_give_me就可以了。

我们传值(记得有分号,后边需要eval执行),然后此时 ,我们让 中的 $c 变为即可成功使 fl0g 变量成功赋值。

paylaod:

非预期解:

这个题本来的的预期解是:

但是按理说这样也可以的呀:

https://blog.csdn.net/miuzzx/article/details/109181768

应该又是环境问题。

web125~argv,parse_str

被过滤了其他方法,

payload

还有:

web126~argv,assert

payload:

web127~fuzz代替_

fuzz:

1.php

python:

得到

这里其他被ban了,只能使用 空格

web128~gettext拓展,get_defined_vars获取已定义变量

gettext拓展的使用.

https://www.cnblogs.com/lost-1987/articles/3309693.html

https://www.php.net/manual/zh/book.gettext.php

所以 返回的就是phpinfo

get_defined_vars — 返回由所有已定义变量所组成的数组 这样可以获得 $flag

因为我们要得到的flag就在flag.php中,所以可以直接用get_defined_vars

payload:

web129~stripos包含特定绕过

  • stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)。

PHP 版本: 5+

目录穿越:

还可以php伪协议

payload:

还可以远程文件包含。在自己服务器上写一个命名 .

web130~正则

直接 post ,正则匹配到 与匹配规则不符 ,同时 在第0 匹配, 而0===FALSE为假绕过。

web131(修复130)~正则最大回溯

利用正则最大回溯次数绕过

https://www.laruence.com/2010/06/08/1579.html

在php中正则表达式进行匹配有一定的限制,超过限制直接返回false

写个py脚本:

得到Falg

web132~运算符 && ||

打开是一个网站。

直接扫目录,扫到

if绕过

payload

web133~无回显rce,curl

分析一下代码发现仿佛是只能读取前面6个字符去执行命令,禁止了命令执行的函数,并且没有写入权限。可能利用就比较可能
但是,如果我们传递的参数就是本身,会不会发生变量覆盖?
那我们来一个简单的测试,

然后就是利用curl去带出flag.php

payload:

php代码审计前奏之ctfshow之php特性(php代码规范)

执行payload

之后就会在burp上收到 flag.php的内容,

其他方法:

利用网站 http://requestbin.net

参照:

https://blog.csdn.net/qq_46091464/article/details/109095382

web134~POST数组的覆盖

  • parse_str() 函数把查询字符串解析到变量中。

  • extract() 函数从数组中将变量导入到当前的符号表。

POST数组的覆盖

可以看到以GET 传参相当于post传参 a 效果。

构造paylaod

web135~rce nl,cp,mv

在133的基础上增加了curl和其他一些字符的过滤,

可以写文件。

也可以

http://dnslog.cn/

申请一个域名。但是这种方法不行,可能域名前缀不行吧。

web136~linux tee命令

把重定向符、mv、cp禁用了。

linux中命令·。

tee命令主要被用来向standout(标准输出流,通常是命令执行窗口)输出的同时也将内容输出到文件

构造payload:

web137~class:fun()

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

  • 第一个参数 是被调用的回调函数,其余参数是回调函数的参数。

php中 ->与:: 调用类中的成员的区别
->用于动态语境处理某个类的某个实例
::可以调用一个静态的、不依赖于其他初始化的类方法.

也就是说双冒号可以不用实例化类就可以直接调用类中的方法

直接调用函数

web138~call_user_func数组回调

这下子把 冒号给禁用了。

用call_user_func()来调用一个类里面的方法

payload:

php代码审计前奏之ctfshow之php特性(php代码规范)

web139

试了,没有写权限没所以不能写入文件了。

也没有回显。

师傅们的脚本。

猜测文件名:

得到flag所在文件 f149_15_h3r3,接着盲注文件内容

web140~弱比较函数调用

弱比较,所以只需要将 $code 等于字母或者 0 即可。

we141~取反-执行php命令

作用是匹配非数字字母下划线的字符.

php中 可以执行phpinfo()命令的。

取反构造

payload:

取反脚本

web142

直接

web143~异或 *

过滤了加减我们还可以用乘除,过滤了~我们可以用异或构造命令。

异或脚本:

payload:

web144~异或

  • \W 匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]'。

直接构造 paylaod:

web145~三米运算符

取反绕过。

取反脚本:

构造

但是不知道如何使它执行,那么fuzz一波。

结果

也就是

payload:

web146~等号,位运算

接着把 三目运算过滤了。

利用绕过。

payload:

web147

非特殊说明,本文版权归 科普观察网 所有,转载请注明出处.

本文分类: 美食

本文标题: php代码审计前奏之ctfshow之php特性(php代码规范)

本文网址: http://jskepuxin.com/meishi/5562.html

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

网站分类
搜索
最新留言
    标签列表