记又一次曲折的集团SQL注入

admin 2024年7月15日11:01:28评论7 views字数 2939阅读9分47秒阅读模式

又名,为下班我也是拼了。

被毙掉的第二篇,难度确实一般但是我感觉还是挺有参考性的嘛~

. . . * . * 🌟 * . * . . .

1 | 首页遇注入

集团首页点点点,直接找到个注入:
记又一次曲折的集团SQL注入

简单梭哈一把and1=1,被拦也是意料之中:

记又一次曲折的集团SQL注入

但这种拦截看着很像是代码级,看到之后心就凉凉一半。不过秉承着:

记又一次曲折的集团SQL注入

还是搞一搞绕过。

2 | 硬刚刚不过

由于客户需要的是证明注入能威胁到整个系统的数据安全(说人话就是要证明能够跑出大量真实数据,不能只注出用户名下班),所以我需要绕过整个WAF的校验而不是仅仅通过换关键字跑出特定数据。
先以乐观的心态假设这是一个WAF,试一试WAF层面的混淆。
第一个自然是熟悉苯人的老读者都知道的垃圾参数,这个方法对WAF可能有效,但对代码拦截是绝对无效的(我难以想象对代码拦截有效的垃圾参数要怎么塞...)。
这里失败,截图我都懒得截。
然后尝试超长参数,失败也是意料之中:

记又一次曲折的集团SQL注入

接下来能做的就不多了,因为一般对WAF进行绕过主要是依靠WAF与服务器的解析差异,而代码级别的拦截很明显是不受这种影响的。
死马当活马医看看这个拦截是否只对一种方式生效(as if GET),还是试一试别的传参方式,比如POST、POST(multipart)、POST(json),但从响应来看这次的拦截覆盖面比较全,并没有漏网之鱼的存在。

记又一次曲折的集团SQL注入

这就很麻烦了,手注脱裤子实际上笔者真没做过(这种感觉破坏力巨大的事情我一般扔给sqlmap),而以现在这种混淆情况能不能注出个用户名都两说,何况出数据呢?

3 | 转进如风,撕开第二个口子

跟第一个点硬刚了半个钟,还是没找到什么比较好的注数据方法。
冷静下来仔细想了一遍:

  1. 1. 只需要一个能证明危害的漏洞即可下班

  2. 2. 已知官网有注入,且测试范围是整个集团

  3. 3. 拦截一般是补救策略而非出厂配置(这个是笔者个人的经验,毕竟出厂能想到注入的早ORM了,在我眼里不上ORM的所有过滤行为一律视为脱裤子放屁,PHP除外)

分析一番之后,感觉还是抄起键盘学习常校长的跑路精神比较好——一个官网就有注入的集团其他地方不用想都知道是筛子嘛。

记又一次曲折的集团SQL注入

果粉要打我我可就要打果粉了

于是进行一番常见的信息收集,找到客户的某个小程序(这里就不上图了,对客户负责)。试了几个功能后回头来看BP,没想到是加密的包:

记又一次曲折的集团SQL注入

不过说实话,这种时候越看到加密的包我越兴奋,毕竟客户看上去还是会修洞的,但这种加密系统八成还没有被人发现过漏洞,只要有注入就约等于下班^ ^。
简单反编译下小程序源码,快速找到Key、Iv:

记又一次曲折的集团SQL注入
记又一次曲折的集团SQL注入

整体加密的json,倒也不罕见。
然后手动加点小参数试一下,直接报错,连数据库类型都给报出来了:

记又一次曲折的集团SQL注入

这下又是看到下班的希望了,再试试是否有拦截,也是米有。那么只要过了这个加密就基本下班了。

4 | mitm牌代理

笔者之前是用过自动加解密的插件的,只可惜这次试了很多次也匹配不到加密点。sqlmap的tamper更不用说,它是无法对整个body进行加密的(当然,如果真要强来也有强来的办法,只是不知道sqlmap会如何应对空荡荡的body)。试来试去,试到最后人都麻了,甚至打算现写bp插件。不过还好最后想起mitmproxy这个各种场景下都非常好用的中间代理。
mitmproxy这个工具的具体功能我就不多介绍了,之前写Android渗透的时候也介绍过了。直接使用它的script功能现写一个加密脚本:

记又一次曲折的集团SQL注入

实现大体是这样,我省去了加解密函数的部分:

from mitmproxy.http import HTTPFlow
from mitmproxy.tools import main


class Counter:
    def request(self, flow: HTTPFlow):
        # 检查请求体是否存在
        if flow.request.content:
            # 尝试解码请求体
            # 对请求体进行正则匹配,找到所有 {.*} 格式的内容
                pattern = r'({.*})'
                matches = re.findall(pattern, flow.request.text)
                for match in matches:
                    # 对每个匹配项进行 AES 加密和 Base64 编码
                    encrypted = encrypt_and_encode(match)
                    # 用加密后的内容替换原始内容
                    flow.request.text = flow.request.text.replace(match, encrypted)

    def response(self, flow: HTTPFlow):
        if flow.response.status_code != 200:
            return
        response = flow.response  # 获取响应对象

addons = [
    Counter()
]

然后命令行启动mitmproxy,作为添加脚本的中间代理,这里使用no-web便于观察:

mitmproxy -s 100.py -p 8009 --mode reverse:http://localhost:8080 --no-web

sqlmap这里设置代理到mitmproxy即可。

5 | away from %25

代理挂上了,sqlmap跑起来,喝杯奶茶的功夫发现跑好了:

记又一次曲折的集团SQL注入

这波主打一个兴奋呐,下班近在眼前,这还不跑个dbs然后甩给客户下班?
但理想很丰满,现实很骨感,敲命令半天连个当前用户都跑不出来。遇到这种情况第一反应还是有拦截或者WAF(WAF99%可以排除,都加密成狗屎了),还好笔者跑sqlmap一般都是会代到bp留一个存档的。于是回头查看bp的记录,看上去倒是没什么问题:

记又一次曲折的集团SQL注入

再仔细看了一遍,才发现问题:

记又一次曲折的集团SQL注入

毕竟加密之前是json,而sqlmap老喜欢往包里扔各种双引号。不过这种情况我也不是第一次碰见,使用--no-escape就行。实在不放心再写个小tamper:

#from lib.core.enums import PRIORITY

def dependencies():
    pass

def tamper(payload, **kwargs):
    return payload.replace("`","'").replace('"',"'")

扔上tamper,--flush再跑一次:

记又一次曲折的集团SQL注入

这次跑出来的结果就能出数据了,向客户汇报一波成功下班。

. . . * . * 🌟  * . * . . .

由于很多人问我微信群的事情,所以我建了一个小微信群。现在可以在公众号菜单里选择合作交流->交流群获取交流群二维码,希望大家和谐交流,为更好更友善的行业环境贡献自己的力量。

如果喜欢我的文章,请点赞在看。网安技术文章、安卓逆向、渗透测试、吃瓜报道,尽在我的公众号:

原文始发于微信公众号(重生之成为赛博女保安):记又一次曲折的集团SQL注入

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年7月15日11:01:28
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   记又一次曲折的集团SQL注入https://cn-sec.com/archives/2954578.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息