代码审计入门总结
通用思路
- 通读全文代码,从功能函数代码开始阅读,例如include文件夹下的
common_fun.php
,或者有类似关键字的文件。 - 看配置文件,带有config关键字的文件,找到
mysql.class.php
文件的connect()函数,查看在数据库连接时是否出现漏洞。 - 继续跟读首页文件
index.php
了解程序运作时调用了哪些函数和文件,以index.php
文件作为标线,一层一层去扩展阅读所包含的文件,了解其功能,之后进入其功能文件夹的首页文件,进行扩展阅读。
漏洞总结:
1.文件操作漏洞
①.文件包含漏洞:(详细可看:https://www.jianshu.com/p/41bb503abe61)
(1) 本地文件包含:
一般存在于模块加载,模板加载,cache调用
包括函数:include()/include_once(),require()/require_once()寻找可控变量
(2)* 远程文件包含:*
前提条件:allow_url_include = on
(3) 文件包含截断:
%00截断(php版本小于5.3)
问号截断(问号后面相当于请求的参数,伪截断)
英文(.) 反斜杠(/) 截断
②.文件读取(下载)漏洞:
搜索关键函数:
file_get_contents() highlight_file() fopen() read file() fread() fgetss() fgets() parse_ini_file() show_source() file() ......
③.文件上传漏洞:
搜索关键函数:move_uploaded_file()
接着看调用这个函数的代码是否存在为限制上传格式或者可以绕过。
(1) 未过滤或本地过滤:
服务器端未过滤,直接上传PHP格式的文件即可利用。
(2) 黑名单扩展名过滤:
限制不够全面:IIS默认支持解析.asp,.cdx, .asa,.cer等。
(3) 文件头 content-type验证绕过:
- getimagesize()函数:验证文件头只要为GIF89a,就会返回真。
- 限制$_FILES["file"]["type"]的值 就是人为限制content-type为可控变量。
④.文件删除漏洞:
搜索关键函数:unlink()
利用回溯变量的方式
老版本下的session_destroy(),可以删除文件,现已基本被修复。
2.代码执行漏洞
①代码执行函数:
搜索关键函数:
eval(), assert(), preg_replace(), call_user_func(), call_user_func_array(), array_map()
(1) preg_replace()函数:
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )
当$pattern处存在e修饰符时,$replacement 会被当做php代码执行。
(2)call_user_func()函数
mixed call_user_func( callable $callbank [ , mixed $parameter [ , mixed $…):
第一个参数为回调函数,第二个参数是回调函数的参数
(3)eval()和assert():
当assert()的参数为字符串时 可执行PHP代码
eval(" phpinfo(); ");【√】 eval(" phpinfo() ");【X】 assert(" phpinfo(); ");【√】 assert(" phpinfo() ");【√】
②.动态函数执行:
动态函数后门:
<?php $_GET['a']($_GET['b']); ?>
③.命令执行函数:
搜索关键函数:
system(), exec(), shell_exec(), passthru() ,pcntl_exec(), popen(),proc_open()
(1) popen()和proc_open():
<?php popen( 'whoami >> 1.txt', 'r' ); ?>
所在路径就会出现一个1.txt ,里面的内容为命令执行后的结果
(2) 反引号命令执行:
<?php echo `whoami`; ?> //直接就可以执行命令
双引号和单引号的区别:
<?php $a = 1; echo " $a " ; //1 echo ' $a ' ;//$a ?> //双引号时,可以直接解析变量,造成代码执行漏洞。
3.变量覆盖漏洞
①.函数使用不当:
int extract( array &$var_array , int $extract_type = EXTR_OVERWRITE , string $prefix = null ) void parse_str( string $str , array &$arr ) bool import_request_variables( string $type , string $prefix )
②.$$变量覆盖:
<?php include "flag.php"; if ($_SERVER["REQUEST_METHOD"] != "POST") die("flag is here"); if (!isset($_POST["flag"]) ) die($_403); foreach ($_GET as $k => $v){ $$k = $$v; } foreach ($_POST as $k => $v){ $$k = $v; } if ( $_POST["flag"] !== $flag ) die($_403); echo "flag: ". $flag . "\n"; die($_200); ?>
使用了两个foreach并且也使用了$$.两个foreach中对 $$key的处理是不一样的,满足条件后会将$flag里面的值打印出来。
但是由于后两个if语句及foreach
代码会将$flag的值给覆盖掉了,所以需要先将$flag的值赋给$_200或$_403变量,然后利用die($_200)或 die($_403)将flag打印出来。
解题方法:
利用第一个foreach先将$flag的值赋给$_200,然后利用die($_200)将原本的flag值打印出来。
最终PAYLOAD:
GET DATA:?_200=flag POST DATA:flag=aaaaaaaaaaaaaaaaaaaaa
4.逻辑漏洞
需要思考的问题:
- 程序是否可以重复安装
- 修改密码是否存在越权,修改其他用户密码
- 找回密码验证码是否可以暴力破解
- cookie是否可以预测 验证存在绕过
①.账户体系中的越权问题:
- 水平越权:A用户能够以B用户的身份,进行B用户的全部权限操作。前提A用户和B用户拥有相同的权限。
- 垂直越权:A用户能够以C用户的身份,进行C用户的全部权限操作,前提C用户比A用户拥有更高的权限。
(1) 未exit
/return
/die
:
<?php if(file_exists('install.lock)){ header("Location:xxx.com"); } echo "test"; ?>
test 依旧会被输出,替换成安装流程,PHP依旧会进行。
(2) 支付漏洞:
- 客户端修改单价
- 客户端修改总价和购买数量
- 服务端未校验严格
- 重复发包利用时间差:
<?php if (check_money($price)){ //Do something //花费几秒 $money = $money - $price; } ?>
可能导致漏洞函数: str_replace()
<?php $a = addslashes($_GET['a']); $b = addslashes($_GET['b']); echo "$a<br>$b<br>"; $c = str_replace($a,'',$b); echo trim($c); ?>
5.会话认证漏洞
- COOKIE验证:没有使用SESSION验证,将信息直接保存在COOKIE中
- 找到传入sql语句的参数的传递过程,回溯变量到最原始的函数,看它保存在cookie的算法是否可逆
- 审计代码时,查看登录处代码

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Go语言探索 - 2(原创)
Go语言基础系列博客用到的所有示例代码 在上一篇文章中,我们主要学习了Go语言环境的安装、IDE的基本安装和使用,这一篇主要学习Go 编程语言的基础。 注释: 注释不会被编译,每一个包应该有相关注释。其中,单行注释是最常见的注释形式,你可以在任何地方使用以 // 开头的单行注释。多行注释也叫块注释,均已以 /* 开头,并以 */ 结尾。(注释的规则适用于很多门语言) 分隔符: 在 Go 程序中,一行代表一个语句结束。每个语句不需要像 Java语言一样以分号 ; 结尾。因为这些都将由 Go 编译器自动完成。 但是如果打算将多个语句写在同一行,就必须使用 ; 人为区分,但在实际开发中我们并不鼓励这种做法,建议分行写 标识符: 标识符是用来命名变量、类型等程序实体。一个标识符实际上就是一个或是多个字母(A~Z和a~z)数字(0~9)、下划线 _ 组成,但是,标识符的第一个字符必须是 字母或下划线 而不能是数字。 以下是无效的标识符: 233(以数字开头) select(Go 语言的关键字) a+b(运算符是不允许的) 空格: 值得一提的是:Go 语言中变量的声明须使用空格隔开 包结构: Go...
- 下一篇
Python sublime 中文的问题汇总【收藏】
Python sublime 中文编译和中文路径问题 转载请标明出处: https://blog.csdn.net/DJY1992/article/details/80272602 本文出自:【奥特曼超人的博客】 中文字符编译问题汇总 中文路径编译问题汇总 目录: Python sublime 中文编译和中文路径问题 一、中文字符编译问题汇总 1.1 控制台无输出 [Decode error - output not utf-8] 1.2 python2 or python3 环境问题 1.3 UnicodeEncodeError:’ascii’ codec can’t encode character 二、中文路径编译问题汇总 2.1 路径中带有中文的问题 2.2 文件用中文命名的问题 一、中文字符编译问题汇总 sublime 设置:可以用过2种方法打开 1. Preferences -> Browse Packages 2. 默认安装路径:C:\Program Files (x86)\Sublime Text\Data\Packages\ (个人) 1.1 控制台无输出 [D...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS7设置SWAP分区,小内存服务器的救世主
- Mario游戏-低调大师作品
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- 2048小游戏-低调大师作品
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题