上次有小伙伴说JAVA利用链分析太枯燥了,想看SRC和代码审计的案例。
于是~作者日思夜想,翻出了两年前的历史案例,终于写出了这篇文章。该案例历史久远,资产早已下架,仅供参考学习。
这个作者真是太用心了,点点关注吧!!!
-------------------------------------------------------------------------------
本文仅供参考学习,请勿使用本文中所提供的任何技术信息或代码工具进行非法测试和违法行为。若使用者利用本文中技术信息或代码工具对任何计算机系统造成的任何直接或者间接的后果及损失,均由使用者本人负责。本文所提供的技术信息或代码工具仅供于学习,一切不良后果与文章作者无关。使用者应该遵守法律法规,并尊重他人的合法权益。
-------------------------------------------------------------------------------
故事开始:两年前的一天,我在群里看着大家吹水,又有人挖了几个“w”。屏幕上一个个喜报跳出来,让我心里五味杂陈——既羡慕,又失落。羡慕的是他们的技术实力,失落的是自己与他们的差距。那一刻,我下定决心:一定要达到群友实力的一半,哪怕只是一半也好。于是,我摒弃杂念,用一晚上的时间埋头钻研,终于有了以下这篇记录文章。
该专属SRC目标为教育资产,对于常年打edusrc的小伙伴来说会很熟悉。
一、信息收集
1.1、学号收集
确认资产后,作者比较喜欢收集一些信息,例如:学号、工号、姓名、手机号等等。
通过google信息收集得到学号。
https://www.xxx.edu.cn/info/xxx/xxx.htm
在搜索引擎查看子域名,发现存在一个信息系统平台,并且没有验证码。
根据提示测试,存在弱口令。
用户:2020xxxxxxxx 密码:2020xxxxxxxx
登录成功后,翻找功能点,在我的团队->新增功能点处,发现大量学号、姓名信息泄露。
1.2、寻找初始密码平台
google搜索关键字:“初始密码”。
使用学号:2020xxxxxxxx,密码:666666,即可成功登录。
在查看个人信息处发现泄露大量敏感信息,其中包括学号、工号、姓名、sfz等等。
二、登录网上服务大厅
根据统一身份认证系统的提示,密码默认为sfz后6位。
登录服务大厅后,里面存在诸多系统提供我们测试。
2.1、某某咨询系统
2.1.1、越权1
点击体检中心。
查看流量包,把该接口所有的参数全部删除!(滞空大法)
拿到大量用户的 userid 值。
点击修改密码,继续抓包数据包。
把 userid 值替换为 getById 后面的参数值即可越权成功。
2.1.2、越权2
点击个人中心。
修改 userid 再次越权。
2.1.3、信息泄露
在路径:https://xxx.edu.cn/serverapi/swagger-ui.html 中泄露后台api文档,接口中存在大量高危泄露信息。
/serverapi/staff/getStaffList 接口泄露大量教师敏感信息。
/serverapi/api/core/user/page 接口泄露大量教师及学生敏感信息。
/serverapi/student/getStudentList 接口泄露大量学生敏感信息。
2.2、某某一体化服务平台
2.2.1、弱口令
该系统存在多个弱口令账号密码。
使用默认密码获得超管权限,接管某某一体化服务平台。
学生基本信息查看点击查询,可以看到全校敏感信息。
大量敏感数据,不过多展示。
2.2.2、越权
使用学生账号登录系统,在学籍卡片处点击毕业证书查询可跳转到报表系统。
修改参数 xs0101id 为其他学号可查看他人毕业证书。
https://xxx.edu.cn/ReportServer?reportlet=/BYZS.cpt&xs0101id=202xxxxxxxxx
学位证同样。
2.3、某软服务平台
将上面获取毕业证、学位证链接中的 reportlet 参数值删除或修改,可得到某软服务的后台地址。(可再次使用滞空大法)
2.3.1、弱口令
admin\admin123
登录成功,查看用户管理。
查看数据库 ip 及账号密码。
2.4、某某校园自助服务系统
2.4.1、弱口令
验证码可重复使用,通过暴力破解得到大量弱口令。
弱口令密码规则如下:
(姓名拼音)\123465 (工号)\123456 (学号)\(sfz后6位)
弱口令较多,不过多展示。
2.4.2、ssrf
将数据包转发到Burp,复制Burp Collaborator Client中的域名链接,发送如下请求。
得到回显。
2.5、某某服务网络云平台
2.5.1、弱口令
(工号)\123456
大量学生敏感信息数据。
2.6、某某资源库
2.6.1、未授权
通过 js 代码发现接口 /user/getUserInfo,拼接得到如下url:
http://xxx.edu.cn/api/as/user/getUserInfo
直接访问发现存在账号:anonymous,密码为MD5加密解密后得到:Aa123456。
2.6.2、越权1
成功登录游客账号。
继续翻找 js 文件,发现 /user/listAllGroupUser 接口。
通过上面的未授权接口 /user/getUserInfo 获取到 groupId 的参数值。
{"groupId":"default_group"}
既然存在那么简单的未授权漏洞,那么越权漏洞一般必然存在,列出组中所有用户。
通过上方接口 listAllGroupUser 得到的用户名:160029 ,密码和 anonymous 用户一样:Aa123456,可登录。
2.6.3、信息泄露
通过点击该账号页面中显示的文件,Burp抓包拦截。
注意拦截漏洞url为:http://xxx.edu.cn/api/as/file/recommendFileNew。
POST参数:{"fileId":"xxxxx.jpg"}
该接口泄露了管理员密码为MD5加密。
通过管理员用户成功登录,具备众多资源库的管理权限和大量文档。
2.6.4、越权2
通过admin用户打开毕业生作品,拦截数据包得到 fileId: xxx.jpg。
通过 /api/as/share/listMy 接口可以看到所有的文件fileid值。
遍历读取,可读到敏感文件。
2.7、某某登录系统
2.7.1、签名伪造信息泄露1
点击忘记密码。
输入账号12345,开启Burp拦截数据包。
返回用户ID为:12345 的敏感信息,包含sfz、姓名、学号、班级。
通过前端js代码发现参数Sign的生成规律。
其中 MD5KeyYm 为 ok15we1@oid8x5afd@。
编写python脚本(代码见末尾)加密生成Sign,并遍历参数IDNo,第10000到第10100个,python脚本逻辑如下:
因参数Sign是使用IDNo与参数IDType的值,当前时间加上前端env.js泄露的Md5Key的值一起MD5加密的,所以遍历IDNo参数(从10000 - 10100),加密后以POST方式发送到漏洞URL:https://xxx.edu.cn/QueryAccInfoH.aspx 其中得到的Sign值就是:{IDNo}|{IDType}|{当前时间}|{Md5Key} 加密后的值,如ID为12222,当前时间为20220627124630,带入就得到:12222|1|20220627124630|ok15we1@oid8x5afd@ ,将该值MD5加密后就得到Sign:6287fd7b29d7942cbe6c7f48f7451097
遍历数据如下:
2.7.2、签名伪造信息泄露2
/QueryAccPhoto.aspx 接口带上签名可遍历用户照片。
照片这里不过多展示。
2.8、某某服务信息平台
2.8.1、弱口令
(学号)\(学号)
弱口令登录成功后,在选择项目经理功能点处存在信息泄露。
泄露邮箱、密码等信息。
密码 md5 解密。
2.9、电子邮件系统
2.9.1、密码复用
重复使用上面的邮箱账号和密码,可登录电子邮件系统。
接管邮箱。
2.10、宏景人力资源系统
2.10.1、0day前台注入(新版本已修复)
2.10.1.1、权限绕过接口1
打开 F12 翻找 js 文件中的接口进行测试。
在文件在发现一个接口,路径为:
/hire/employNetPortal/search_zp_position.do?br_getpassword=get`dbname="+dbName+"`userC="+userNameCloumn+"`passC="+passWordCloumn 其中 “ ` ”表示GET请求中添加参数的“ & ”。
访问该页面,通过在找回密码页面JS代码中得到路径:
/hire/employNetPortal/search_zp_position.do?b_query=link
拼接访问后可以进入系统页面,此时已经通过身份验证,猜测后台已将当前请求Cookie设为通过验证,再次访问漏洞URL发现不跳转回登录页面,绕过了登录验证。
2.10.1.2、权限绕过SQL注入
在 js 文件中继续翻找,尝试寻找后台的链接。
/train/plan/searchCreatPlanList.do?b_selectPlan=query`selectID=
这时重新访问漏洞URL,发现已经可以访问,绕过了验证。
http://xxx.edu.cn/train/plan/searchCreatPlanList.do?b_selectPlan=query&selectID=1
参数 selectID 输入单引号发现报错。
脏数据绕过 WAF,查询数据。
如果直接访问该注入点会自动跳转到登录页面。
2.10.1.3、权限绕过接口2
回到登录页面,打卡 F12 发现忘记密码的功能点,它的 onclick 调用的是 getPassword 方法。
点击忘记密码链接,看见这个忘记密码的 jsp 文件和登录主页的 jsp 文件,不仅陷入沉思,这是一个 templates 模板的文件夹,下面应该全是 jsp 文件,那么会不会存在 getPassword.jsp 文件呢???
拼接链接,回车访问!!!
网页不存在......
全部改成小写,回车成功访问。
/templates/index/getpassword.jsp
访问后台注入点,没问题。
三、宏景前台注入0day代码分析(新版本已修复)
针对上文提到的宏景前台SQL注入漏洞,作者对其运行逻辑充满好奇。为了解其背后的实现机制,接下来我们将深入代码进行详细分析。
3.1、SetSelectedRecordTrans注入分析
1.访问以下链接即可绕过登录直接访问后台sql注入点 /templates/index/getpassword.jsp 2.后台sql注入链接(selectID存在注入) /train/plan/searchCreatPlanList.do?b_selectPlan=query&selectID=1
3.1.1、/templates/index/getpassword.jsp 分析
16行 session 设置 islogon 为 true ,也就是说只要访问这个文件就会给我们设置 session。
3.1.2、注入点分析
3.1.2.1、struts-config.xml
查看struts-config.xml文件,找到/train/plan/searchCreatPlanList路径,跟入com.hrms.struts.action.FrameAction类型。
3.1.2.2、ActionBase类
FrameAction类继承了ActionBase类。
跟入ActionBase类,找到 execute 方法,该类会默认调用这个方法。
126行获取session,任何128行判断是否为空,因为我们之前已经被设置过session了,无需里面上面的代码,直接走到最后 myexecuteIt方法。
3.1.2.3、FrameAction类
myexecuteIt方法在FrameAction类中。
83行获取了session进行下面的判断,我们不为空,所以不必理会。
94行获取session的sessionHM值,我们没有这个值,进入96行创建一个hashmap对象。
再在100行中把session的sessionHM为空的值放入var5(类似hashmap)里的sessionHM key的值中。
103行获取var5 requestPamaHM key的值,我们也没有这个东西,所以var13赋值也是为空。
115行把var3(Request请求)和空的var13带入到A方法当中。
117行最后返回的对象put添加到requestPamaHM key值里。
52行获取所有的参数名和参数值。
53行进入B方法。
55、56行,如果var2为空,就创建一个hashmap。
61行以&符号进行切割,然后63行对每个参数名和参数值进行遍历。
64行去掉空格,65行再以=符号分割,分别获取参数名和参数值。
68行加入到var2 hashmap返回。
跟进B方法,可以看到是一个全局过滤方法,单双引号都被过滤掉了。
再次回到myexecuteIt方法。
102行获取参数名,然后121行遍历参数名,124行对 "b_" 开头的参数名进行进一步判断。
如果是 "b_" 开头的参数名,在131行使用var8(当前url路径)+ "#" + 参数名 进行字符串拼接。
最后在136行执行跳转到 MRMapping.xml 配置文件的路由当中。
总结:这里的拦截器先去ActionBase类判断是否为登录状态,然后跳转到FrameAction类的myexecuteIt方法对所有的参数名和参数值进行过滤关键字(其中包括单双引号),然后使用【url路径+"#"+参数名】拼接成字符串跳转到MRMapping.xml配置文件路径当中。
3.1.2.4、MRMapping.xml
打开MRMapping.xml文件,找到刚才拼接的路由:/train/plan/searchCreatPlanList#b_selectPlan。
可以看到function-id="2020020116"。
3.1.2.5、WFMapping.xml
在WFMapping.xml文件,搜索2020020116,找到class类路径。
3.1.2.6、SetSelectedRecordTrans类
打开该类,14行通过requestPamaHM key获取所有参数名和参数值。
15行获取selectID参数值,传入到PubFunc.keyWord_reback中。
跟入PubFunc.keyWord_reback,发现居然把本来过滤的单双引号给替换回来了!
以*符号为分割,直接带入sql语句执行。
SQL注入分析到此结束。
四、总结
这次从黑盒挖 SRC 到 0day 分析的旅程到这里就画上了句号。从整体过程来看,其实并没有使用什么高深的技术,更多是基于常规的 top 漏洞进行分析和挖掘。然而,这样的基础方法依然能带来一些突破,但在当前愈发内卷的环境下,仅仅依靠常规漏洞和传统思维,显然难以脱颖而出,也容易被行业淘汰。
因此,作者认为,与其固守常见的挖洞思维,不如更多地尝试拓展攻击面的横向思路。比如,一个看似不起眼的弱口令或信息泄露,往往能引发一连串的安全问题,从而实现链式攻击,这才是未来挖掘的重要方向。
作者始终坚定:黑盒的最终目的,是为了更好地服务于白盒安全审计。黑盒可以帮助我们发现问题,而白盒则是深挖问题根源、从代码层面构筑安全防线的必经之路。
最后,作为对这段历程的总结,想与大家分享一个自己的看法:基础虽重要,但在基础之上,只有不断思考和探索新的攻击路径,才能走得更远,看到更多可能性。
附上两年前专属的SRC赏金作为这次分享的收尾,也希望这段经历能对大家有所启发。