代码审计⼊门
⼜补了⼀⼤章节的课程,对我来说感觉很多都要学习,不太会,那就先熟悉流程
1 代码审计⼊门
1、常见的代码审计⼯具
1、Fortify SCA
2、Checkmarx CxSuite
3、360代码卫⼠
4、PHP代码审计⼯具——Rips
参考:www.jianshu/p/cd1cb66e4d7d
5、seay代码审计(常⽤)
参考:www.oschina/p/seay
6、SonarQube
参考:wwwblogs/qiumingcheng/p/7253917.html
7、Cobra
参考:zhuanlan.zhihu/p/32363880
8、kiwi
参考:github/alpha1e0/kiwi
2、代码审计中常见的危险函数和字符串
参考:
/drops/drops/%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E5%85%A5%E9%97%A8%E6%80%BB%E7%BB%93.html 0x01 整体
0x02 各种洞洞
a.⽂件操作漏洞
1.⽂件包含漏洞:
(1) 本地⽂件包含:
(2) 远程⽂件包含:
(3) ⽂件包含截断:
2.⽂件读取(下载)漏洞:
3.⽂件上传漏洞:
(1) 未过滤或本地过滤:服务器端未过滤,直接上传PHP格式的⽂件即可利⽤。
(2) ⿊名单扩展名过滤:
(3) ⽂件头 content-type验证绕过:
(4) 防范:
4.⽂件删除漏洞:
b.代码执⾏漏洞
1.代码执⾏函数:
(1) preg_replace()函数:
(2)mixed call_user_func( callable $callbank [ , mixed $parameter [ , mixed $…):
(3)eval()和assert():
2.动态函数执⾏:
3.命令执⾏函数:
(1) popen和proc_open():
(2) 反引号命令执⾏:
c.变量覆盖漏洞
1.函数使⽤不当:
2.$$变量覆盖:
d.逻辑漏洞
1.等于与存在判断绕过:
(1) in_array(): ⽐较之前会⾃动转换类型
(2)is_numeric():当传⼊参数为hex时直接通过并返回true 并且MYSQL可以直接使⽤hex编码代替字符串明⽂可以⼆次注⼊并且可能造成XSS漏洞
(3)双等于==和三等于===:
2.账户体系中的越权问题:
(1) 未exit/return/die:
(2) ⽀付漏洞
e.会话认证漏洞
1. 到传⼊sql语句的参数的传递过程回溯变量到最原始的函数看它保存在cookie的算法是否可逆
2. 和MD5⽐起 sha1更安全解密sha1的⽹站更少
3. 限制⼀个⽤户只能同时在⼀个IP上登录
f.⼆次漏洞
1.类型:
2.技巧:
(1) 钻GPC等转义的空⼦:
GBK的宽字节注⼊
(2)字符串问题:
2 常见的危险函数和审计点
1、RIPS审计⼯具的下载,安装,使⽤
2、PHP常见的部分危险函数解析
2.1 PHP代码执⾏函数
a.eval()
b.assert()
2.2 PHP包含函数
常见的包含函数:require,include,require_once,include_once
include $file 中,如果变量 $file 可控,则就可以包含任意⽂件。
此外,根据不同的配置环境,可以包含不同的⽂件:远程⽂件和本地⽂件。
包含函数还可以通过⽀持的协议和封装协议以及过滤器读取任意⽂件内容。
例⼦,如
利⽤php流filter读取任意⽂件
include($_GET('file');
// ?file=php://filter/convert.base64-encode/resource=index.php
上⾯的代码中,就通过filter读取index.php的内容,并将内容编码成base64再输出。
2.3命令执⾏函数
常见的命令执⾏函数有:
* exec() -- 执⾏⼀个外部程序
* passthru() -- 执⾏外部程序并显⽰原始输出
* proc_exec() -- 通过shell环境执⾏命令,并且将完整的输出以字符串的⽅法返回
* system() -- 执⾏外部程序,并且显⽰输出
* popen() -- 通过popen()的参数传递⼀条命令,并对popen()所打开的⽂件进⾏执⾏。
2.4 ⽂件操作函数常见的任意⽂件读取,写⼊,删除往往是下⾯⼏个函数受到了控制. copy() -- 拷贝⽂件
file_get_contents() -- 将整个⽂件读⼊⼀个字符串
file_put_contents() -- 将⼀个字符串写⼊⽂件
file() -- 将整个⽂件读⼊⼀个数组中
fopen() -- 打开⽂件或者URL
move_uploaded_file() -- 将上传的⽂件移动到新位置
readfile() -- 读取⽂件
rename() --重命名⽂件或者⽬录
rmdir() -- 删除⽬录
unlink() & delete() -- 删除⽂件
详细参考链接:buluo/Dukebf/note/715934
www.bbsmax/A/pRdB8DR6Jn/
3 代码审计实战之SQL注⼊漏洞
1.基本技巧
sql注⼊漏洞通常有两种利⽤⽅式。⼀种是权限较⼤,直接写⼊webshell,另外⼀种是权限较⼩,但是可以读取⽤户账号密码,⽐如读取管理员账号密码,登录后台管理。
sql注⼊经常出现在登录页⾯http请求中的user-agent,client-ip,x-forward-for等可能会被程序存储到数据库中的地⽅。另外,在订单处理的地⽅,由于业务逻辑复杂,经常会有⼆次注⼊漏洞。
⾄于在⽩盒审计中,若想定向挖掘sql注⼊漏洞,只需要注意这⼏个数据库操作关键字:select from , mysql_connect , mysql_query , mysql_fetch_now , update , insert , delete ;查到这些关键字后,定向追踪他们,就可以审计sql注⼊漏洞
2.编码注⼊
程序在进⾏⼀些操作之前,经常会进⾏⼀些编码处理,通过输⼊⼀些编码函数不兼容的特殊字符,可以导致输出的字符变成有害数据。其中最常见的编码注⼊就是mysql的宽字节注⼊以及urldecode/rawurldecode这两个函数。
宽字节注⼊
怎么说呢,这个漏洞以前研究过,但是总是没研究透。个⼈感觉,只要是set character_set_client='gbk'或者set NAMES 'gbk',那么就可能存在漏洞。⾄于原理虽然⽆法搞的⼗分清楚,但是可以直接⼿⼯测试。看能否吃的掉转义字符。
解决这个漏洞的⽅法:
第⼀种⽅法,set NAMES 'gbk' 之后,在 set character_set_client=binary就可以了。
第⼆种⽅法,使⽤pdo⽅式,在php5.3.6及以下版本设置 setAttribute(PDO::ATTR_EMULATE_PREPARES,false);来禁⽤prepared statements的仿真效果。
综上所述,要想看代码中是否有宽字节注⼊,那么搜索⼏个关键字:
SET NAMES
character_set_client
mysql_set_charset('gbk')
⼆次urldecode注⼊
如果⽬标⽹站开启了GPC,并且⽤了urldecode或者rawurldecode函数,那么通过⼆次解码,第⼆次就会解析出单引号,导致注⼊。
因此,在代码审计中,可以通过搜索urldecode和rawurldecode来挖掘⼆次注⼊漏洞。
常见的注⼊点:
输⼊
HTTP头
user-agent
client-ip
x-forward-formysql 字符串转数组
数据库操作关键字
select/update/insert/delete
mysql_connect
mysql_query
mysql_fetch_row
编码注⼊
sql注⼊预防⽅法
通常,程序要么被动获取参数,⽐如get,post;要么主动读取⽂件或者远程页⾯;因此,过滤好这两条路,就可以防⽌sql注⼊。
在PHP的核⼼配置中,magic_quotes_gpc负责对get,post,cookie的值进⾏过滤,magic_quotes_runtime对从数据库中或者⽂件中获取的数据进⾏过滤。
但是,上⾯两种⽅法只能过滤部分sql注⼊,因为他们只是转义了单引号,双引号,反斜杠\,空字符null,对int注⼊没什么⽤。因为int类型可以直接接sql语句,不需要闭合。
addslashes函数
这个函数对参数中的单引号,双引号,反斜线,空字符进⾏过滤。但是有的程序员在开发的时候,没有考虑到get请求中可能存在数组(这个函数是对字符串进⾏过滤),导致了绕过。
说实话,get请求中带数组是怎么带的?这个我还真⽐较懵。估计得完整开发⼀个⽹站之后,才能知道get请求中带数组是怎么回事?
mysql_rel_escape_string($str,$con)
这个函数也是过滤,第⼀个参数是字符串,第⼆个参数可选,是数据库连接,若没有设置第⼆个参数,那就默认为上⼀次连接的数据库。
这个函数主要过滤的是:\x00,\n,\r,\,',",\x1a
但是,这⾥的\x00和\x1a我不太懂是什么意思。
intval()函数
前⾯的函数针对的是字符型注⼊,对Int型注⼊效果不是太好。因此,这个intval()函数就是以⽩名单的思想,对数据进⾏过滤。
4 代码审计实战之任意⽂件上传
1、代码审计之⽂件上传漏洞危险函数的绕过姿势
C⽂件头content-type验证绕过:验证$_FILES[“file”][“type”]的值,这个是可控的。
D.函数误⽤导致上传绕过
以iconv()函数为例,在iconv转码的过程中,utf->gb2312(其他部分编码之间转换同样存在这个问题)会导致字符串被截断,如:$filename=”shell.php(hex).jpg”;(hex为0x80-0x99),经过iconv转码后会变成$filename=”shell.php “。
E.竞争上传,主要涉及到的为copy函数。
2、⽂件上传漏洞审计流程
1. 审计函数
2. move_uploaded_file()
3. 定义和⽤法:
4. move_uploaded_file() 函数将上传的⽂件移动到新位置。
5. 若成功,则返回 true,否则返回 false。
6. 语法:
7. move_uploaded_file(file,newloc)
8. 超全局变量 $_FILES
9. 后缀名是图⽚格式
10. 前缀名不能是外部提交的
11. 上传的⽬录不可以是获取外部提交的路径
3、代码举例分析
⽂件上传⾸先需要⼀个表单,如下,我们把它叫做a.html:
<form action="t.php" method="post" enctype="multipart/form-data"><input name="aaa" type="file" /><input type="submit" /></form>
这⾥有⼏个要素:
action属性是提交的⽬标。
method属性是提交所⽤的HTTP⽅法,常⽤的就是 POST 和 GET,⽂件上传⼀般⽤ POST。
enctype属性必须要写成这样,因为⽂件上传和普通的提交具有不同的编码⽅式。如果不写的话,可能会被当做urlencoded,就是k1=v1&k2=v2的键值对形式,导致解析不出东西。
最后是⽂件输⼊框,它的name属性⾮常重要,它是PHP脚本中寻⽂件的关键字。
接下来是PHP脚本中的东西,PHP中通过$_FILES对象来读取⽂件,通过下列⼏个属性:
$_FILES[file]['name'] - 被上传⽂件的名称。
$_FILES[file]['type'] - 被上传⽂件的类型。
$_FILES[file]['size'] - 被上传⽂件的⼤⼩(字节)。
$_FILES[file]['tmp_name'] - 被上传⽂件在服务器保存的路径,通常位于临时⽬录中。
$_FILES[file]['error'] - 错误代码,0为⽆错误,其它都是有错误。
t.php中的代码写成这样:
<?phpif(!isset($_FILES['aaa'])) {
echo 'file not found';
exit();
}
var_dump($_FILES['aaa'])
可以看到那个aaa就是⽂件输⼊框中的name属性。
我们把这两个⽂件放到服务器的⽬录中,或者直接在⽬录下启动PHP⾃带的服务器。之后打开a.html随便传上去⼀个⽂件,会得到这样的结果,这⾥我直接上传了a.html:array(5) {
["name"]=> string(6) "a.html"
["type"]=> string(9) "text/html"
["tmp_name"]=> string(44) "C:\Users\asus\AppData\Local\p"
["error"]=> int(0)
["size"]=> int(133)
}
需要说的是,在处理⽂件上传的时候,不应信任⽂件类型type,因为类型在浏览器⽣成之后,是可以改的。甚⾄可以⼿动构造出于类型与实际内容不匹配的数据包。
同时也不应该信任⽂件名称name。⽽是应该分离⽂件名与扩展名,对扩展名进⾏⽩名单过滤。⽂件名
按需舍弃重新⽣成,或者过滤后再使⽤。
5 PHP反序列化漏洞代码审计
1、什么是序列化
A、PHP⽹站的定义:
B、PHP反序列化
2、理解PHP反序列化漏洞
3、PHP反序列化漏洞利⽤的前提
a.unserialize()函数的参数可控;
b.php⽂件中存在可利⽤的类,类中有魔术⽅法
4、PHP反序列化漏洞—发现技巧
5、PHP反序列化漏洞—构造exploit思路
6、案例分析
wwwblogs/xiaozi/p/7839256.html
1st/posts/php-unserialize-analysis/
注:以上⼤多转⾃破壳笔记学习资料,欢迎⼤家前来报名学习
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论