起因:

它还时间过得真快,转眼就要大学毕业了,学了这么久的安全,还没有对母校测试一下,哈哈哈,去年测试过,那时候刚学,啥也不会,就感觉学校网站很安全,今天再次测试发现,ennnnnn,"挺好的"。

开始测试

首先进入官网,在官网里面有很多网站服务。

webvpn逻辑?弱口令?

在这个页面中可以看到给了用户名的密码,那么用户名是什么呢?哪里获取用户名?

接下来就继续进入寻找其它网站了,寻找一些信息泄露什么的,或者用户名枚举什么的,发现的一个用户名枚举的网站。

点击修改密码,填写内容并提交

更换一个测试账号尝试:

如果账号存在则返回密码错误,若不存在则返回不存在。

尝试爆破账号,对后三位进行爆破

测试后,找到近百的账号,将账号放到刚刚的webvpn中测试,密码就用网页显示的。

然后就很舒服了,拥有了几十个vpn账号,然后满心欢喜的登录进去,发现.....

呵呵呵

为了回报母校,怎么能就挖一个弱口令给学校呢。这不是很尴尬了。

thinkphp rce

继续找网站,在主站的下面看到了一个教学诊断网

这个确实.....很nice,直接拿出thinkphp漏扫,直接输入url,测试

某系统漏洞合集

当拿到第一个shell后就蛮开心的,继续寻找下一个站点测试,一个一年才打开一次的网站。厚码厚码(我很爱我的学校)

ennn,其实翻到这个页面的时候,没有抱着可以挖到漏洞的心态的,主要是因为.....

进入公共课页面,查看一下有没有waf,尝试插入一条xss的payload,然后.....

额....这是什么waf呀,不认识,那么接下来存在waf的情况下,很多操作都无法进行了,那么在这种情况下,我一般会将这个网址的真实ip找出来,判断是否是云waf,同时找到真实ip也会增加收集到更多的信息。

找到真实ip后就端口扫描了,在端口扫描之前最好先在鹰图,fofa等等平台先收集一波信息,因为nmap或是masscan扫描时可能会封ip。

经过扫描发现了该平台在8099端口,然后就是判断是否会拦截payload了。

good,很好,那么接下来就是测试漏洞了。

看到这个登录界面,首先就是测试是否弱口令,sql注入或者逻辑了,但是经过测试发现不存在这些漏洞,但是存在一个用户枚举漏洞。

用户枚举

然后就是fuzz测试账号了,但是这个漏洞很鸡肋,这里就提一嘴,没啥用。

接口未授权

在尝是了一波js接口后没有发现什么漏洞,但是查找到了一些(没有用的)信息泄露。

近万条数据吧

这样的接口存在3个,但是没有一些很敏感的东西。

以及一句mssql的报错语句

但是像这样的信息泄露算漏洞吗?

本来打算放弃的,但是想起来github,于是将学校域名放github上搜了一些,峰回路转,惊喜来了。

之前都没有找到这个子域名,于是惊喜的将这个打开,

看到这个我感觉差不多赢了一半了,于是开始测试接口,发现接口认证的参数

&accessKey={accessKey}&secretKey={secretKey}

没有作用,无论填不填这两个参数都可以查询或是操作这些接口,相当于这些接口全部都可以调用。

差不多有十几个接口吧。可以添加用户,删除用户,查看学分,查看用户详情等等。

okok,注册一个用户,开始下一轮漏洞。

sql注入(两枚)

在刚刚注册了用户,登录进去。

到这里之后正常的思路应该是找上传点,然后getshell,但是还是想测一下js文件,说不定有什么意外收获呢,于是在经过半小时的测试后发现了几处未授权接口。

第一处

将url和参数进行拼接。

当时测试的时候在id的后面增加字母或者纯数字或是其他标点符号都没有问题(' 123a 等等字符),但是测试发现增加单引号后网页发生了跳转?

于是将该url放入了sqlmap尝试注入:

查看是否为dba权限。

开摆了。

第二处

第二处同样是js文件内找到。

继续构造参数

然后就是fuzz测试了,发现stucode参数在加入单引号后就会返回False,而加入其他任何字符都是返回True,

哎,大概率存在盲注。

经过漫长的等待,终于测试出来了,盲注.....

文件上传

在头像上传的地方,上传图片,抓包。

更改后缀,发现上传文件没有过滤,但是上传脚本文件直接500错误,这个网站是由iis搭建的。

而上传php文件则直接404,应该是服务器设置了什么规则,哎。尝试过很多,但是都失败了。并且会对文件内容进行校验。

但是但是,xss我们还是可以试试的,哎,rce没办法,那就弹个窗吧。

在图片中间的地方插入xss语句

但是如果没有找到可以注册的api,则这个漏洞无法利用,为了扩大漏洞危害,尝试删除cookie,是否可以未授权文件上传。

额,ok,存储型xss.......

弱口令+被拦截的文件上传

继续测试,找到一个心理健康中心的平台,直接找到后台地址

尝试登录,查看数据包

这个难道存在admin用户?可以尝试爆破其他用户?并且测试发现,验证码可以重复使用,

于是直接先来一个爆破用户名

额,有点小意外,哈哈哈哈。

这是啥操作?我只是想爆破用户名的......

登录进入后台

找到文件上传的地方,这里其实测试过js文件内的接口,发现都需要认证,没办法只能找上传接口了。

经过我不断的测试发现,这个文件上传不存在后缀名过滤,

但是存在waf,至于是什么waf就无法判断了,尝试了很多方法都无法绕过,

但是但是,作为一个有理想的人,好歹也来个弹窗吧,安慰一下自己。

上传一个xml文件,弹窗

少壮不努力,老大玩弹窗

为了扩大漏洞危害,必须是未授权上传呀,不然这算漏洞吗?

直接把认证和cookie都删除了

未授权文件上传(存储xss)......

无意中看到这个页面......

你以为我会继续测试?

我没有身份证,所以不测了。

信息收集+登录后台+没有绕过的文件上传

这次是一个第二课堂的系统,其实刚进来是完全没有头绪的.....直到

于是,我将之前信息泄露的学生学号放上去测试,然后

难道学校欺骗小学生?

我不甘心,然后将前面爆破到的教工账号放上去测试。

进入后找了一堆接口发现全部要登录,而且没啥漏洞,于是就把手伸到了文件上传的地方。

第一处:

这一处应该存在黑名单过滤,脚本类文件无法上传,这里包括了xml,html,js,css文件均无法上传,该系统应该存在waf,上传脚本文件直接400错误,就连弹窗快乐一下都不行了?

放弃是不可能的,记得pdf应该也可以弹窗的,然后就是找pdf的弹窗payload,

工具:

osnr/horrifying-pdf-experiments: Stuff which works in Chrome and maybe Acrobat and Foxit. (github.com)

scq.py

# FROM https://github.com/osnr/horrifying-pdf-experiments
import sys
from pdfrw import PdfWriter
from pdfrw.objects.pdfname import PdfName
from pdfrw.objects.pdfstring import PdfString
from pdfrw.objects.pdfdict import PdfDict
from pdfrw.objects.pdfarray import PdfArray
def make_js_action(js):
    action = PdfDict()
    action.S = PdfName.JavaScript
    action.JS = js
    return action
def make_field(name, x, y, width, height, r, g, b, value=""):
    annot = PdfDict()
    annot.Type = PdfName.Annot
    annot.Subtype = PdfName.Widget
    annot.FT = PdfName.Tx
    annot.Ff = 2
    annot.Rect = PdfArray([x, y, x + width, y + height])
    annot.MaxLen = 160
    annot.T = PdfString.encode(name)
    annot.V = PdfString.encode(value)
    # Default appearance stream: can be arbitrary PDF XObject or
    # something. Very general.
    annot.AP = PdfDict()
    ap = annot.AP.N = PdfDict()
    ap.Type = PdfName.XObject
    ap.Subtype = PdfName.Form
    ap.FormType = 1
    ap.BBox = PdfArray([0, 0, width, height])
    ap.Matrix = PdfArray([1.0, 0.0, 0.0, 1.0, 0.0, 0.0])
    ap.stream = """
%f %f %f rg
0.0 0.0 %f %f re f
""" % (r, g, b, width, height)
    # It took me a while to figure this out. See PDF spec:
    # https://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf#page=641
    # Basically, the appearance stream we just specified doesn't
    # follow the field rect if it gets changed in JS (at least not in
    # Chrome).
    # But this simple MK field here, with border/color
    # characteristics, _does_ follow those movements and resizes, so
    # we can get moving colored rectangles this way.
    annot.MK = PdfDict()
    annot.MK.BG = PdfArray([r, g, b])
    return annot
def make_page(fields, script):
    page = PdfDict()
    page.Type = PdfName.Page
    page.Resources = PdfDict()
    page.Resources.Font = PdfDict()
    page.Resources.Font.F1 = PdfDict()
    page.Resources.Font.F1.Type = PdfName.Font
    page.Resources.Font.F1.Subtype = PdfName.Type1
    page.Resources.Font.F1.BaseFont = PdfName.Helvetica
    page.MediaBox = PdfArray([0, 0, 612, 792])
    page.Contents = PdfDict()
    page.Contents.stream = """
BT
/F1 24 Tf
ET
    """
    annots = fields
    page.AA = PdfDict()
    # You probably should just wrap each JS action with a try/catch,
    # because Chrome does no error reporting or even logging otherwise;
    # you just get a silent failure.
    page.AA.O = make_js_action("""
try {
  %s
} catch (e) {
  app.alert(e.message);
}
    """ % (script))
    page.Annots = PdfArray(annots)
    return page
if len(sys.argv) > 1:
    js_file = open(sys.argv[1], 'r')
    fields = []
    for line in js_file:
        if not line.startswith('/// '): break
        pieces = line.split()
        params = [pieces[1]] + [float(token) for token in pieces[2:]]
        fields.append(make_field(*params))
    js_file.seek(0)
    out = PdfWriter()
    out.addpage(make_page(fields, js_file.read()))
    out.write('result.pdf')

payload.js

app.alert("xss")

运行:

python scq.py payload.js

然后会多出来应该result.pdf的文件。

然后怀着激动的心情上传

接下里就是跟上面的一样了,将认证信息以及cookie全部删除,看文件是否可以正常上传

发现文件一样可以上传,可以造成存储xss,哎。

弱口令?

进入另外一处登录地址,是志愿服务

这里尝试了学号,发现学号是无法登录的,然后又用到了教职工号,然后一发入魂

发现所以职工号的密码都为123456,但是进入后需要点击注册,可以接管这个账号,但是作为一个有原则的人,没有进行注册填写,没有影响原有数据。

结尾

额...还有几处漏洞,都是一些框架的漏洞,没什么可说的,直接工具梭哈就可以了,比如struts。

上面说的漏洞也就一个可以getshell,但是这一个getshell并不影响我们进入内网。

直接tasklist查看一下进程

火绒?

懂得都懂好吧,火绒的横向渗透拦截较强,其他的.....

后续就是上线cs,内网漫游了。

简单说一下内网吧,fscan梭哈,资产还是很多的,一些老框架的漏洞很多,还有弱口令有一些吧,大部分都是数据库弱口令。防护软件部分电脑存在。

内网里面的渗透就暂且不发了。

总体来说,这次渗透最重要的就是信息收集了,以及各种漏洞的组合,同时自己也对那些waf的拦截机制也不是很了解,导致后面的几个黑名单都没有绕过去,未来还是需要好好研究一下文件上传过waf的思路了,不然直接高危变低危。

不知不觉就要毕业了,从该开始学网安,那时候就想着总有一天给学校来一次渗透测试,但是由于当时刚刚学,啥也不会,上来就开扫描器,没一会就最直接凉了,还记得当时学校的waf是safedog,现在不知道已经换成啥了,学校的网站也都换了一遍ui。回头看曾经的自己,真好,真希望重头来一遍,再见了学校,再见了她。