前言
为了更好的理解漏洞原理以及提升自己的挖洞能力,终于还是入坑了代码审计。况且这个想法已经在脑海中酝酿很久了,但由于方方面面的原因没能照顾到代码审计的学习,索性趁五一假期宅在家里有时间,所以打算正式把这门手艺安排上。
何为代码审计
简介
代码审计(Code audit)是一种以发现程序错误,安全漏洞和违反程序规范为目标的源代码分析。
即对源代码进行检查,寻找代码中会导致安全问题的bug(漏洞)。
前置知识
掌握基础的编程语法
能看懂代码的逻辑
漏洞形成原理的理解
熟悉不同系统的不同特性
熟悉各种中间件的特性差异
通用审计思路
思路概览
- 回溯敏感函数的参数传递过程
- 查找可控变量,追踪变量传递过程
- 寻找敏感功能点,通读其代码
- 直接阅读通篇代码
实例讲解(回溯敏感参数)
espcms_v5源码
Seay源码审计工具
审计开始
先用工具自动审计一波,看看有哪些可能的漏洞
选中提示由sql注入漏洞的地方,双击跟进:
可以发现,在第23行的sql语句中有可控的参数$parentid
。在右边的变量列表中点击该变量,可以看到其赋值流程:
可见,参数$parentid
从函数accept()
中获得,右键该函数并选择函数定位。最后在文件class_function.php
的第353行发现该函数的定义:
该函数的作用是获取参数$_GET
、$_POST
、$_COOKIE
的值,然后进入R
分支。
显然,这里的传参是可以控制的,首先是对$_GET进行传参,然后才是$_POST。
但是,在第372行中,参数$var[$k]被函数daddslashes()
进行了处理,所以,在这里跟进分析一波函数daddslashes()。
在第179行有该函数的定义:
addslashes()函数的功能:
daddslashes() 函数对字符串或数组进行反斜杠处理
在单引号,双引号,反斜杠前'添加反斜杠'
一般用于对表单提交的数据进行处理,防止sql注入
'附:'如果MAGIC_QUOTES_GPC=ON,则不处理。
但是尽管如此,这里的处理并不影响对该漏洞的利用,因为此处的sql语句中没有单引号(’),所以我们不需要去构造闭合的利用条件。
$sql = "select * from $db_table where parentid=$parentid";
于是,便可以确认这里存在sql注入。接下来只需要找到该漏洞的触发点即可,回到漏洞点,发现漏洞函数oncitylist()定义在继承了connecter类的important类
中。
右键全局定位该类(important),最后在/adminsoft/index.php中发现了该类的实例化,也就以为着我们可以在此处构造payload:
先简单分析以上代码:
先由函数indexget()获取参数$archive和$action
然后包含/control/\$archive.php
再由语句`$action='on'.$action`赋值
最后传入if语句进行判断后执行$action函数
现在我们来整体理一遍流程:
函数oncitylist()存在sql注入,参数$parentid,文件citylist.php
$parentid由\$_GET()传入前经过daddslashes()处理
所以可确认函数oncitylist()中存在sql注入
而函数又在类important中被定义
即在实例化important类时通过GET方式由\$action传入citylist
以及传入$archive=citylist包含citylist.php
所以最后构造的payload:
http://192.168.43.143/upload/adminsoft/index.php?archive=citylist&action=citylist&parentid=-1%20union%20select%201,2,user(),4,5
常见漏洞审计tips
sql注入漏洞
可以定位以下数据库操作关键字
select from
mysql_connect
mysql_query
mysql_fetch_now
update
insert
delete
#查到这些关键字后,定向追踪他们,就可以审计sql注入漏洞
sql注入漏洞之编码注入
#mysql的宽字节注入
可以定位以下函数
urldecode()
rawurldecode()
sql注入漏洞之宽字节注入
'前提条件'
set character_set_client='gbk'
set NAMES 'gbk'
可以定位以下关键字
SET NAMES
character_set_client
mysql_set_charset('gbk')
#判断代码中是否有宽字节注入
sql注入漏洞之二次url解码注入
前提
GPC开启
可以定位以下关键函数
urldecode()
rawurldecode()
#通过urldecode()或rawurldecode()
#那么通过二次解码
#会解析出单引号,导致注入
反射型xss漏洞
可以定位以下关键字
echo
print
...
#若直接将未经过滤的用户输入输出
#就会造成反射型XSS
存储型xss漏洞
'查找写入数据的sql语句以及输出'
#条件
数据库这块过程中没有进行实体化编码以及输出
页面的过程中没进行实体化编码
#很容易产生存储型XSS
本地文件包含漏洞
常存在于模块加载,模板加载
可以定位以下函数寻找可控变量:
include()
include_once()
require()
require_once()
远程文件包含漏洞
'前提':allow_url_include = on
allow_url_fopen=on
php://input和php:filter
可以定位以下关键函数寻找可控变量:
include()
include_once()
require()
require_once()
文件读取(下载)漏洞
可以定位以下关键函数寻找可控变量:
file_get_contents()
highlight_file()
fopen()
read_file()
fread()
fgets()
parse_ini_file()
show_source()
file()
...
文件上传漏洞
可以定位以下关键函数
move_uploaded_file()
getimagesize()
copy()
#看调用这个函数的代码是否存在为限制上传格式或者可以绕过
文件删除漏洞
可以定位以下关键函数
unlink()
#利用回溯变量的方式控制代表文件操作行为的参数
CSRF漏洞
首先寻找后台的一些功能点(添加管理员/修改管理员密码等)
CSRF多是由于没有验证token及referer而存在
# 后台CSRF配合上一些后台的漏洞往往能造成一些大的危害
如任意文件上传+上传点处CSRF = Getshell
代码执行漏洞
可以定位以下关键函数来进行分析
'代码执行函数'
eval()
assert()
preg_replace()
call_user_func()
call_user_func_array()
array_map()
'命令执行函数'
system()
exec()
shell_exec()
passthru()
pcntl_exec()
popen()
proc_open()
...
代码逻辑漏洞
in_array(): 比较之前会自动转换类型
is_numeric():当传入参数为hex时 直接通过并返回true
#MYSQL可以直接使用hex编码代替字符串明文 可以二次注入 并且可能造成XSS漏洞
双等于==和三等于===
...
业务逻辑漏洞
'抓包分析以下问题'
程序是否可以重复安装
修改密码是否存在越权修改其他用户密码
找回密码验证码是否可以暴力破解
cookie是否可以预测 验证存在绕过
变量覆盖漏洞
可以定位以下关键函数以及符号$
extract()
parse_str()
import_request_variables()
'$$'
#$$变量覆盖
XXE漏洞
可以定位关键函数
simplexml_load_string()
以及关键字
Document
...
.
.
.
结语
由于目前的我没有太多挖洞经验,很多都是基于靶场练习,于是暂时只打算记录我在学习过程中经常遇见的Web漏洞审计tips,至于其他漏洞等以后碰见了再补上!
这也算是正式吹响代码审计的号角了!
参考文章:
Railgun’s Blog
sosly 菜鸟笔记
代码审计之旅