Skip to content

As we know, modsecurity is a WAF for resolving Raw Packets. But in many cases, especially in the cloud environment, we also need modsecurity to have the ability to detect the risk of certain logs.

License

Notifications You must be signed in to change notification settings

Microflow-IO/modsecurity-for-anylog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

logo

ModSecurity for Anylog

🎬Background

In cloud and cloud-native environments, how to achieve application-level lateral movement attack detection, and sensitive data abnormal behavior warning, without affecting the environment and business, without blind spots, is two difficulties in the industry;

🛠Resolvent

ModSecurity is a famous WAF engine, but the original version of ModSecurity can only detect Raw Packet, which is usually only used for traditional architecture and cloud boundary security;

Nano Probe can obtain fine-grained traffic logs inside cloud and cloud-native environments in an ultra-lightweight way;

If we modify ModSecurity to analyze the HTTP fine-grained logs output by Nano, we can, in principle, fully leverage ModSecurity's detection capabilities to detect various application-level lateral movement attacks and sensitive data behavior anomalies within the cloud and cloud-native environments.

📠MSA Introduction

ModSecurity for Anylog (hereinafter referred to as MSA) is based on the above background and method.

It is a modified version of ModSecurity for all application logs. It can not only analyze JSON logs from Nano probes, but also enable attack detection on any application and business logs through user configuration.

lateral movement attack detection architecture

graph TB  
    subgraph "Cloud and Cloud-Native"  
        VM1["Virtual Machine 1 (with Nano)"]  
        VM2["Virtual Machine 2 (with Nano)"]  
        Node1["Node 1 (with Nano Pod)"]  
        Node2["Node 2 (with Nano Pod)"]  
    end  

    Middleware["Logstash/Fluentd"]  
    MSA["ModSecurity for Anylog (MSA)"]  
    AnalyticsPlatform["Data Analytics Platform / SOC"]  

    VM1 -.->|"JSON over UDP"| Middleware  
    VM2 -.->|"JSON over UDP"| Middleware  
    Node1 -.->|"JSON over UDP"| Middleware  
    Node2 -.->|"JSON over UDP"| Middleware  

    Middleware -.->|"JSON Data"| AnalyticsPlatform  
    Middleware -.->|"JSON Data"| MSA  

    MSA -.->|"Alerts (Syslog)"| AnalyticsPlatform  

    classDef vm fill:#e1f5fe,stroke:#01579b,stroke-width:2px;  
    classDef node fill:#e8f5e9,stroke:#1b5e20,stroke-width:2px;  
    classDef middleware fill:#fff3e0,stroke:#e65100,stroke-width:2px;  
    classDef msa fill:#fce4ec,stroke:#880e4f,stroke-width:2px;  
    classDef analytics fill:#f3e5f5,stroke:#4a148c,stroke-width:2px;  

    class VM1,VM2 vm;  
    class Node1,Node2 node;  
    class Middleware middleware;  
    class MSA msa;  
    class AnalyticsPlatform analytics;
Loading

🤷‍♂️How to Use?

Clone the code

[root@racknerd-b20bda0 ~]# git clone https://github.com/Microflow-IO/modsecurity-for-anylog
Cloning into 'modsecurity-for-anylog'...
remote: Enumerating objects: 66, done.
remote: Counting objects: 100% (66/66), done.
remote: Compressing objects: 100% (49/49), done.
remote: Total 66 (delta 15), reused 63 (delta 15), pack-reused 0 (from 0)
Unpacking objects: 100% (66/66), done.

Modify the LISTEN_PORT and OUTPUT environment variables according to your situation. Here, LISTEN_PORT is the JSON port for GELF format input, and OUTPUT is the JSON output port for alerts, both carried over UDP.

[root@racknerd-b20bda0 ~]# cd modsecurity-for-anylog/
[root@racknerd-b20bda0 modsecurity-for-anylog]# ls
docker-compose.yml  LICENSE  modsecurity
[root@racknerd-b20bda0 modsecurity-for-anylog]# cat docker-compose.yml | grep env -A 4
    environment:
      LISTEN_PORT: 15155
      OUTPUT: 127.0.0.1:12201
      RULEPATH: /usr/local/openresty/nginx/conf/modsecurity/modsecurity.conf

Use docker compose up -d to start the container

[root@racknerd-b20bda0 modsecurity-for-anylog]# docker compose up -d
[+] Running 2/2
 ✔ Network modsecurity-for-anylog_default  Created                                   0.3s 
 ✔ Container uniwaf                        Started                                   0.4s 
[root@racknerd-b20bda0 modsecurity-for-anylog]# docker ps | grep uniwaf
82a5bbb5f1ee   registry.jxit.net.cn:5000/uniserver/uniwaf:git-25     "sh -xc 'uniwaf -a -…"   12 seconds ago   Up 11 seconds                                               uniwaf

modsecurity directory stores alert rule files and maps to /usr/local/openresty/nginx/conf/modsecurity/ in the container.

[root@racknerd-b20bda0 modsecurity-for-anylog]# ls modsecurity/
crs-setup.conf  makefile.test  modsecurity.conf  rules  unicode.mapping  
[root@racknerd-b20bda0 modsecurity-for-anylog]# ls modsecurity/rules/
crawlers-user-agents.data                        REQUEST-931-APPLICATION-ATTACK-RFI.conf
iis-errors.data                                  REQUEST-932-APPLICATION-ATTACK-RCE.conf

You can modify rule files in modsecurity/rules, restart the container for changes

[root@racknerd-b20bda0 modsecurity-for-anylog]# docker compose restart
[+] Restarting 1/1
 ✔ Container uniwaf  Started                                               10.5s

Enter container check test data and script, sending test-uniwaf.json to port 15155 once per second

[root@racknerd-b20bda0 ~]# docker exec -it uniwaf sh
/ # cd /usr/local/openresty/nginx/conf/modsecurity/
/usr/local/openresty/nginx/conf/modsecurity # ls
test.sh            uniwaf-proxy.conf test-uniwaf.json   unicode.mapping
/usr/local/openresty/nginx/conf/modsecurity # cat test-uniwaf.json 
{"BEGIN_TIME":"2024-05-30 07:16:48.917","END_TIME":"2024-05-30 07:16:48.918","PROBE_VER":"20240527-128","host":"10.64.1.254","SYSTEM":"Ubuntu 22.04.3","SRC_IP":"192.168.1.105","DST_IP":"192.168.1.55","SRC_PORT":"46152","DST_PORT":"80","NIC":"any","CARD":"br-vmr","CARD_IP":"192.168.1.105","SRC_NET_DELAY":"0.01","DST_NET_DELAY":"0.13","NET_DELAY":"0.14","RST_PKTS":"0","RETRANS_PKTS":"0","BYTES":"1171","HTTP_RESPONSE":"0.792","PAGELOAD":"0.792","RETCODE":"403","METHOD":"GET","URL":"/?t=../../etc/passwd","DOMAIN":"192.168.1.55","FORWARD":"0.0.0.0","AGENT":"curl/7.81.0","REQ_HEADER":"GET /?t=../../etc/passwd HTTP/1.1\r\nHost: 192.168.1.55\r\nUser-Agent: curl/7.81.0\r\nAccept: */*\r\n\r\n","REQ_BODY":"","RSP_HEADER":"HTTP/1.1 403 Forbidden\r\nDate: Thu, 30 May 2024 07:16:49 GMT\r\nContent-Type: text/html; charset=UTF-8\r\nTransfer-Encoding: chunked\r\nConnection: keep-alive\r\nserver: ZhongKui WAF\r\n\r\n","RSP_BODY":"223sdfalkjsflkajf","L7_PROTOCOL":"http","L4_PROTOCOL":"tcp","message":"jxit","message-type":"comm","gl2_source_collector":"64210464315174928","DISK_RATIO":"46.73","TOTAL_CPU":"4","LICENSE":"Only for POC"}
/usr/local/openresty/nginx/conf/modsecurity # cat test.sh 
#!/bin/sh

while true; do 
  timeout 1 nc -u 127.0.0.1 15155 < test-uniwaf.json 
  sleep 1
done

Start the script and use tcpdump to grab the 12201 alarm output port packet

/usr/local/openresty/nginx/conf/modsecurity # nohup ./test.sh &
/usr/local/openresty/nginx/conf/modsecurity # nohup: appending output to nohup.out
/usr/local/openresty/nginx/conf/modsecurity # 
/usr/local/openresty/nginx/conf/modsecurity # timeout 5 tcpdump -i lo port 12201 -w a.pcap
tcpdump: listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
2 packets captured
6 packets received by filter

Open the packet file to verify the alarm generated by the attack

/usr/local/openresty/nginx/conf/modsecurity # cat a.pcap 
{"rule_id":"932160","alert_engine":"modsecurity","time":"2024-05-30 07:16:48","message":"jxit","forward":"0.0.0.0","retcode":"403","source":"","src_ip":"192.168.1.105","dst_ip":"192.168.1.55","geoip":"","src_port":"46152","dst_port":"80","host":"10.64.1.254","domain":"192.168.1.55","url":"/?t=../../etc/passwd","method":"GET","msg":"Remote command execution: Discover Unix Shell code","matched":"Matched \"Operator `PmFromFile' with parameter `unix-shell.data' against variable `ARGS:t' (Value: `../../etc/passwd' )","severity":"2","req_header":"GET /?t=../../etc/passwd HTTP/1.1\r\nHost: 192.168.1.55\r\nUser-Agent: curl/7.81.0\r\nAccept: */*\r\n\r\n","req_body":"","rsp_header":"HTTP/1.1 403 Forbidden\r\nDate: Thu, 30 May 2024 07:16:49 GMT\r\nContent-Type: text/html; charset=UTF-8\r\nTransfer-Encoding: chunked\r\nConnection: keep-alive\r\nserver: ZhongKui WAF\r\n\r\n","rsp_body":"223sdfalkjsflkajf"}

About

As we know, modsecurity is a WAF for resolving Raw Packets. But in many cases, especially in the cloud environment, we also need modsecurity to have the ability to detect the risk of certain logs.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages