Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

crowdsecurity/http-bf-wordpress_bf is bypassed when using NGINX Reverse Proxy #861

Open
sanvu88 opened this issue Oct 26, 2023 · 3 comments

Comments

@sanvu88
Copy link

sanvu88 commented Oct 26, 2023

File: http-bf-wordpress_bf.yaml

When using NGINX Reverse Proxy, users only need to create a post method to a link like http://example.com/wp-login.php/ to bypass /http-bf-wordpress_bf. Because the link ends with /, file_name will be empty. Currently my solution is to create a filter like this:

filter: 'evt.Meta.log_type == "http_access-log" && evt.Meta.http_path contains "wp-login.php" && evt.Parsed.verb == "POST" && evt.Meta.http_status in ["200", "301", "302", "307"]'

@LaurenceJJones
Copy link
Contributor

Are you directly just proxying passing it to the applications or doing any regex matching?

@sanvu88
Copy link
Author

sanvu88 commented Oct 31, 2023

Are you directly just proxying passing it to the applications or doing any regex matching?

I'm not. It seems Nginx will automatically remove the / at the end and do a 302 redirect to wp-login.php causing the filter to be bypassed.

@LaurenceJJones
Copy link
Contributor

LaurenceJJones commented Oct 31, 2023

Just quick test (From my tests both dont care about trailing slash)

Compose

services:
  nginx:
    image: nginx:alpine
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 80:80
  db:
    # We use a mariadb image which supports both amd64 & arm64 architecture
    image: mariadb:10.6.4-focal
    # If you really want to use MySQL, uncomment the following line
    #image: mysql:8.0.27
    command: '--default-authentication-plugin=mysql_native_password'
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=somewordpress
      - MYSQL_DATABASE=wordpress
      - MYSQL_USER=wordpress
      - MYSQL_PASSWORD=wordpress
  wordpress:
    image: wordpress:latest
    volumes:
      - wp_data:/var/www/html
    restart: always
    environment:
      - WORDPRESS_DB_HOST=db
      - WORDPRESS_DB_USER=wordpress
      - WORDPRESS_DB_PASSWORD=wordpress
      - WORDPRESS_DB_NAME=wordpress
volumes:
  db_data:
  wp_data:

nginx.conf

worker_processes 1;
  
events { worker_connections 1024; }

http {

    sendfile on;

    upstream docker-app {
        server wordpress:80;
    }

    access_log /var/log/nginx/example.access.log;
    error_log /var/log/nginx/example.error.log;
    
    server {
        listen 80;
 
        location / {
            proxy_pass         http://docker-app;
            proxy_redirect     off;
        }
    }
}

Wordpress logs

root-wordpress-1  | 172.18.0.2 - - [31/Oct/2023:09:30:44 +0000] "GET /wp-login.php HTTP/1.0" 200 2229 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
root-wordpress-1  | 172.18.0.2 - - [31/Oct/2023:09:30:44 +0000] "GET /images/wordpress-logo.svg?ver=20131107 HTTP/1.0" 404 452 "http://docker-app/wp-login.php" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
root-wordpress-1  | 172.18.0.2 - - [31/Oct/2023:09:30:47 +0000] "GET /wp-login.php/ HTTP/1.0" 200 2229 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
root-wordpress-1  | 172.18.0.2 - - [31/Oct/2023:09:30:47 +0000] "GET /images/wordpress-logo.svg?ver=20131107 HTTP/1.0" 404 452 "http://docker-app/wp-login.php/" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"

Wordpress-apache

root-wordpress-1  | 172.18.0.4 - - [31/Oct/2023:09:41:12 +0000] "GET /wp-login.php HTTP/1.0" 200 2229 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
root-wordpress-1  | 172.18.0.4 - - [31/Oct/2023:09:41:12 +0000] "GET /wp-includes/js/zxcvbn-async.min.js?ver=1.0 HTTP/1.0" 200 569 "http://docker-app/wp-login.php" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
root-wordpress-1  | 172.18.0.4 - - [31/Oct/2023:09:41:12 +0000] "GET /images/wordpress-logo.svg?ver=20131107 HTTP/1.0" 404 452 "http://docker-app/wp-login.php" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
root-wordpress-1  | 172.18.0.4 - - [31/Oct/2023:09:41:12 +0000] "GET /favicon.ico HTTP/1.0" 404 452 "http://docker-app/wp-login.php" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
root-wordpress-1  | 172.18.0.4 - - [31/Oct/2023:09:41:14 +0000] "GET /wp-login.php/ HTTP/1.0" 200 2229 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
root-wordpress-1  | 172.18.0.4 - - [31/Oct/2023:09:41:14 +0000] "GET /images/wordpress-logo.svg?ver=20131107 HTTP/1.0" 404 452 "http://docker-app/wp-login.php/" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"

Nginx logs

192.168.121.1 - - [31/Oct/2023:09:30:44 +0000] "GET /wp-login.php HTTP/1.1" 200 1783 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
192.168.121.1 - - [31/Oct/2023:09:30:44 +0000] "GET /images/wordpress-logo.svg?ver=20131107 HTTP/1.1" 404 272 "http://docker-app/wp-login.php" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
192.168.121.1 - - [31/Oct/2023:09:30:47 +0000] "GET /wp-login.php/ HTTP/1.1" 200 1783 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
192.168.121.1 - - [31/Oct/2023:09:30:47 +0000] "GET /images/wordpress-logo.svg?ver=20131107 HTTP/1.1" 404 272 "http://docker-app/wp-login.php/" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"

Futher testing it seems anything starting with /wp-login.php will be treated as valid by the php file

root-wordpress-1  | 172.18.0.4 - - [31/Oct/2023:09:43:59 +0000] "GET /wp-login.php/12312331/123423132 HTTP/1.0" 200 2229 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"

So we should change the filter to be evt.Parsed.request startsWith '/wp-login.php'

Apache2

$ cscli explain --log '172.18.0.4 - - [31/Oct/2023:09:43:59 +0000] "GET /wp-login.php/12312331/123423132 HTTP/1.0" 200 2229 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"' --type apache2 -v
line: 172.18.0.4 - - [31/Oct/2023:09:43:59 +0000] "GET /wp-login.php/12312331/123423132 HTTP/1.0" 200 2229 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
	├ s00-raw
	|	├ 🟢 crowdsecurity/non-syslog (+5 ~8)
	|		├ update evt.ExpectMode : %!s(int=0) -> 1
	|		├ update evt.Stage :  -> s01-parse
	|		├ update evt.Line.Raw :  -> 172.18.0.4 - - [31/Oct/2023:09:43:59 +0000] "GET /wp-login.php/12312331/123423132 HTTP/1.0" 200 2229 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
	|		├ update evt.Line.Src :  -> /tmp/cscli_explain2143585454/cscli_test_tmp.log
	|		├ update evt.Line.Time : 0001-01-01 00:00:00 +0000 UTC -> 2023-10-31 09:46:41.574811939 +0000 UTC
	|		├ create evt.Line.Labels.type : apache2
	|		├ update evt.Line.Process : %!s(bool=false) -> true
	|		├ update evt.Line.Module :  -> file
	|		├ create evt.Parsed.message : 172.18.0.4 - - [31/Oct/2023:09:43:59 +0000] "GET /wp-login.php/12312331/123423132 HTTP/1.0" 200 2229 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
	|		├ create evt.Parsed.program : apache2
	|		├ update evt.Time : 0001-01-01 00:00:00 +0000 UTC -> 2023-10-31 09:46:41.5748735 +0000 UTC
	|		├ create evt.Meta.datasource_type : file
	|		├ create evt.Meta.datasource_path : /tmp/cscli_explain2143585454/cscli_test_tmp.log
	├ s01-parse
	|	└ 🟢 crowdsecurity/apache2-logs (+21 ~2)
	|		└ update evt.Stage : s01-parse -> s02-enrich
	|		└ create evt.Parsed.bytes : 2229
	|		└ create evt.Parsed.rawrequest : 
	|		└ create evt.Parsed.referrer : -
	|		└ create evt.Parsed.response : 200
	|		└ create evt.Parsed.target_fqdn : 
	|		└ create evt.Parsed.auth : -
	|		└ create evt.Parsed.http_user_agent : Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0
	|		└ create evt.Parsed.port : 
	|		└ create evt.Parsed.request : /wp-login.php/12312331/123423132
	|		└ create evt.Parsed.timestamp : 31/Oct/2023:09:43:59 +0000
	|		└ create evt.Parsed.httpversion : 1.0
	|		└ create evt.Parsed.verb : GET
	|		└ create evt.Parsed.clientip : 172.18.0.4
	|		└ create evt.Parsed.ident : -
	|		└ update evt.StrTime :  -> 31/Oct/2023:09:43:59 +0000
	|		└ create evt.Meta.http_path : /wp-login.php/12312331/123423132
	|		└ create evt.Meta.http_user_agent : Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0
	|		└ create evt.Meta.log_type : http_access-log
	|		└ create evt.Meta.service : http
	|		└ create evt.Meta.http_status : 200
	|		└ create evt.Meta.http_verb : GET
	|		└ create evt.Meta.source_ip : 172.18.0.4
	├ s02-enrich
	|	├ 🟢 crowdsecurity/dateparse-enrich (+2 ~2)
	|		├ create evt.Enriched.MarshaledTime : 2023-10-31T09:43:59Z
	|		├ update evt.Time : 2023-10-31 09:46:41.5748735 +0000 UTC -> 2023-10-31 09:43:59 +0000 UTC
	|		├ update evt.MarshaledTime :  -> 2023-10-31T09:43:59Z
	|		├ create evt.Meta.timestamp : 2023-10-31T09:43:59Z
	|	├ 🟢 crowdsecurity/geoip-enrich (+9)
	|		├ create evt.Enriched.Longitude : 0.000000
	|		├ create evt.Enriched.ASNNumber : 0
	|		├ create evt.Enriched.ASNOrg : 
	|		├ create evt.Enriched.ASNumber : 0
	|		├ create evt.Enriched.IsInEU : false
	|		├ create evt.Enriched.IsoCode : 
	|		├ create evt.Enriched.Latitude : 0.000000
	|		├ create evt.Meta.ASNNumber : 0
	|		├ create evt.Meta.IsInEU : false
	|	├ 🟢 crowdsecurity/http-logs (+7)
	|		├ create evt.Parsed.file_dir : /wp-login.php/12312331/
	|		├ create evt.Parsed.impact_completion : true
	|		├ create evt.Parsed.static_ressource : false
	|		├ create evt.Parsed.file_frag : 123423132
	|		├ create evt.Parsed.file_name : 123423132
	|		├ create evt.Parsed.file_ext : 
	|		├ create evt.Meta.http_args_len : 0
	|	├ 🟢 crowdsecurity/jellyfin-whitelist (unchanged)
	|	└ 🟢 crowdsecurity/nextcloud-whitelist (unchanged)
	├-------- parser success 🟢
	├ Scenarios
		└ 🟢 crowdsecurity/http-crawl-non_statics

Nginx logs

$ cscli explain --log '172.18.0.4 - - [31/Oct/2023:09:43:59 +0000] "GET /wp-login.php/12312331/123423132 HTTP/1.0" 200 2229 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"' --type nginx -v
line: 172.18.0.4 - - [31/Oct/2023:09:43:59 +0000] "GET /wp-login.php/12312331/123423132 HTTP/1.0" 200 2229 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
	├ s00-raw
	|	├ 🟢 crowdsecurity/non-syslog (+5 ~8)
	|		├ update evt.ExpectMode : %!s(int=0) -> 1
	|		├ update evt.Stage :  -> s01-parse
	|		├ update evt.Line.Raw :  -> 172.18.0.4 - - [31/Oct/2023:09:43:59 +0000] "GET /wp-login.php/12312331/123423132 HTTP/1.0" 200 2229 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
	|		├ update evt.Line.Src :  -> /tmp/cscli_explain3431606629/cscli_test_tmp.log
	|		├ update evt.Line.Time : 0001-01-01 00:00:00 +0000 UTC -> 2023-10-31 09:47:36.221585572 +0000 UTC
	|		├ create evt.Line.Labels.type : nginx
	|		├ update evt.Line.Process : %!s(bool=false) -> true
	|		├ update evt.Line.Module :  -> file
	|		├ create evt.Parsed.message : 172.18.0.4 - - [31/Oct/2023:09:43:59 +0000] "GET /wp-login.php/12312331/123423132 HTTP/1.0" 200 2229 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0"
	|		├ create evt.Parsed.program : nginx
	|		├ update evt.Time : 0001-01-01 00:00:00 +0000 UTC -> 2023-10-31 09:47:36.221609718 +0000 UTC
	|		├ create evt.Meta.datasource_path : /tmp/cscli_explain3431606629/cscli_test_tmp.log
	|		├ create evt.Meta.datasource_type : file
	├ s01-parse
	|	├ 🟢 crowdsecurity/nginx-logs (+22 ~2)
	|		├ update evt.Stage : s01-parse -> s02-enrich
	|		├ create evt.Parsed.body_bytes_sent : 2229
	|		├ create evt.Parsed.remote_addr : 172.18.0.4
	|		├ create evt.Parsed.request : /wp-login.php/12312331/123423132
	|		├ create evt.Parsed.request_length : 
	|		├ create evt.Parsed.verb : GET
	|		├ create evt.Parsed.http_referer : -
	|		├ create evt.Parsed.proxy_upstream_name : 
	|		├ create evt.Parsed.http_user_agent : Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0
	|		├ create evt.Parsed.target_fqdn : 
	|		├ create evt.Parsed.http_version : 1.0
	|		├ create evt.Parsed.proxy_alternative_upstream_name : 
	|		├ create evt.Parsed.remote_user : -
	|		├ create evt.Parsed.request_time : 
	|		├ create evt.Parsed.status : 200
	|		├ create evt.Parsed.time_local : 31/Oct/2023:09:43:59 +0000
	|		├ update evt.StrTime :  -> 31/Oct/2023:09:43:59 +0000
	|		├ create evt.Meta.log_type : http_access-log
	|		├ create evt.Meta.service : http
	|		├ create evt.Meta.http_status : 200
	|		├ create evt.Meta.http_user_agent : Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/119.0
	|		├ create evt.Meta.http_verb : GET
	|		├ create evt.Meta.source_ip : 172.18.0.4
	|		├ create evt.Meta.http_path : /wp-login.php/12312331/123423132
	├ s02-enrich
	|	├ 🟢 crowdsecurity/dateparse-enrich (+2 ~2)
	|		├ create evt.Enriched.MarshaledTime : 2023-10-31T09:43:59Z
	|		├ update evt.Time : 2023-10-31 09:47:36.221609718 +0000 UTC -> 2023-10-31 09:43:59 +0000 UTC
	|		├ update evt.MarshaledTime :  -> 2023-10-31T09:43:59Z
	|		├ create evt.Meta.timestamp : 2023-10-31T09:43:59Z
	|	├ 🟢 crowdsecurity/geoip-enrich (+9)
	|		├ create evt.Enriched.IsInEU : false
	|		├ create evt.Enriched.IsoCode : 
	|		├ create evt.Enriched.Latitude : 0.000000
	|		├ create evt.Enriched.Longitude : 0.000000
	|		├ create evt.Enriched.ASNNumber : 0
	|		├ create evt.Enriched.ASNOrg : 
	|		├ create evt.Enriched.ASNumber : 0
	|		├ create evt.Meta.ASNNumber : 0
	|		├ create evt.Meta.IsInEU : false
	|	├ 🟢 crowdsecurity/http-logs (+7)
	|		├ create evt.Parsed.file_dir : /wp-login.php/12312331/
	|		├ create evt.Parsed.file_frag : 123423132
	|		├ create evt.Parsed.impact_completion : true
	|		├ create evt.Parsed.file_ext : 
	|		├ create evt.Parsed.static_ressource : false
	|		├ create evt.Parsed.file_name : 123423132
	|		├ create evt.Meta.http_args_len : 0
	|	├ 🟢 crowdsecurity/jellyfin-whitelist (unchanged)
	|	└ 🟢 crowdsecurity/nextcloud-whitelist (unchanged)
	├-------- parser success 🟢
	├ Scenarios
		└ 🟢 crowdsecurity/http-crawl-non_statics

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants