PHP代码审计基础-初级篇
对于php代码审计我也是从0开始学的,对学习过程进行整理输出沉淀如有不足欢迎提出共勉。对学习能力有较高要求,整个系列主要是在工作中快速精通php代码审计,整个学习周期5天 ,建议花一天时间熟悉php语法。
我是直接phpstudy2019一键搭建小白首选
所谓工欲善其事必先利其器,找一款适合自己的php开发工具自行百度搭建,我用的是phpstrom .
初级篇主要讲
1. php历史版本漏洞。
2. 变量配置缺陷。
3. 函数缺陷。
4. 弱语言缺陷。
PHP配置漏洞
我们要熟知php各版本漏洞
Register_globals 全局变量注册开关
在该选项为on情况下,会直接把用户GET,POST等方式提交的参数注册成全局变量并初始化值为参数对应的值
Php小于4.2.3默认打开 5.3废弃 5.4移除
Allow_url_include 是否允许包含远程文件
Php 5.2 后默认设置off
Magic_quotes_gpc 魔术引号自动过滤
会自动在get post,cookie 变量对单引号,双引号,反斜杠,空字符的前面加反斜杠
缺陷不会过滤$_SERVER 变量
Php5.3后废弃,5.4移除 小于4.2.3 默认打开
Magic_quotes_runtime 魔术引号自动过滤
和上面一样 却是对从数据库取出的数据进行转义 防止二次注入 同样在5.4取消
Safe_mode 安全模式
在开启时做命令执行操作会提示执行命令失败,和一些敏感操作. 可以查看配置是否开启。
Open_basedir 可访问目录
默认web目录,查看配置是否出现全目录可访问情况
Disable_functions 禁用函数
禁用敏感函数如exec 可以通过dl()函数来绕过自定义php扩展方法实现命令执行,这个函数并不安全。
Display_errors 错误显示
生产环境关闭错误回显 display_errors=off
PHP漏洞函数
变量覆盖
extract()
该函数使用数组键名作为变量名,使用数组键值作为变量值。针对数组中的每个元素,将在当前符号表中创建对应的一个变量。条件:若有EXTR_SKIP则不行。
<?php
$a = "Original";
$my_array = array("a" => "Cat", "b" => "Dog", "c" => "Horse");
extract($my_array);
echo "$a = $a; $b = $b; $c = $c";
?> # 结果:$a = Cat; $b = Dog; $c = Horse
parse_str()
解析字符串并注册成变量
$b=1;
Parse_str('b=2');
Print_r($b);
# 结果: $b=2
import_request_variables()
将 GET/POST/Cookie 变量导入到全局作用域中,全局变量注册。在5.4之后被取消,只可在4-4.1.0和5-5.4.0可用。
//导入POST提交的变量值,前缀为post_
import_request_variable("p", "post_");
//导入GET和POST提交的变量值,前缀为gp_,GET优先于POST
import_request_variable("gp", "gp_");
//导入Cookie和GET的变量值,Cookie变量值优先于GET
import_request_variable("cg", "cg_");
$$变量覆盖
## 提交参数chs,则可覆盖变量"$chs"的值。$key为chs时,$$key就变成$chs
<?
$chs = '';
if($_POST && $charset != 'utf-8'){
$chs = new Chinese('UTF-8', $charset);
foreach($_POST as $key => $value){
$$key = $chs->Convert($value);
}
unset($chs);
}
绕过过滤的空白字符
" "%00" (ASCII 0 (0x00)),空字节符。
制表符
"\t" (ASCII 9 (0x09)),水平制表符。
空白字符:
"\n" (ASCII 10 (0x0A)),换行符。
"\v" "\x0b" (ASCII 11 (0x0B)),垂直制表符。
"\f" "%0c" 换页符
"\r" "%0d"(ASCII 13 (0x0D)),回车符。
空格:
" " "%20" (ASCII 32 (0x20)),普通空格符。
Trim 函数过滤 \t\n\r 缺少了\f(%0c)
从而绕过%0c过滤
截断
Iconv 异常字符截断问题
## 因iconv遇到异常字符就不转后面的内容了,所以可以截断。
## 这里chr(128)到chr(255)都可以截断。
$a='1'.char(130).'2';
echo iconv("UTF-8","gbk",$a); //将字符串的编码从UTF-8转到gbk
echo iconv('GB2312', 'UTF-8', $str); //将字符串的编码从GB2312转到UTF-8
eregi、ereg可用%00截断
功能:正则匹配过滤 条件:要求php<5.3.4可以把非法的数据放在%00后面进行绕过我们可以看一个ctf题就是考察了这个知识
## http://127.0.0.1/Php_Bug/05.php?password=1e9%00*-*
#GET方式提交password,然后用ereg()正则限制了password的形式,只能是一个或者多个数字、大小写字母,继续strlen()限制了长度小于8并且大小必须大于9999999,继续strpos()对password进行匹配,必须含有-,最终才输出flag
#因为ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用%00截断正则匹配。
#对于另一个难题可以使用科学计数法表示,计算器或电脑表达10的的幂是一般是e,也就是1.99714e13=19971400000000,所以构造 1e8 即 100000000 > 9999999,在加上-。于是乎构造password=1e8%00*-*,成功得到答案
<?php
if (isset ($_GET['password'])) {
if (ereg ("^[a-zA-Z0-9]+$",$_GET['password']) === FALSE)
{
echo '<p>You password must be alphanumeric</p>';
}
else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999)
{
if (strpos ($_GET['password'], '*-*') !== FALSE)
{
die('Flag: ' . $flag);
}
else
{
echo('<p>*-* have not been found</p>');
}
}
else
{
echo '<p>Invalid password</p>';
}
}
move_uploaded_file 用\0截断
5.4.x<= 5.4.39, 5.5.x<= 5.5.23, 5.6.x <= 5.6.7 原来在高版本(受影响版本中),PHP把长度比较的安全检查逻辑给去掉了,导致了漏洞的发生
获取文件名不一致%00 \0 导致截断后面的文件名
inclue用?截断
<?php $name=$_GET['name']; $filename=$name.'.php'; include $filename; ?>
当输入的文件名包含URL时,问号截断则会发生,并且这个利用方式不受PHP版本限制,原因是Web服务其会将问号看成一个请求参数。 测试POC: http://127.0.0.1/test/t1.php?name=http://127.0.0.1/test/secret.txt? 则会打开secret.txt中的文件内容。本测试用例在PHP5.5.38版本上测试通过。
系统长度截断
这种方式在PHP5.3以后的版本中都已经得到了修复。 win260个字符,linux下4*1024=4096字节
mysql长度截断
mysql内的默认字符长度为255,超过的就没了。 由于mysql的sql_mode设置为default的时候,即没有开启STRICT_ALL_TABLES选项时,MySQL对于插入超长的值只会提示warning
mysql中utf-8截断
insert into dvwa.test values (14,concat("admin",0xc1,"abc"))
写入为admin
弱类型比较
以下等式会成立
'' == 0 == false '123' == 123 'abc' == 0 '123a' == 123 '0x01' == 1 '0e123456789' == '0e987654321' [false] == [0] == [NULL] == [''] NULL == false == 0 true == 1
==、>、<的弱类型比较
这里用到了PHP弱类型的一个特性,当一个整形和一个其他类型行比较的时候,会先把其他类型转换成整型再比。
##方法1 ##$a["a1"]="1e8%00"; ##这里用%00绕过is_numeric,然后1e8可以比1336大,因此最后能$v1=1 ##方法2 ##$a["a1"]=["a"]; ##使用数组,可以,因为数组恒大于数字或字符串 ##方法3 ##$a["a1"]=1337a; ##1337a过is_numeric,又由>转成1337与1336比较 <?php is_numeric(@$a["a1"])?die("nope"):NULL; if(@$a["a1"]){ var_dump($a); ($a["a1"]>1336)?$v1=1:NULL; } var_dump($v1);
switch 弱类型
// 第一种:弱类型,1e==1
// $x1=1e
// 第二种:利用数组名字bypass
// $x1=1[]
// 传入后为string(3) "1[]",但在switch那里为1
if (isset($_GET['x1']))
{
$x1 = $_GET['x1'];
$x1=="1"?die("ha?"):NULL;
switch ($x1)
{
case 0:
case 1:
$a=1;
break;
}
}
md5比较(0e相等、数组为Null)
md5('240610708') //0e462097431906509019562988736854 md5('QNKCDZO') //0e830400451993494058024219903391 0e 纯数字这种格式的字符串在判断相等的时候会被认为是科学计数法的数字,先做字符串到数字的转换。 md5('240610708')==md5('QNKCDZO'); //True md5('240610708')===md5('QNKCDZO'); //False 这样的对应数值还有: var_dump(md5('240610708') == md5('QNKCDZO')); var_dump(md5('aabg7XSs') == md5('aabC9RqS')); var_dump(sha1('aaroZmOk') == sha1('aaK1STfY')); var_dump(sha1('aaO8zKZF') == sha1('aa3OFF9m')); var_dump('0010e2' == '1e3'); var_dump('0x1234Ab' == '1193131'); var_dump('0xABCdef' == ' 0xABCdef');
可以用于登录判断
240610708
技巧:找出在某一位置开始是0e的,并包含“XXX”的字符串
Md5 加密数组都是空 可以利用绕过
json传数据{“key”:0}
PHP将POST的数据全部保存为字符串形式,也就没有办法注入数字类型的数据了而JSON则不一样,JSON本身是一个完整的字符串,经过解析之后可能有字符串,数字,布尔等多种类型。
第一个application/x-www-form-urlencoded,是一般表单形式提交的content-type第二个,是包含文件的表单。第三,四个,分别是json和xml,一般是js当中上传的.
{“key”:”0″}
这是一个字符串0,我们需要让他为数字类型,用burp拦截,把两个双引号去掉,变成这样:
{“key”:0}
十六进制与十进制比较
== 两边的十六进制与十进制比较,是可以相等的。
至此已经介绍完了php常规函数缺陷,版本漏洞,语言特性导致的漏洞。需要熟记这些缺陷的利用方法。
PHP代码审计基础-初级篇的更多相关文章
- PHP代码审计基础-中级篇
初级篇更多是对那些已有的版本漏洞分析,存在安全问题的函数进行讲解,中级篇更多是针对用户输入对漏洞进行利用 中级篇更多是考虑由用户输入导致的安全问题. 预备工具首先要有php本地环境可以调试代码 总结就 ...
- PHP代码审计基础-高级篇
高级篇主要讲 1. 熟知各个开源框架历史版本漏洞. 2. 业务逻辑漏洞 3. 多线程引发的漏洞 4. 事务锁引发的漏洞 在高级篇审计中有很多漏洞正常情况下是不存在的只有在特殊情况下才有 PHP常用框架 ...
- PHP代码审计(初级篇)
一.常见的PHP框架 1.zendframwork: (ZF)是Zend公司推出的一套PHP开发框架 功能非常的强大,是一个重量级的框架,ZF 用 100%面向对象编码实现. ZF 的组件结构独一无二 ...
- NSIS安装制作基础教程[初级篇], 献给对NSIS有兴趣的初学者
NSIS安装制作基础教程[初级篇], 献给对NSIS有兴趣的初学者 作者: raindy 来源:http://bbs.hanzify.org/index.php?showtopic=30029 时间: ...
- 零基础学习hadoop到上手工作线路指导初级篇:hive及mapreduce(转)
零基础学习hadoop到上手工作线路指导初级篇:hive及mapreduce:http://www.aboutyun.com/thread-7567-1-1.html mapreduce学习目录总结 ...
- 零基础学习hadoop到上手工作线路指导(初级篇)
零基础学习hadoop,没有想象的那么困难,也没有想象的那么容易.在刚接触云计算,曾经想过培训,但是培训机构的选择就让我很纠结.所以索性就自己学习了.整个过程整理一下,给大家参考,欢迎讨论,共同学习. ...
- [学习线路] 零基础学习hadoop到上手工作线路指导(初级篇)
about云课程最新课程Cloudera课程 零基础学习hadoop,没有想象的那么困难,也没有想象的那么容易.在刚接触云计算,曾经想过培训,但是培训机构的选择就让我很纠结.所以索性就自己学习了. ...
- HTML5 Canvas(画布)实战编程初级篇:基本介绍和基础画布元素
欢迎大家阅读HTML5 Canvas(画布)实战编程初级篇系列,在这个系列中,我们将介绍最简单的HTML5画布编程.包括: 画布元素 绘制直线 绘制曲线 绘制路径 绘制图形 绘制颜色,渐变和图案 绘制 ...
- 零基础学习hadoop到上手工作线路指导初级篇:hive及mapreduce
此篇是在零基础学习hadoop到上手工作线路指导(初级篇)的基础,一个继续总结.五一假期:在写点内容,也算是总结.上面我们会了基本的编程,我们需要对hadoop有一个更深的理解:hadoop分为h ...
随机推荐
- charles 禁用缓存
本文参考:charles 禁用缓存 No caching Settings/无缓存工具的用法 弹窗面板上一句话概括了他的工作原理:通过修改请求和响应头来防止缓存; 无缓存工具 无缓存工具阻止客户端应用 ...
- 让我们一起学习如何使用AIDL,它其实并不难(Android)
前言 该篇文件讲述的是AIDL最基本的使用(创建.调用),关于对于AIDL更深的认识,在后续的随笔中,会持续与大家分享并探讨. 正文 AIDL的定义(什么是AIDL?) AIDL的应用场景(AIDL可 ...
- linux 堆栈查看
top -c 查看进程ID pstree PID 查看线程树 pstack PID 查看堆栈
- Salesforce学习之路-developer篇(一)利用VS Code结合Git开发Salesforce
Part 1: 从Git中克隆代码到本地 git clone https://github.com/git/git Part 2: 在VS Code中安装Salesforce和Git插件 在VS Co ...
- ASP.NET Core 3.0 : 二十五. TagHelper
什么是TagHelper?这是ASP.NET Core 中新出现的一个名词,它的作用是使服务器端代码可以在Razor 文件中参与创建和呈现HTML 元素.(ASP.NET Core 系列目录) 一.概 ...
- Collections.unmodifiableMap,Collections.unmodifiableList,Collections.unmodifiableSet作用及源码解析
在文章:Mybatis源码解析,一步一步从浅入深(五):mapper节点的解析中mybatis的源码中用到了Collections.unmodifiableList方法,其实还有unmodifiabl ...
- Kilani and the Game-吉拉尼的游戏 CodeForce#1105d 模拟 搜索
题目链接:Kilani and the Game 题目原文 Kilani is playing a game with his friends. This game can be represente ...
- 洗牌Shuffle'm Up POJ-3087 模拟
题目链接:Shuffle'm Up 题目大意 模拟纸牌的洗牌过程,已知两个牌数相等的牌堆.求解经过多少次洗牌的过程,使牌的顺序与目标顺序相同. 思路 直接模拟,主要是字符串的操作.问题是,如何判断出不 ...
- 原来python如此神奇
一.优缺点分析 1.缺点: ① 数学问题的生成中只考虑了消除乘除法加括号的无效情况(例如3*(4+5)或(6*5)/2这样的计算),但没有去掉加减法加括号的无效情况(例如(4+(7+8))或(3-(2 ...
- 初识PE文件结构
前言 目前网络上有关PE文件结构说明的文章太多了,自己的这篇文章只是单纯的记录自己对PE文件结构的学习.理解和总结. 基础概念 PE(Portable Executable:可移植的执行体)是Win3 ...