php代码审计是什么意思,php代码审计基础篇
文章最后更新时间为:2019年01月20日 22:08:44
0. 前言
打算寒假学习代码审计和pwn,但是pwn真的是对人太不友好了,在这靠抖取暖的寒冬里大概看完了尹毅的《代码审计 企业级web代码安全架构》,虽然书有好几年了,但是里面的漏洞挖掘思路还是很友好的。写的一气呵成,看的也很过瘾,这里记录一波,打好基础。
本篇为基础篇,介绍常见的SQL注入,XSS,CSRF、文件操作、代码执行、命令执行等漏洞的挖掘思路和防范策略。很多细节没写,可以写,但没必要。
1. SQL注入
sql注入最为常见,一般出现在登陆界面、表单界面、http中的GET参数,x-forward-for等,另外在订单系统还容易发生二次注入,审计时需要关注这几个地方。
1.1 普通注入
对于与数据库交互的数据没有任何防护,这种低级错误比较少见,普通注入有int型和string型,对于这些我们只需要查找一些关键函数即可,比如mysql_connect、mysql_query、select from、mysql_fetch_row、update、insert、delete等,我们做白盒审计的时候,只需要查找这些关键词即可定向挖掘SQL注入漏洞。
1.2 宽字节注入
在使用PHP连接数据库的时候,当设置set character_set_client=gbk时会导致一个编码转换的注入问题,也就是宽字节注入。
当存在宽字节注入时,注入参数里的%df%27会将过滤的\(%5c)吃掉。举个例子,当/1.php?id=1存在注入,我们输入/1.php?id=1' and 1=1#,MYSQL执行的是select * from user where id = '1\' and 1 = 1#'
显然单引号没有闭合,但是当我们提交1.php?id=1%df' and 1 = 1#时,这时MYSQL运行的是select * from user where id = '1運' and 1 = 1#'
单引号闭合,注入成功,造成这种结果的原因是客户端编码为GBK,MYSQL服务器对查询语句进行转码的过程中,将%df%5c变成了一个汉字“運”,造成了引号的逃逸。
通常php设置编码的方式不是set character_set_client=gbk而是SET NAMES 'gbk',
SET NAMES 'gbk'等同于以下代码SET
character_set_connection = 'gbk',
character_set_result = 'gbk',
character_set_client = gbk
不过这也存在漏洞,官方给出的建议是使用mysql_set_charset来设置编码,不过它也是调用了SET NAMES,效果差不多。
对宽字节注入的挖掘比较简单,搜索以下几个关键词即可:SET NAMES
character_set_client=gbk
mysql_st_charset('gbk')
关于宽字节注入有以下几种解决方式:客户端使用utf-8编码
在执行查询之前先执行SET NAMES 'gbk', 再设置character_set_client = binary
使用mysql_set_charset('gbk')设置编码,然后使用mysql_real_escape_string()函数进行参数过滤
使用PDO方式查询
1.3 二次urldecode注入
如果网站某处使用了urldecode或者rawurldecode函数,则又可能导致二次注入。比如当网站先采用addslashes()、mysql_real_escape_string()、mysql_escape_string()函数对字符串进行过滤,然后再对字符串进行解码,这样就会造成二次注入。
测试代码:<?php
$a = addslashes($_GET['p']);
$b = urldecode($a);
echo '$a ='.$a;
echo '
';
echo '$b ='.$b;
原因是当我们提交参数到webserver时,webserver会自动进行解码一次,%25解码后是%,%25%27解码后也就是%27,然后再解码一次,%27解码为单引号。
1.4 防范
目前主要的防范方法有:gpc/rutime魔术引号
主要涉及配置文件参数magic_quotes_gpc和magic_quotes_runtime,前者负责对GET、POST、COOKIE的值进行过滤,后者对从数据库或者文件中获取的数据进行过滤,但是只对单引号、双引号、反斜杠和空字符进行过滤,在int型注入上没多大作用。
使用过滤函数addslashes函数
mysql_[real_]escape_string函数
intval等字符转换
关于以上函数,这里就不多说了PDO prepare预编译
2. XSS漏洞
2.1 漏洞挖掘
XSS漏洞比SQL注入更多,也更难防,经常出现在文章发表、评论回复、留言以及资料设置等地方,在通读代码的时候可以重点关注这几个地方。
挖掘XSS的漏洞关键在于寻找没有被过滤的参数,且这些参数传输到输出函数,常见的输出函数有print、print_r、printf、spintf、echo、die、var_dump、var_export,所以我们只要寻找带有变量的这些函数即可。
2.2 漏洞防范
2.2.1 特殊字符HTML实体转码
一般的XSS漏洞都是没有过滤特殊符号,比如,这里只需要先输入双引号就可以提前闭合利用漏洞,防御这类的XSS一般对特殊字符进行过滤即可。常见的有单引号、双引号、尖括号、反斜杠、冒号、and符号、#。为了保证数据的完整性,最好采用HTML转码。
2.2.2 标签事件黑白名单
过滤字符仍有可能被利用,如宽字节转码可以吃掉反斜杠,面对这种情况可以采用黑/白名单。
3. CSRF漏洞
3.1 漏洞挖掘
CSRF主要是用于越权操作,所有漏洞自然在有权限控制的地方,像管理后台、会员中心、论坛帖子以及交易管理等地方。
我们在漏洞挖掘的时候可以先搭建好环境,打开几个有非静态操作的页面,抓包看有没有token,如果没有token的话在直接请求页面,不带referer,如果返回的数据还是一样的话说明很可能存在csrf漏洞。
从白盒角度来说,主要是看核心文件里面有没有验证token和referer相关的代码。这里的核心文件指的是被大量引用的基础文件,或者直接搜token这个关键字,如果核心文件里面没有,再去看比较重要的功能点的代码。
3.2 漏洞防范
防御CSRF漏洞的最主要问题是解决可信的问题,即使是管理员权限提交到服务器的数据,也不一定是完全可信的,所以针对CSRF的防御有以下两点:增加token/referer验证避免img标签请求的水坑攻击
增加验证码
4. 文件操作漏洞
文件操作包含文件包含、文件读取、文件删除、文件修改以及文件上传等。且一一道来?
4.1 文件包含
文件包含大多出现在模块加载的地方,比如传入的模块名参数,实际上是直接把这个拼接到了包含文件的路径中,比如espcms的代码:$archive = indexget('archive','R');
$archive = empty($archive) ? 'adminuser':'$archive;
$action = indexget('action','R');
$action = empty($action) ? 'login':$action;
include admin_ROOT . adminfile . "/control/$archive.php";
传入的$archive就是被包含的文件名,所以我们在挖掘文件包含漏洞的时候可以先跟踪一下程序运行流程,看看文件名是否可控,另外就是直接搜索include()、include_once()、require()、require_once()这四个函数来回溯看看有没有可控的变量。
文件的包含截断
大多数的文件包含漏洞都是需要截断的,正常的文件代码都是像include(BASEPATH.$mod.'php')这样的方式,如果我们不能写入以php结尾的文件时,那我们就要用到阶段,下面说下几种截断当时
1.利用%00截断,方法很古老,受限于GPC和addslashes的过滤,在php5.3之后的版本中也会失败,所以这基本是个鸡肋方法。
使用举例:<?php
include $_GET['a'].'.php'
?>
请求 http://localhost/test/1.php?a=2.txt%00
2.利用多个英文句号(.)和反斜杠(/)来截断,这种方法不受GPC限制,不过同样在PHP5.3版本之后被修复。
测试代码:<?php
$str = '';
for($i=0;$i<=240;$i++){
$i.='.';
}
$str = '2.txt'.$str;
echo $str;
include $str.'.php';
windows下测试是240个连续的点(.)或者点加斜杠(./)能够截断,linux下是2038个斜杠加点能够截断(/.)
3.远程文件包含时利用问号来伪截断,不受FPC和PHP版本限制。
在HTTP协议里面,访问http://remotehost/1.txt和访问http://remotehost/1.txt?php返回的结果是一样的.webserver把问号之后的内容当成是请求参数,而txt不再webserver里面解析,参数对访问txt返回的内容不影响。所以就实现了伪截断。
4.2 文件读取和下载
文件读取漏洞和下载漏洞差别不大,挖掘起来也很容易,一种方式是可以先黑盒看看功能点对应的文件,再去读文件,另外一种方式就是去搜索文件读取的函数,看看有没有可控的变量,文件读取函数有:file_get_content()、highlight_file()、fopen()、readfile()、fread()、fgetss()、fgets()、parse_ini_file()、show_source()、file(),除了这些之外,还有一些函数,比如文件包含函数include等,可以利用PHP输入输出流php://filter来读取文件。
4.3 文件上传漏洞
文件上传漏洞挖掘起来很简单,一般应用上传点比较少,上传函数只有move_uploaded_file()这一个,所以审计的时候直接搜索这个函数即可,查看文件名能否绕过,问题比较多的是黑名单限制以及未更改上传文件名的方式,未改名一般可以利用解析漏洞。其次涉及到黑名单的绕过,content-type和文件头的绕过。
4.4 文件删除漏洞
挖掘文件删除漏洞可以先去找相应的功能点,直接黑盒测试一下看能不能删除文件,如果删除不了,再去从执行流程追踪文件名的传递参数,也可以搜索带变量参数的unlink()。
5. 代码执行漏洞
5.1 漏洞挖掘
该漏洞主要由eval()、assert()、preg_replace()、call_user_func()、call_user_func_array()、array_map()等函数的过滤不严格导致的,另外还有php的动态函数($a($b))也是目前出现比较多的。eval()和assert()导致的漏洞大多是因为载入缓存或者模板以及对变量的处理不严格导致,比如把一个可控的参数拼接到模板里面,再当成代码执行。
preg_replace()函数的代码执行需要/e参数,这个函数本来是用来处理字符串的,因此漏洞出现最多的地方是在对字符串的处理,比如url、html标签以及文章内容的过滤。
call_user_func()和call_user_func_array()函数的功能是调用函数,多用于框架里面动态调用函数,小程序里面出现这种当时的代码执行会比较少。如果参数可控,那就可以调用意外的函数。
动态函数的代码执行,比如$_GET($_POST['xxx']),基于这种写法变形出来的各种异形,常被用做web后门使用。要挖掘这种形式的代码执行漏洞,需要寻找可控的动态函数名。
5.2 漏洞防范
采用参数白名单过滤即可,可采用正则表达式来限制参数。
6. 命令执行漏洞
6.1 漏洞挖掘
命令执行漏洞是可以执行系统或者应用指令(如cmd或者bash命令),最多出现在包含环境包的应用里面,类似于eyou这类产品,直接在系统安装即可启动自带的web服务和数据库服务。
web应用中会有比较多的点之间使用system()、exec()、shell_exec()、passthru()、popen()、proc_open()等函数直接执行系统命令来调用这些脚本,可以直接在代码中搜这几个函数,收获应该会不少。
除了这类应用,还有像discus等应用也有直接调用外部程序的功能,如数据库导出功能,曾经就出现过命令执行漏洞,因为特征比较明显,所以可以直接搜函数名即可进行漏洞挖掘。
另外反引号也可以直接执行命令,比如<?php
echo `whoami`;
6.2 漏洞防范
php在SQL防注入上有addslashes()、mysql_[real_]escape_string()等函数,在命令上也有防注入函数,一共两个escapeshellcmd()和escapeshellarg(),前者过滤整条命令,后者过滤参数,细节略。
或者采用参数白名单,在使用的时候匹配一下参数是否在白名单,在大多数参数过滤时都很好用。
7. 总结
No summary
php代码审计是什么意思,php代码审计基础篇相关推荐
- Python Qt GUI设计:信号与槽的使用方法(基础篇—7)
目录 1.信号与槽的概念 2.信号与槽的基础函数 2.1.创建信号函数 2.2.连接信号函数 2.3.断开信号函数 2.4.发射信号函数 3.信号和槽的使用方法 3.1.内置信号与槽的使用 3.2.自 ...
- Python Qt GUI设计:窗口布局管理方法【强化】(基础篇—6)
目录 1. 水平布局类(QHBoxLayout) 2.垂直布局类(QVBoxLayout) 3.网格布局类(QGridLayout) 3.1.单一的网络布局 3.2.跨越行.列的网络布局 4.表单布局 ...
- Python Qt GUI设计:窗口布局管理方法【基础】(基础篇—5)
目录 1.布局管理器进行布局 2.容器控件进行布局 3.geometry属性:控件绝对布局 4.sizePolicy属性:微调优化控件布局 Qt Designer提供4种窗口布局方式,分别如下: Ve ...
- ES6 你可能不知道的事 – 基础篇
ES6 你可能不知道的事 – 基础篇 转载 作者:淘宝前端团队(FED)- 化辰 链接:taobaofed.org/blog/2016/07/22/es6-basics/ 序 ES6,或许应该叫 ES ...
- python多线程并发_Python进阶记录之基础篇(二十四)
回顾 在Python进阶记录之基础篇(二十三)中,我们介绍了进程的基本概念以及Python中多进程的基本使用方法.其中,需要重点掌握多进程的创建方法.进程池和进程间的通信.今天我们讲一下Python中 ...
- 基础篇9-python基本数据结构-列表
基础篇9-python基本数据结构-列表 一.列表: 1.有序的集合 2.通过偏移来索引,从而读取数据 3.支持内嵌 a =[[1,2,3],[4,5,6]] 4.可变类型 a[0][1] = 7 二 ...
- Linq初级班 Linq To XML体验(基础篇)
LINQ To XML体验(基础) 这两天开始学习LINQ to XML的知识,我会继续把自己的感想和示例发布给初学者们学习的,一样欢迎高手们多多指点,请勿使用过激语言,针锋相对,我是个初学者,自知还 ...
- php 爬虫_Scrapy 爬虫完整案例-基础篇
1 Scrapy 爬虫完整案例-基础篇 1.1 Scrapy 爬虫案例一 Scrapy 爬虫案例:爬取腾讯网招聘信息 案例步骤: 第一步:创建项目. 在 dos下切换到目录 D:爬虫_scriptsc ...
- class括号里的object_Python入门 类class 基础篇
记住一句话:类是模板,而实例则是根据类创建的对象. 我初学时对类的理解是从类的字面上,可以片面的认为它是一个种类,它是相似特征的抽像,也就是相似的东西,可以把相似特征的事务抽象成一个类.(事务可以是具 ...
- MySQL基础篇:子查询
文章目录 概述 where型子查询 from型子查询 EXISTS型子查询 复制表子查询 概述 在某些情况下,当进行一个查询时,需要的条件或数据要用另一个select语句的结果,这个时候,就要用到** ...
最新文章
- 最强六大开源轻量级人脸检测项目分析
- Linux Bash小结1
- CentOS x64上Matlab R2015b的镜像安装方法与卸载
- 人类一败涂地做图教程_《人类一败涂地》形象绘画技巧图文指南
- 为什么老师批改完试卷,分数下要画两条横线?今天终于知道了!
- 服务器windows模拟linux环境,科学网—Windows不用虚拟机或双系统,轻松实现shell环境:gitforwindows - 刘永鑫的博文...
- Linux安装Ncurses库
- with grant option 与with admin option的区别
- Windows的SVN的下载和安装
- 河北对口升学计算机VB知识点,vb对口升学试题.docx
- matlab心电滤波,应用Matlab对人体的心电信号进行滤波
- EasyDarwin开源云平台接入海康威视EasyCamera摄像机之快照获取与上传
- 分形吧matlab,使用matlab画分形图.pdf
- [sdx62]bitbake lighttpd出现NOTE: Reconnecting to bitbake server...
- 【echarts应用】---pie饼图篇
- react使用antd-mobile做自定义替换头像功能
- ESP8266 网络服务器仪表显示传感器读数
- 级联H桥储能系统研究与设计 soc均衡控制,相内soc均衡,相间soc均衡,蓄电池充放电控制 级联h桥储能
- 原生js实现的金山打字小游戏
- c语言程序设计王立柱pdf,C语言程序设计 教学课件 朱立华 王立柱 C语言程序设计课件第4章090909.pdf...
热门文章
- 痛恨3721的朋友们,装个avast! Antivirus吧
- 计算机打开就是桌面界面的讲解,电脑桌面图标打不开,小猪教您电脑桌面图标打不开怎么办...
- socket tcp java_用JAVA写一个SOCKET 接收TCP发来的消息
- 在linux系统中 用户的主目录可以不在,在Linux系统中,root用户的家目录是 答案:/root...
- linux kernel基本构成的内容有下列哪些项_Linux内核线程kernel thread详解
- win10搭建java开发环境_如何在WIN10搭建Java开发环境
- syslinux引导扇区不支持ntfs文件系统_磁盘与文件系统
- 设计灵感|纯文字排版也能让海报引人注目
- 手机展示海报PSD模板、适用众多设计!
- 电商视觉:焦点图的万能构图模板