3rsh1
/single dog/college student/ctfer
3rsh1's Blog

php代码审计2

php代码审计

空白符问题:

intval ( mixed var [, intbase = 10 ] ) : int

获取变量的整数值,默认为十进制。

如果参数是空的数组的话,返回0。若是非空的数组的话返回的值为1。

如果参数是字符串即字母一类的数字的话,返回为0,且若开头为数字,则会返回开头的数字。如果其中夹杂了一些特殊的符号的话如\n,只会返回数字。且在is_numeric()函数的判定下也是数字。

且最大值被操作系统限制:32位最大值位2^^31,有符号区别。64位则是2^^64。

对于此函数的一些参数,只有在第一个参数是字符串形式的时候才会生效。反之则有一些特殊的表示方法来代替第二个参数生效。

这里就直接做说明吧,第二参数只有在第一个参数是字符串形式的时候才会生效。反之不会生效,且在其是数字形式的时候我们可以用进制的形式来代理第二个参数的作用。0x1A可以表示十六进制,042可以表示八进制的34,貌似关于数学的一些符号只可以不在字符串的形式下使用。

<?php
echo intval(42);                      // 42
echo intval(4.2);                     // 4
echo intval('42');                    // 42
echo intval('+42');                   // 42
echo intval('-42');                   // -42
echo intval(042);                     // 34
echo intval('042');                   // 42
echo intval(1e10);                    // 1410065408
echo intval('1e10');                  // 1
echo intval(0x1A);                    // 26
echo intval(42000000);                // 42000000
echo intval(420000000000000000000);   // 0
echo intval('420000000000000000000'); // 2147483647
echo intval(42, 8);                   // 42
echo intval('42', 8);                 // 34
echo intval(array());                 // 0
echo intval(array('foo', 'bar'));     // 1
?>

因为1e10超范围了所以会显示奇怪的数。第二种利用方法:

<?php
echo intval("0x1a", 0), "\n"; // hex; prints "26"
echo intval("057", 0), "\n"; // octal; prints "47"
echo intval("42", 0), "\n"; // decimal; prints "42"
?>

还有一个小点就是浮点数精度的问题。

当数字长度超范围了的时候,超出的部分在弱类型比较的时候会被忽略。

var_dump(1.00000000000000000000000000005==1);//bool(true)

此函数忽略的特殊字符:

'\t' '\r' '\n' '\v' '\f' '%20'
is_numeric ( mixed $var ) : bool

判断变量是不是数字或者是数字字符串。

且在一些情况下会跳过一些字符如下可见:

https://www.3rsh1.cool/wp-content/uploads/2020/04/wp_editor_md_f0699680c36194f31dfd09e54c8ab69a.jpg

'\t' '\r' '\n' '\v' '\f' '%20'
trim ( string str [, stringcharacter_mask = " \t\n\r\0\x0B" ] ) : string

除去字符串首尾的空白字符或者其他字符。

若是第二个参数不指定的话,会自动除去默认的那几个字符。

t \n \r \v \0  

例题见:

E:\phpstudy_pro\WWW\trim_intval_demo

伪随机数相关问题:

mt_rand ( void ) : int
mt_rand ( int min , intmax ) : int

生成可指定最大值和最小值之间的随机数。如果没有指定最大值和最小值就返回0~mt_getrandmax()之间的随机数。

mt_srand ([ int $seed ] ) : void

用来给下一步产生的随机数播种。没有设定参数是,种子为随机数。

因为同一个种子生成的随机数是相同的,于是就可以根据生成的随机数来推测其种子。种瓜得瓜,种豆得豆嘛。

在window系统下rand()函数生成的随机数的范围要小的多(0 ~ 32767),但是mt_rand()函数生成的随机数的范围要大的多(0~2**31-1)。

涉及到php_mt_rand工具的使用,仅Linux版本:

./php_mt_rand [生成的第一个随机数]

运算符及其他函数:

$a= (1 and 1);//内部其实是一个且运算,即全真则真,有假则假。
$a= 1 and 1;    //先执行=,再执行and 
https://www.3rsh1.cool/wp-content/uploads/2020/04/wp_editor_md_eef93fd569b8a6722ff0408ece08c23f.jpg
parse_url ( string url [, intcomponent = -1 ] ) : mixed

解析一个url并返回其组成部分。返回值是一个关联数组,不会判断url的合法性,但是会尽量正确的解析url

第一个参数是要解析的url。第二个参数可以指定为: 指定 PHP_URL_SCHEMEPHP_URL_HOSTPHP_URL_PORTPHP_URL_USERPHP_URL_PASSPHP_URL_PATHPHP_URL_QUERYPHP_URL_FRAGMENT 的其中一个来获取 URL 中指定的部分的 string。 (除了指定为 PHP_URL_PORT 后,将返回一个 integer 的值)。

schema      //使用的协议
host        //主机名
port        //端口
user        //用户
pass        //密码
path        //路径
query       //?后面的传值
fragment    //#后面的内容
$url = 'http://username:password@hostname/path?arg=value#anchor';

var_dump(parse_url($url));

echo parse_url($url, PHP_URL_PATH);
<!--
    array(7) {
  ["scheme"]=>
  string(4) "http"
  ["host"]=>
  string(8) "hostname"
  ["user"]=>
  string(8) "username"
  ["pass"]=>
  string(8) "password"
  ["path"]=>
  string(5) "/path"
  ["query"]=>
  string(9) "arg=value"
  ["fragment"]=>
  string(6) "anchor"
}
-->

且需要注意的是,此函数允许对file:///协议带有三个/,但是仅限于此协议,否则会报错返回false。若是让返回不存在的内容会返回一个null。可在弱类型中使用。貌似判断路径的时候是根据\判断的,所以如果file协议后有三个/的话,后面到?之前的内容都会被当做路径。

在get取值的时候,. ,点和空格会被自动认为是下划线_

escapeshellarg和escapeshellcmd缺陷:

escapeshellarg ( string $arg ) : string

把字符串转码为可以在shell内使用的参数。

第一个参数为需要转码的字符串,返回值为转码之后的字符串。

echo escapeshellarg("'");   //  ''\'''
a="'a";
echo escapeshellarg(a);    //  ''\''a'
a="'a'";
echo escapeshellarg(a);    //  ''\''a'\'''
a="a'";
echo escapeshellarg(a);    //  'a'\'''

如果你尝试以下的话会发现奇奇怪怪的操作。对于单引号来说。

首先会有一个最外层的单引号,其次若转码的字符串内有单引号的话会先转义再套一个单引号。若是其他的字符为字母一类的则不需要加单引号了。

这里的单引号都是真实存在的,并不是用来表示数据类型才加上的。

escapeshellcmd ( string $command ) : string

shell元字符转义。感觉和上面的那个函数差不多。只不过范围更广一些。

对shell命令中可能欺骗命令执行的字符进行转义。

反斜线(\)会在以下字符之前插入: &#;`|*?~<>^()[]{}$*, \x0A 和\xFF。’和”仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 *%! 字符都会被空格代替。windows和unix也不一样的。

这个函数对单引号转义的时候是从开头开始的,寻找不成对的单引号进行转义。第一个函数是把所有的单引号都会给转义并且括起来。

$a="aaaaa'whoami";
echo escapeshellcmd(excapeshellarg($a));
//'aaaaa'\''whoami'
//'aaaaa'\\''whoami\'

如上图所示,whoami命令成功逃逸出来了。

正则表达式:

正则表达式一般都是贪婪匹配,即最大长度匹配,找到满足条件的最长的字符串。至于非贪婪匹配就是匹配到结果就好。

{m,n}   //m到n个
?       //一个或0个
*       //任意多个
+       //一个或多个

非贪婪:

aaab
.*?b

/ab.*?c/        //其实意思很显然易懂了,任意字符串匹配多个中的最小值。

一个奇奇怪怪的规则。因为是非贪婪,且b是限制条件。故b是有优先匹配权的。先用b来匹配。发现第一个字符是a,不满足。所以回溯一次把匹配权交给.*?发现满足条件,保留。再用b匹配,依次重复。只需回溯三次。

https://www.3rsh1.cool/wp-content/uploads/2020/04/wp_editor_md_921434d36d43b9c0c6b925ecd0d3b827.jpg

.*匹配了所有的字符。在第二个匹配中,会自后向前匹配[]中的内容。匹配时是一个一个匹配的,要回溯8次。

为了防止正则匹配引起的ddos攻击,php设置了最大回溯次数pcre.backtrack_limit

var_dump(ini_get('pcre.backtrack_limit'));

当回溯次数超过了最大回溯次数的时候某些函数就会返回false。由于match自身的逻辑会导致回溯次数增加3次,且是在最后的结果中。

disable_function绕过:

其实就是不能用的函数,在经过中间件解析之后。有些函数是不能使用的,来保护系统。这里的禁用其实指的是服务端的禁用。

scandir ( string directory [, intsorting_order [, resource $context ]] ) : array

第一个参数是目录,第二个参数是排序,默认按字母升序,若是此参数设为1,则是按字母降序。第三个参数不晓得。

var_dump(scandir('c:'));

会直接返回一个数组形式的文件列表,即此目录下有哪些文件和文件夹。

windows下com模块:

<?php
command=_GET['a'];
wsh=new com('WScript.shell');exec=wish->exec("cmd /c".command);
stdout=exec->stdout();
stroutout=stdout->readall();
echo $stroutout;
>?
pcntl_exec ( string path [, arrayargs [, array $envs ]] ) : void

在当前的进程空间中执行指定的程序。以给定的参数执行程序。

第一个参数是要执行的二进制程序的路径。

第二个参数 args是一个要传递给程序的参数的字符串数组。

第三个参数,键值对, envs是一个要传递给程序作为环境变量的字符串数组。这个数组是 key => value格式的,key代表要传递的环境变量的名称,value代表该环境变量值。

https://www.3rsh1.cool/wp-content/uploads/2020/04/wp_editor_md_aff3c3f614bceca63f5075f2d1535b8c.jpg

利用此函数反弹shell的一个操作。

https://www.3rsh1.cool/wp-content/uploads/2020/04/wp_editor_md_81cf7c977a9ab18d0d914cf95bbafe25.jpg

LD_preload是linux系统的一个环境变量,用于加载程序之前定义自己的动态链接库。因此我们可以利用此功能来使用自己的或是更好的函数。另一方面我们也可以向别人的程序中注入自己的程序,从而达到自己的目的。可以覆盖原有的数据库。

https://www.3rsh1.cool/wp-content/uploads/2020/04/wp_editor_md_7d9471263ede5282489752d8f26a2238.jpg

发表评论

textsms
account_circle
email

3rsh1's Blog

php代码审计2
php代码审计 空白符问题: intval ( mixed $var [, int $base = 10 ] ) : int 获取变量的整数值,默认为十进制。 如果参数是空的数组的话,返回0。若是非空的数组的话返回的值为1。 …
扫描二维码继续阅读
2020-04-22