分类目录归档:网络安全

nginx防止webshell窥探任意目录

webshell作为一种服务器端解析脚本,它的破坏力极为惊人。服务器在设置不当的情况下非常容易被提权,从而拿到服务器权限。回想十多年前老徐作为一名脚本小子,也曾拿下过不少站点服务器权限,所以在信息安全这一块老徐尤为谨慎。本篇主要介绍一下我是如何设置nginx从而防止webshell窥探任意目录。

nginx配置

fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  REQUEST_SCHEME     $scheme;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;
fastcgi_param  PHP_VALUE  "open_basedir=$document_root:/tmp/:/proc/";

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;

重点关注这一行fastcgi_param PHP_VALUE "open_basedir=$document_root:/tmp/:/proc/";

这行语句表示当前站点的PHP脚本只能够访问$document_root 、/tmp/ 、/proc/ ,这三个目录。

$document_root变量表示我们nginx配置中server块root指令定义的目录。

建议

如果你正在搭建一个php服务器环境,不防从github找一个webshell放在web根目录,利用webshell功能来调优web服务器的安全性,直到webshell什么都干不了。

最后

如果你是一名运维工程师或者是站长,那么你应该将服务器的安全放在首要位置,不要让自己的努力瞬间化为灰烬。

使用ipset来增强你的防火墙

这几天陆续白嫖了几台甲骨文服务器,替你们薅了几把资本主义羊毛。然后就开始着手折腾服务器防火墙的事宜,主要目的是防GWF毕竟访问的人多越容易被察觉。

安装ipset

yum -y install ipset

创建ipset库

ipset create blanklist hash:ip timeout 86400

上面语句表示创建了一个blanklist库,插入到该库的ip将在86400秒后自动删除。

至于更加深入研究需要自行去探索,搜索关键词:iptables ipset 自动过期 解封

创建防火墙规则

iptables -I INPUT -m comment --comment "黑名单" -m set --match-set blanklist src -j DROP
service iptables save
systemctl reload iptables

上面的语句表示入站方向命中黑名单则丢弃数据包,紧跟其后的语句表示持久化当前iptables规则然后重新加载iptables规则。

iptables视乎对规则有着严格的顺序要求,iptables有着非常复杂的语法规则老徐玩的也不是非常溜,目前只在自己的服务器上能保证命中黑名单就阻断。

老徐在自己的国内服务器部署了Hfish蜜罐系统,结合蜜罐系统提供的数据接口使用Python脚本将IP写入ipset黑名单库即可实现自动拦截恶意端口扫描、若口令攻击等简单的安全需求。

当然老徐只建议一般的个人开发者或者小站长自己拿来玩儿的服务器可以这么干,我们大中华局域网IPv4资源有限,封禁一个公网IP也许一个小区都访问不了你的企业网站,如果你是某企业的运维或安全我权当你没来过。

Python脚本

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import datetime
import json
import os
import time

import requests


def main():
    ip_list = get_ip_list()
    # 创建ipset
    shell("ipset create hfish hash:ip timeout %s -exist" % 86400)
    for ip in ip_list:
        # 将IP添加到ipset
        shell("ipset add hfish -exist %s 2>&1" % ip)


def get_ip_list():
    """
    获取外网攻击IP列表

    :return: IP列表
    """
    url = "https://hfish.tool.xuchengen.cn/api/v1/attack/ip?" \
          "api_key=UperCSJpoxLqGvLCFqbbkNUEuwaLAGTdJKHtMtjLchpaxNoJfoYDPpdrUUKyVqni"

    payload = json.dumps({
        "start_time": get_start_time(),
        "end_time": get_end_time(),
        "intranet": 0
    })

    headers = {
        'Content-Type': 'application/json'
    }

    response = requests.request("POST", url, headers=headers, data=payload)
    obj = json.loads(response.text)

    if obj["response_code"] == 0:
        return obj["data"]["attack_ip"]

    return list()


def shell(cmd: str) -> str:
    """
    执行shell脚本

    :param cmd: 命令字符串
    :return: 命令执行后响应的字符串
    """

    stdout = os.popen(cmd)
    with stdout as stdout_:
        result: str = str().join(stdout_.readlines())

    return result


def get_start_time():
    """
    获取开始时间戳

    :return: 开始时间戳
    """
    today = datetime.date.today()
    return int(time.mktime(time.strptime(str(today), '%Y-%m-%d'))) - 1


def get_end_time():
    """
    获取结束时间戳

    :return: 结束时间戳
    """
    today = datetime.date.today()
    tomorrow = today + datetime.timedelta(days=1)
    return int(time.mktime(time.strptime(str(tomorrow), '%Y-%m-%d'))) - 1


if __name__ == '__main__':
    main()

上面的Python脚本内置了老徐自己搭建的Hfish蜜罐系统接口,如果你跟老徐一样都是腾讯云北京机房恰巧跟我处于同一IP段那不防试一试,也许能防范不少恶意端口扫描以及弱口令攻击。

对了别忘了把Python脚本加入crontable,建议一分钟一次。

使用Docker搭建HFish蜜罐陷阱

几个星期以前我试着使用Docker搭建了一套基于HFish的蜜罐系统,从现有掌握的数据来看主要的攻击来自境外也许攻击者们对北京地区的机房比较感兴趣,绝大多数的攻击都是ssh弱口令扫描。我搭建这套蜜罐系统需求是收集弱口令字典以及将恶意IP通过web hook加入到iptables中。

HFish

HFish是一款安全、简单可信赖的跨平台蜜罐软件,允许商业和个人用户免费使用。

特点

安全可靠:主打低中交互蜜罐,简单有效;

蜜罐丰富:支持SSH、FTP、TFTP、MySQL、Redis、Telnet、VNC、Memcache、Elasticsearch、Wordpress、OA系统等10多种蜜罐服务,支持用户制作自定义Web蜜罐;

开放透明:支持对接微步在线X社区API、五路syslog输出、支持邮件、钉钉、企业威胁、飞书、自定义WebHook告警输出;

快捷管理:支持单个安装包批量部署,支持批量修改端口和服务;

跨平台:支持Linux x32/x64/ARM、Windows x32/x64平台;

架构

HFish由控制端和节点端组成,控制端用来生成和管理节点端,并接收、分析和展示节点端回传的数据,节点端接受控制端的控制并负责构建蜜罐服务。

基于Docker容器搭建HFish

建议将自己服务器上已安装的SSH、Mysql、FTP等服务端口号改为10000端口以上,保证不跟HFish冲突。

端口说明

21为FTP端口
22为SSH端口
23为Telnet端口
69为TFTP端口
3306为Mysql端口
5900为VNC端口
6379为Redis端口
8080为暗网端口
8081为HTTP代理池端口
8989为插件端口
9000为Web端口
9001为系统管理后台端口
9200为Elasticsearch端口
11211为Memcache端口

创建volume卷

docker volume create hfish_data

部署容器

默认帐号密码均为:admin

docker run -itd \
--name hfish \
-p 21:21 \
-p 22:22 \
-p 23:23 \
-p 69:69 \
-p 3306:3306 \
-p 5900:5900 \
-p 6379:6379 \
-p 8080:8080 \
-p 8081:8081 \
-p 8989:8989 \
-p 9000:9000 \
-p 9001:9001 \
-p 9200:9200 \
-p 11211:11211 \
-v hfish_data:/opt
--restart=always \
imdevops/hfish:latest

添加防火墙规则

iptables -t nat -A POSTROUTING -m addrtype --src-type LOCAL -o docker0 -j MASQUERADE
service iptables save

数据大屏

这个数据大屏看起来挺唬人但是有个Bug,在右上角的时间以及中间列表区域的攻击时间与真实时间不一致。

使用fail2ban保护您的服务器

一直以来我的服务器经常被一群脚本小子非法扫描很是令人讨厌,比较万幸的是经过我细心照料也从来没有被成功攻破,这得益于从业多年小心谨慎的态度保障了服务器的安全运行。

什么是Fail2ban

Fail2Ban是一个入侵检测系统框架,它可以保护电脑服务器免受蛮力攻击。以Python程式设计语言编写,并能够在类Unix系统上运行,这些系统具有本地安装的封包控制系统或防火墙的界面,例如Iptables或TCP Wrapper。

1、Fail2ban 跟 DenyHosts是类似的工具,可以阻挡有人恶意以字典暴力破解密码,通常应用于有开启 sshd、telnetd跟ftpd的主机上。

2、Fail2ban 的做法是将超过多次失败连线的 IP 列用 iptables(给IPv4 使用) 或 ip6tables (给IPv6使用)禁止该 IP之后的连线。

3、至于要多久之后可以再允许该 IP 再次连线可以在 Fail2ban 的设定档案内设定。

安装Fail2ban

yum -y install fail2ban

配置Fail2ban

建议将SSH端口设置在10000端口以上,这样做的好处是可以规避掉绝大多数的暴力破解

Fail2ban配置文件我这里是统一写在/etc/fail2ban/jail.local文件中

[DEFAULT]
# 禁止一周
bantime = 604800
# 忽略的IP段
ignoreip = 127.0.0.1/8 172.21.0.0/16
# 禁止动作
banaction = iptables-allports

[ssh]
enabled = true
port = 22
filter = sshd
logpath = %(sshd_log)s
findtime = 259200
maxretry = 2

[nginx-botsearch]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
logencoding = utf-8
maxretry = 2

[nginx-http-auth]
enabled = true
port = http,https
logpath = /var/log/nginx/error.log
logencoding = utf-8
maxretry = 2

[mysqld-auth]
enabled = true
filter = mysqld-auth
port = 3306
logpath = /var/log/mysqld.log
logencoding = utf-8
findtime = 259200
maxretry = 2

基本命令解释

fail2ban-client -h           命令帮助

fail2ban-client stauts    查看配置状态

fail2ban-client status ssh        查看ssh配置状态

fail2ban-client unbanip {ip}    解封某个IP

Fail2ban演示

这里展示一下Fail2ban拦截到恶意爆破mysql密码被成功禁止的IP

[root@xuchengen ~]# fail2ban-client status mysqld-auth
Status for the jail: mysqld-auth
|- Filter
|  |- Currently failed: 0
|  |- Total failed:     294
|  `- File list:        /var/log/mysqld.log
`- Actions
   |- Currently banned: 7
   |- Total banned:     8
   `- Banned IP list:   34.79.107.251 5.188.206.5 5.188.206.4 5.188.206.6 34.79.68.246 5.188.206.3 5.188.206.2

 

Centos7释放Journal产生的日志文件

坦率的讲徐叔有好几台服务器国内几台阿里云,美国也有几台。奈何磁盘都只有可怜兮兮的40G好在都是SSD磁盘。精打细算网站上的图片都不敢放高清的,视频压根就不敢放。最近巡查发现磁盘突然暴涨了好几个G的磁盘占用经过排查主要都是由Jorunal生成的日志所导致。

从Centos7开始使用的systemd使用了journal日志,这个日志的管理方式和以往使用syslog的方式不同,可以通过管理工具维护。

使用df -h检查磁盘文件,可以看到/run目录下有日志目录/run/log/journal,占用了数G空间。

Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root  8.5G  4.2G  4.4G  49% /
tmpfs                     16G  1.6G   15G  11% /run

在日志目录下有很多历史累积的日志。

检查当前journal使用磁盘量

journalctl --disk-usage

清理方法可以采用按照日期清理,或者按照允许保留的容量清理

journalctl --vacuum-time=2d
journalctl --vacuum-size=500M

如果要手工删除日志文件,则在删除前需要先轮转一次journal日志

systemctl kill --kill-who=main --signal=SIGUSR2 systemd-journald.service

要启用日志限制持久化配置,可以修改 /etc/systemd/journald.conf

SystemMaxUse=16M
ForwardToSyslog=no

重启

systemctl restart systemd-journald.service

检查journal是否运行正常以及日志文件是否完整无损坏

journalctl --verify

参考

How to clear journalctl

Is it safe to delete /var/log/journal log files?

社工库搭建

社工库想必大家伙都懂!

一、技术选型 

Elasticsearch + javaWeb

社工库主要用来检索用户数据,数据量一般在数十亿甚至数百亿,只有写入(导入)和查询,写入次数少,查询次数多,频率高。

与数据库比起来,es支持的数据量更大,更方便水平扩展,天生高可用,检索更快(实际测试5亿数据毫秒级响应),各原始数据的导入更方便。

对于前端交互用java或者python或者php本质上没有多少区别,比较社工库的用户量不大,前端开发工作量也不大。

继续阅读

自编译Nginx伪装Server版本信息

Nginx (“engine x”) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器。Nginx是由Igor Sysoev为俄罗斯访问量第二的Rambler.ru站点开发的,第一个公开版本0.1.0发布于2004年10月4日。其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。本篇文章徐叔介绍如何伪装你的Nginx让脚本小子摸不着头脑。:)

一、前期准备

1.Centos7环境。

2.Nginx安装包建议下载稳定版(Stable version),本篇以1.10.2为例子。

3.确认系统中是否已安装gcc、openssl-devel、pcre-devel、zlib-devel。

yum -y install gcc openssl-devel pcre-devel zlib-devel

二、修改相关变量

1.目标文件路径src/core/nginx.h修改后如下:

/*
 * Copyright (C) Igor Sysoev
 * Copyright (C) Nginx, Inc.
 */


#ifndef _NGINX_H_INCLUDED_
#define _NGINX_H_INCLUDED_


#define nginx_version      1010002
#define NGINX_VERSION      "1.10.2"
#define NGINX_VER          "apple/" NGINX_VERSION

#ifdef NGX_BUILD
#define NGINX_VER_BUILD    NGINX_VER " (" NGX_BUILD ")"
#else
#define NGINX_VER_BUILD    NGINX_VER
#endif

#define NGINX_VAR          "APPLE"
#define NGX_OLDPID_EXT     ".oldbin"


#endif /* _NGINX_H_INCLUDED_ */

继续阅读

XSS攻击的简单防御

XSS(Cross Site Scripting)跨站脚本攻击,恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页之时,嵌入其中Web里面的Script代码会被执行,从而达到恶意攻击用户的目的。

方案一

主要是利用了 SpringMVC 的特性,使用 SpringMVC 内置的方法 defaultHtmlEscape,在 web.xml 中配置上 context-param,然后在 Form 中加入 spring 的标签,具体配置如下。

<context-param>  
   <param-name>defaultHtmlEscape</param-name>  
   <param-value>true</param-value>  
</context-param>

<spring:htmlEscape defaultHtmlEscape="true" />

继续阅读