我们一直在努力保持领先的最新趋势,今天我们发现了一个非常有趣的事,这或者是我们之前没有发现,或者是刚发生的。 我们只能说这是新发现的。
我们都了解的iFrame注入攻击,对吧?
了解一个iFrame注入
今天的iFrame 是非常标准的HTML标记,它是在自己网页中嵌入其他网站内容的简单方式。 被几乎所有的浏览器支持和百万计的网站使用,使用AdSense吗? 那么你的网站中就有一个iFrame。
我知道这东西很好,然而总是福祸相惜。
今天的攻击,特别是当我们谈论路过式下载,首选是利用IFRAME标记。 它简单方便,只需简单的属性修改,攻击者可以稳妥的从另一个站点嵌入代码,并通过客户的浏览器不知不觉的加载。
像这样:
攻击者通常从其他网站嵌入的恶意文件,通常是一个PHP文件或类似的形式。 当然,这并不是唯一的方法,但是是最普遍的。 从检测和修复的角度来看,这往往很容易修复。
新的iFrame注入法
然而今天,我们发现一个有趣的iFrame注入类型。
它的特殊之处不是在iframe标签中嵌入的内容,而是它分发恶意软件的方式。 你会看到,攻击者将威胁隐藏在PNG文件中。
我几乎可以听到很多你的窃笑,PFF .. 这不是新的…. 但问题是在细节上我的朋友。
如下,iFrame加载了一个有效的文件,没有什么恶意,一个叫jquery.js的JavaScript文件。这一切看上去都很好。你要细细的找:
起初,很多人会说我们傻。 这些代码很好,没看见什么问题,对不对? 然后,我们注意到了这个小函数,loadFile()。 函数本身并不奇怪,但事实上,它是装载一个PNG-var strFile = ‘./dron.png。 你会被它惊讶良久,它才是一个真正的黑手。
自然,下一步就是好奇的打开dron.png文件。 会有什么可怕的事情发生吗?
噢,什么都没有,太无聊了,这纯粹是浪费时间。
但是,请等一下,我发现这里有个有趣的小循环。
嗯,这是确实挺奇怪的,这是一个解码循环。 为什么要一个循环的解码PNG文件呢?
作为一个优秀的研究人员,采取最简单的方式,我可以将它加载到简单的测试页上 并提取图像内容。搞定!
测试页上加载它之后这,我们获得了strData变量:
看到它在干嘛了吗?
它做了个iFrame注入,并把它嵌入到PNG的元数据中,像一个新的分配机制。
有两点需要特别注意了,它使用createElement做了一个iFrame标签,然后设置elm.style.position.left 和 elm.style.position.top 属性的值为-1000px,把iframe放到可视区域之外。这些值都是负值,在浏览器中根本看不到。但是你知道谁能看到吗?只有浏览器和Google能看到。这就是下载驱动和搜索引擎感染(SEP)攻击的小伎俩。
最后我们在elm.src元素中发现了真正的威胁。
做的这么独特到底有什么用呢?
它尽力隐藏真正的威胁的水平是独特的。现在的杀毒软件不会解码图像元数据,直到JavaScript文件加载完毕就停止扫描。不会追踪cookie文件,对于攻击者来说,这太好了,使它们很难被发现。
记住一点,尽管我们这里谈论的是PNG文件,这些方法和概念也可以应用到其他类型图像中。重要的一点是:留意你的web 服务状态,了解哪些修改和未修改的文件并确保漏洞未被利用。
通常情况下,一些新的侦查和排障需要一定的时间。 现在我们的 网站恶意软件扫描器能发现它吗 ? 绝对可以!
.user.ini简单的说就是php除默认配置文件php.ini外的另额外的可以放在网站目录下的配置文件,本文我们来看看.user.ini文件的PHP后门及防范。背景
这个估计很多同学看了不屑,认为是烂大街的东西了:
.htaccess文件构成的PHP后门,那么我来个新的吧:.user.ini。它比.htaccess用的更广,不管是 nginx/apache/IIS,只要是以fastcgi运行的php都可以用这个方法。我的nginx服务器全部是fpm/fastcgi,我的 IIS php5.3以上的全部用的fastcgi/cgi,我win下的apache上也用的fcgi,可谓很广,不像.htaccess有局限性。
.user.ini
那么什么是.user.ini?
这得从php.ini说起了。php.ini是php默认的配置文件,其中包括了很多php的配置,这些配置中,又分为几种:PHP_INI_SYSTEM、PHP_INI_PERDIR、PHP_INI_ALL、PHP_INI_USER。 在此可以查看:http://php.net/manual/zh/ini.list.php 这几种模式有什么区别?看看官方的解释:
其中就提到了,模式为PHP_INI_USER的配置项,可以在ini_set()函数中设置、注册表中设置,再就是.user.ini中设置。 这里就提到了.user.ini,那么这是个什么配置文件?那么官方文档在这里又解释了:
除了主 php.ini 之外,PHP 还会在每个目录下扫描 INI 文件,从被执行的 PHP 文件所在目录开始一直上升到 web 根目录($_SERVER['DOCUMENT_ROOT'] 所指定的)。如果被执行的 PHP 文件在 web 根目录之外,则只扫描该目录。
在 .user.ini 风格的 INI 文件中只有具有 PHP_INI_PERDIR 和 PHP_INI_USER 模式的 INI 设置可被识别。
这里就很清楚了,.user.ini实际上就是一个可以由用户“自定义”的php.ini,我们能够自定义的设置是模式为“PHP_INI_PERDIR 、 PHP_INI_USER”的设置。(上面表格中没有提到的PHP_INI_PERDIR也可以在.user.ini中设置)
实际上,除了PHP_INI_SYSTEM以外的模式(包括PHP_INI_ALL)都是可以通过.user.ini来设置的。
而且,和php.ini不同的是,.user.ini是一个能被动态加载的ini文件。也就是说我修改了.user.ini后,不需要重启服务器中间件,只需要等待user_ini.cache_ttl所设置的时间(默认为300秒),即可被重新加载。
然后我们看到php.ini中的配置项,可惜我沮丧地发现,只要稍微敏感的配置项,都是PHP_INI_SYSTEM模式的(甚至是php.ini only的),包括disable_functions、extension_dir、enable_dl等。 不过,我们可以很容易地借助.user.ini文件来构造一个“后门”。
Php配置项中有两个比较有意思的项(下图第一、四个):
auto_append_file、auto_prepend_file,点开看看什么意思:
指定一个文件,自动包含在要执行的文件前,类似于在文件前调用了require()函数。而auto_append_file类似,只是在文件后面包含。 使用方法很简单,直接写在.user.ini中:
12auto_prepend_file=01.gif
01.gif是要包含的文件。
所以,我们可以借助.user.ini轻松让所有php文件都“自动”包含某个文件,而这个文件可以是一个正常php文件,也可以是一个包含一句话的webshell。
测试一下,我分别在IIS6.0+Fastcgi+PHP5.3和nginx+fpm+php5.3上测试。 目录下有.user.ini,和包含webshell的01.gif,和正常php文件echo.php:
访问echo.php即可看到后门:
Nginx下同样:
那么,我们可以猥琐地想一下,在哪些情况下可以用到这个姿势? 比如,某网站限制不允许上传.php文件,你便可以上传一个.user.ini,再上传一个图片马,包含起来进行getshell。不过前提是含有.user.ini的文件夹下需要有正常的php文件,否则也不能包含了。 再比如,你只是想隐藏个后门,这个方式是最方便的。
加密php文件对于一些重要的非开源程序都会这样做了,而加密php程序官方有提供一个Zend工具了,下面我们来给各位介绍Zend加密php文件的操作步骤.安装破解版的Zend Guard 6.0软件之后,博主Jhonse哥就尝试给php文件加密。
第一步: 打开Zend Guard 6.0软件
验证码通常是用来安全保证我们网站注册或登录不被注入的,但为了更安全我们通常会生成一些混合验证码了,下面一起来看看例子.
在我们开发登录模块或者是论坛的灌水模块的时候,为了防止恶意提交,需要用到验证码。验证码就是用来区分人和机器的一种手段,当然这种手段不是万无一失,但总归会起到一些作用。
验证码的实现需要GD库的支持,没有开启GD库的童鞋需开启GD库。
其实验证码的制作和使用非常的简单,仅仅只是需要4个步骤就可以搞定:创建验证码底图,显示验证码内容,增加干扰元素,输出验证码。下面我们来进行步骤拆分:
第一步:创建验证码底图
$image = imagecreatetruecolor(100, 30); // 创建一个宽为 100 高为 30 的底图 该底图的背景色 为黑色 是系统定义的
$bgcolor = imagecolorallocate($image, 255, 255, 255); // 为上面创建的底图分配 白色的背景颜色
imagefill($image, 0, 0, $bgcolor); // 填充白色背景色
第二步:显示验证码内容
// 输出验证码内容
for ($i=0; $i < 4; $i++) {
$fontsize = 6;
$fontcolor = imagecolorallocate($image, rand(0,120), rand(0,120), rand(0,120));
$data = 'qwertyuipkjhgfdsazxcvbnm23456789';
$content = substr($data, rand(0, strlen($data)), 1);
$x = ($i*100/4) + rand(5,9);
$y = rand(5,10);
imagestring($image, $fontsize, $x, $y, $content, $fontcolor); //在图像上水平输出一行字符串
}
第三步:增加干扰元素
// 增加干扰点元素
for ($i=0; $i < 300; $i++) {
$pointcolor = imagecolorallocate($image, rand(50,200), rand(50,200), rand(50,200));
imagesetpixel($image, rand(0,99), rand(0,29), $pointcolor);
}
// 增加干扰线元素 线 和 点 的颜色一定要控制好 要比验证码数字的颜色浅 避免出现验证码数字看不见的现象
for ($i=0; $i < 4; $i++) {
$linecolor = imagecolorallocate($image, rand(100,240), rand(100,240), rand(100,240));
imageline($image, rand(0,99), rand(0,29), rand(0,99), rand(0,29), $linecolor);
}
第四步:输出验证码
// 输出创建的图像 在输出图像之前 必须输出头信息 用来规定输出的图像类型
header("Content-Type: image/png");
imagepng($image);
// 销毁图像
imagedestroy($image);
至此,一个简单的验证码就实现了,关于实现验证码的注意事项已经写在了注释里。
使用验证码的时候,我们一般都需要用session来保存以便验证,在这里就不作详细介绍。
我们只要查看开源的程序几乎都会有下面两段差不多相关的代码,代码的功能就是过滤提交数据中的一些特殊字符了,通常是有post与get了,下面来看看吧.
/**
* 递归方式的对变量中的特殊字符进行转义
*
* @access public
* @param mix $value
*
* @return mix
*/
function addslashes_deep($value)
{
if (empty($value))
{
return $value;
}
else
{
return is_array($value) ? array_map('addslashes_deep', $value) : addslashes($value);
}
}
使用:
/* 对用户传入的变量进行转义操作。*/
if (!get_magic_quotes_gpc())
{
if (!empty($_GET))
{
$_GET = addslashes_deep($_GET);
}
if (!empty($_POST))
{
$_POST = addslashes_deep($_POST);
}
$_COOKIE = addslashes_deep($_COOKIE);
$_REQUEST = addslashes_deep($_REQUEST);
}