php常见缺陷函数

assert

这个函数是php的断言函数,用来判断一个表达式是否成立。返回true or false。

注:assert执行的字符串包含的php语句如果有多条,只会执行第一条。

该表达式会被当做php函数来执行,相当于eval()

MD5

PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。同时MD5不能处理数组。

md5()处理数组

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

PHP Hash漏洞(关于0e开头的md5值)

PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。

攻击者可以利用这一漏洞,通过输入一个经过哈希后以”0E”开头的字符串,即会被PHP解释为0,如果数据库中存在这种哈希值以”0E”开头的密码的话,他就可以以这个用户的身份登录进去,尽管并没有真正的密码。

即:如果md的值是以0e开头的,那么就与其他的0e开头的Md5值是相等的。

下列的字符串的MD5值都是0e开头的:

QNKCDZO

240610708

s878926199a

s155964671a

s214587387a

s214587387a

0e开头的md5和原值:

s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020

md5强绕过
(string)$_POST['a'] !== (string)$_POST['b'] && md5($_POST['a']) === md5($_POST['b'])

a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

$md5=md5($md5)

md5=0e215962017

strpos()

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

利用换行进行绕过(%0a)也可使用数组

Call_user_func()函数

函数将第一个参数作为调用的函数,其余参数为函数的传入参数,当两个值为可控内容时会产生命令执行漏洞。

in_array()

检查数组中是否存在某个值,第三个参数如果未设置为true(默认关闭),将存在弱类型绕过

搜索数组中是否存在指定的值。

creat_function()

适用范围:php4>=4.0.1,php5,php7
功能:
根据传递的参数创建匿名函数,并为其返回唯一名称
语法:

creat_function(string $agrs,string $code)
//string $agrs  声明的函数变量部分
//string $code  执行的方法代码部分

此函数在内部执行eval(),因此具有与eval()相同的安全问题。此外,它具有较差的性能和内存使用特性。

strcmp()

strcmp() 函数比较两个字符串。

该函数返回:

  • 0 - 如果两个字符串相等
  • <0 - 如果 string1 小于 string2
  • >0 - 如果 string1 大于 string2

php<5.3

如果传入非字符串类型(数组),将返回0,也就是判断为两边相等

filter_var(url过滤)

未对协议进行校验,可利用xxx://绕过

class_exists

当存在__autoload函数,会自动调用,如果类名可控,可造成危害,如果参数也可控,可利用内部函数进行攻击。

escapeshellarg与escapeshellcmd

escapeshellarg与escapeshellcmd配合使用会存在绕过

escapeshellarg — 把字符串转码为可以在 shell 命令里使用的参数

功能 :escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,shell 函数包含 exec(), system() 执行运算符(反引号)

定义 :string escapeshellarg ( string $arg )

escapeshellcmd — shell 元字符转义

功能:escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符之前进行转义。

反斜线(\)会在以下字符之前插入:

 &#;`|\?~<>^()[]{}$*, \x0A 和 \xFF\

* 仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 %! 字符都会被空格代替。

定义 :string escapeshellcmd ( string $command)

parse_str

parse_str的作用就是解析字符串并且注册成变量,它在注册变量之前不会验证当前变量是否存在,所以会直接覆盖掉当前作用域中原有的变量

parse_url

作用:parse_url — 解析 URL,返回其组成部分

filter_var ()

filter_var() 问题在于,我们在双引号中嵌套转义空格仍然能够通过检测。同时由于底层正则表达式的原因,我们通过重叠单引号和双引号,欺骗 filter_val() 使其认为我们仍然在双引号中,这样我们就可以绕过检测。
”aaa’aaa”@example.com

readfile

可利用 ../http/../../ 跳过目录(如检测关键字https是否存在)

截断

%00 遇到遇到函数过滤会成为\0

htmlentities

将字符转换为 HTML 转义字符

$_SERVER['REQUEST_URI']

获取的参数是不会将参数中的特殊符号进行转换

HPP

当给一个参数多个赋值时,由于现行的HTTP标准没有提及在遇到多个输入值给相同的参数赋值时应该怎样处理,而且不同的网站后端做出的处理方式是不同的,从而造成解析错误。

img

例如 id=1&id=2 只会接收第二个参数

preg_replace /e

preg_replace ($pattern , $replacement , $subject )

其中 $pattern为正则表达式

 $replacement为替换字符串
 $subject 为要搜索替换的目标字符串或字符串数组

pattern以/e结尾时replacement的值会被作为php函数执行。

例如执行 preg_replace (‘/test/e’ , “phpinfo();” , “test” )

“test”会被替换为phpinfo();并执行。

preg_replace 使用了 /e 模式,导致可以代码执行

参考文章

var_dump

var_dump( 0 == "a" ); true
var_dump( "0" == "a" ); false
因为php把字母开头的转化为整型时,转化为0, 前面数字后面字母的话就只取到第一个字母出现的位置之前(如intval(’'123abd45gf)结果为123)

basename()

返回路径中的文件名部分

basename会忽略一些奇怪的字符%80 ~ %ff

mt_scrand() mt_rand()

php伪随机数

先根据已知信息(残缺的伪随机数)生成php_mt_seed4.0所需要的参数,在使用php_mt_seed进行爆破获得seed种子,最终生成相同的完整伪随机数

str_replace

替换字符串中的一些字符(区分大小写)

无法迭代过滤,可双写进行绕过

addslashes()

返回在预定义字符之前添加反斜杠的字符串。

预定义字符是:

  • 单引号(')
  • 双引号(")
  • 反斜杠(\)
  • NULL

%bf%27本身不是一个有效的GBK字符,但经过 addslashes() 转换后变为0xbf5c27,前面的0xbf5c是个有效的GBK字符,所以%bf5c%27会被当作一个字符%bf5c和一个单引号来处理,结果漏洞就触发了

<?php            //data传入%bf%27
header("Content-Type:text/html;charset=gbk");
$data = $_GET['data'];
echo addslashes($data);
设置数据库字符为gbk导致宽字节注入
使用icon,mb_convert_encoding转换字符编码函数导致宽字节注入
url解码导致绕过addslashes
base64解码导致绕过addslashes
json编码导致绕过addslashes
没有使用引号保护字符串,直接无视addslashes
使用了stripslashes(去掉了\)
字符替换导致的绕过addslashes
参考
https://bbs.ichunqiu.com/thread-10899-1-1.html

extract()

从数组中将变量导入到当前的符号表。

在指定参数为EXTR_OVERWRITE或者没有指定函数可以导致变量覆盖

strip_tags

剥去字符串中的 HTML、XML 以及 PHP 的标签。

thinkphp原生代码中的upload()上传功能,会对上传的文件名执行该函数。
利用该方法可以进行前端绕过。
当php进行上传文件后缀验证,过滤.php时。
一般情况下诸如 1.php是无法上传上去的,但是此处可以通过 构造文件名为 1.<a>php绕过该验证。
文件上传后不满足.php绕过过滤,但是在tp的原生上传函数被调用是<a>被去除,文件就会被以php格式上传

Ereg()

Ereg函数用来对字符串中指定的字符进行匹配,返回True或False值。

当php<5.3.4,当字符串中存在%00的时候,ereg将不会匹配%00后面的字符串,从而进行绕过。

Sha1()

当sha1函数传入的数据为数组时会返回Null类型数据。

unset

unset( bar);用来销毁指定的变量,如果变量 bar 包含在请求参数中,可能出现销毁一些变量而实现程序逻辑绕过。

<?php  
// http://127.0.0.1/index.php?_CONFIG=123
$_CONFIG['extraSecure'] = true;

foreach(array('_GET','_POST') as $method) {
    foreach($$method as $key=>$value) {
      // $key == _CONFIG
      // $$key == $_CONFIG
      // 这个函数会把 $_CONFIG 变量销毁
      unset($$key);
    }
}

if ($_CONFIG['extraSecure'] == false) {
    echo 'flag {****}';
}
?>

Preg_match()

执行匹配正则表达式

当被匹配的数据为数组的时候回返回false值。

可利用PCRE回溯次数限制绕过

可利用换行绕过

php标签

php标签的写法
1.<?php ?>
常规写法

2.<?= ?>
注:

利用短标签写法可以绕过一些对php字符的过滤 <?= -> <? echo
Windows环境中短标签默认是打开的,Linux下 默认是关闭的。
控制参数: php支持短标签,需要我们把short_open_tag 设置为On.
3.<% %>
注:需要配置php.ini文件。在配置文件中找到asp_tags=off ,将off改为on。改动配置文件后需要重启apache。

4.<script language="php"> eval($_POST[2333]);</script>

类反射

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

回调函数

call_user_func()
call_user_func_array()
array_map()
array_filter()
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
下一篇