Security
244 TopicsF5 XC Session tracking with User Identification Policy
With F5 AWAF/ASM there is feature called session tracking that allows tracking and blocking users that do too many violations not only based on IP address but also things like the BIG-IP AWAF/ASM session cookie. What about F5 XC Distributed Cloud? Well now we will answer that question 😉 Why tracking on ip addresses some times is not enough? XC has a feature called malicious users that allows to block users if they generate too many service policy, waf , bot or other violations. By default users are tracked based on source IP addresses but what happens if there are proxies before the XC Cloud or NAT devices ? Well then all traffic for many users will come from a single ip address and when this IP address is blocked many users will get blocked, not just the one that did the violation. Now that we answered this question lets see what options we have. Reference: AI/ML detection of Malicious Users using F5 Distributed Cloud WAAP Trusted Client IP header This option is useful when the client real ip addresses are in something like a XFF header that the proxy before the F5 XC adds. By enabling this option automatically XC will use this header not the IP packet to get the client ip address and enforce Rate Limiting , Malicious Users blocking etc. Even in the XC logs now the ip address in the header will be shown as a source IP and if there is no such header the ip address in the packet will be used as backup. Reference: How to setup a Client IP as the Source IP on the HTTP Load Balancer headers? – F5 Distributed Cloud Services (zendesk.com) Overview of Trusted Client IP Headers in F5 Distributed Cloud Platform User Identification Policies The second more versatile feature is the XC user identification policies that by default is set to "Client IP" that will be the client ip from the IP packet or if "Trusted Client IP header" is configured the IP address from the configured header will be used. When customizing the feature allows the use of TLS fingerprints , HTTP headers like the "Authorization" header and more options to track the users and enforce rate limiters on them or if they make too many violations and Malicious users is enabled to block them based on the configured identifier if they make too many waf violations and so much more. The user identification will failover to the ip address in the packet if it can't identify the source user but multiple identification rules could be configured and evaluated one after another, as to only failover to the packet ip address if an identification rule can't be matched! If the backend upstream origin server application cookie is used for user identification and XC WAF App firewall is enabled and you can also use Cookie protection to protect the cookie from being send from another IP address! The demo juice shop app at https://demo.owasp-juice.shop/ can be used for such testing! References Lab 3: Malicious Users (f5.com) Malicious Users | F5 Distributed Cloud Technical Knowledge Configuring user session tracking (f5.com) How to configure Cookie Protection – F5 Distributed Cloud Services (zendesk.com)109Views0likes0CommentsF5 XC vk8s workload with Open Source Nginx
I have shared the code in the link below under Devcentral code share: F5 XC vk8s open source nginx deployment on RE | DevCentral Here I will desribe the basic steps for creating a workload object that is F5 XC custom kubernetes object that creates in the background kubernetes deployments, pods and Cluster-IP type services. The free unprivileged nginx image nginxinc/docker-nginx-unprivileged: Unprivileged NGINX Dockerfiles (github.com) Create a virtual site that groups your Regional Edges and Customer Edges. After that create the vk8s virtual kubernetes and relate it to the virtual site."Note": Keep in mind for the limitations of kubernetes deployments on Regional Edges mentioned in Create Virtual K8s (vK8s) Object | F5 Distributed Cloud Tech Docs. First create the workload object and select type service that can be related to Regional Edge virtual site or Customer Edge virtual site. After select the container image that will be loaded from a public repository like github or private repo. You will need to configure advertise policy that will expose the pod/container with a kubernetes cluster-ip service. If you are deploying test containers, you will not need to advertise the container . To trigger commands at a container start, you may need to use /bin/bash -c -- and a argument."Note": This is not related for this workload deployment and it is just an example. Select to overwrite the default config file for the opensource nginx unprivileged with a file mount."Note": the volume name shouldn't have a dot as it will cause issues. For the image options select a repository with no rate limit as otherwise you will see the error under the the events for the pod. You can also configure command and parameters to push to the container that will run on boot up. You can use empty dir on the virtual kubernetes on the Regional Edges for volume mounts like the log directory or the Nginx Cache zone but the unprivileged Nginx by default exports the logs to the XC GUI, so there is no need. "Note": This is not related for this workload deployment and it is just an example. The Logs and events can be seen under the pod dashboard and even the container/pod can accessed. "Note": For some workloads to see the logs from the XC GUI you will need to direct the output to stderr but not for nginx. After that you can reference the auto created kubernetes Cluster-IP service in a origin pool, using the workload name and the XC namespace (for example niki-nginx.default). "Note": Use the same virtual-site where the workload was attached and the same port as in the advertise cluster config. Deployments and Cluster-IP services can be created directly without a workload but better use the workload option. When you modify the config of the nginx actually you are modifying a configmap that the XC workload has created in the background and mounted as volume in the deployment but you will need to trigger deployment recreation as of now not supported by the XC GUI. From the GUI you can scale the workload to 0 pod instances and then back to 1 but a better solution is to use kubectl. You can log into the virtual kubernetes like any other k8s environment using a cert and then you can run the command "kubectl rollout restart deployment/niki-nginx". Just download the SSL/TLS cert. You can automate the entire process using XC API and then you can use normal kubernetes automation to run the restart command F5 Distributed Cloud Services API for ves.io.schema.views.workload | F5 Distributed Cloud API Docs! F5 XC has added proxy_protocol support and now the nginx container can work directly with the real client ip addresses without XFF HTTP headers or non-http services like SMTP that nginx supports and this way XC now can act as layer 7 proxy for email/smpt traffic 😉. You just need to add "proxy_protocol" directive and to log the variable "$proxy_protocol_addr". Related resources: For nginx Plus deployments for advanced functions like SAML or OpenID Connect (OIDC) or the advanced functions of the Nginx Plus dynamic modules like njs that is allowing java scripting (similar to F5 BIG-IP or BIG-IP Next TCL based iRules), see: Enable SAML SP on F5 XC Application Bolt-on Auth with NGINX Plus and F5 Distributed Cloud Dynamic Modules | NGINX Documentation njs scripting language (nginx.org) Accepting the PROXY Protocol | NGINX Documentation334Views2likes1CommentBlock IP Addresses With Data Group And Log Requests On ASM Event Log
Problem this snippet solves: This is Irule which will block IP Addresses that are not allowed in your organization. instead of adding each IP Address in Security ›› Application Security : IP Addresses : IP Address Exceptions you can create a data group and use a simple IRULE to block hundreds of Addressess. Also,createing a unique signature to specify the request of the illigile IP Address. First, You will need to create Data Group under Local Traffic ›› iRules : Data Group List and add your illigile IP Addresses to the list. If you have hundreds of IP's that you want to block, you can to it in TMSH using this command: TMSH/modify ltm data-group internal <Data-Group-Name> { records add {IP-ADDRESS} } Now, We are ready to create the IRULE under Local Traffic ›› iRules : iRule List Last, Create violation list under Security ›› Options : Application Security : Advanced Configuration : Violations List Create -> Name:Illegal_IP_Address -> Type:Access Violation -> Severity:Critical -> Update Don't forgat to enable trigger ASM IRULE events with "Normal Mode" How to use this snippet: Code : when HTTP_REQUEST { set reqBlock 0 if { [class match [IP::remote_addr] equals ] } { set reqBlock 1 # log local0. "HTTP_REQUEST [IP::client_addr]" } } when ASM_REQUEST_DONE { if { $reqBlock == 1} { ASM::raise "Illegal_IP_Address" # log local0. "ASM_REQUEST_DONE [IP::client_addr]" } } Tested this on version: 13.01.6KViews1like5CommentsFormat objectGUID attribute from hexadecimal to bindable string (hyphen-separated format)
Code is community submitted, community supported, and recognized as ‘Use At Your Own Risk’. Short Description Format objectGUID attribute from hexadecimal to bindable string (hyphen-separated format) Problem solved by this Code Snippet Claims recipients might require an Active Directory objectGUID to be represented as a bindable string (hyphen seperated format). The code snippet will help you to format the received objectGUID attribute from Active Directory from hexadecimal format "0xDE96F75DA1E135438C0F229A952D1432" to bindable string format "5df796de-e1a1-4335-8c0f-229a952d1432" How to use this Code Snippet In the VPE: add a "Variable Assign" item after the "AD Query" or "LDAP Query" used to get the "objectGUID" attribute in the left-side choose "custom variable" and choose a variable name. For example "session.sso.token.custom.formatedObjectGUID" in the righ-side choose "custom expression" and paste the code below Code Snippet Meta Information Version:1.0 Coding Language:TCL Full Code Snippet set hexGUID [mcget {session.ad.last.attr.objectGUID}] set substr1 "[string range $hexGUID 8 9][string range $hexGUID 6 7][string range $hexGUID 4 5][string range $hexGUID 2 3]" set substr2 "[string range $hexGUID 12 13][string range $hexGUID 10 11]" set substr3 "[string range $hexGUID 16 17][string range $hexGUID 14 15]" set substr4 "[string range $hexGUID 18 21]" set substr5 "[string range $hexGUID 22 33]" return "[string tolower "$substr1-$substr2-$substr3-$substr4-$substr5"]"32Views0likes0CommentsPOC: Create and sign a JWT with iRule
Code is community submitted, community supported, and recognized as ‘Use At Your Own Risk’. Short Description This snippet creates and signes a JWT. Signing algorithm is RS256. Problem solved by this Code Snippet This is a simple way to create a valid JWT for testing purposes. How to use this Code Snippet Add a private key Assign it to a VS and request "/jwt" to get a signed token Code Snippet Meta Information Version: POC Coding Language: TCL Full Code Snippet https://github.com/JuergenMang/f5-irules-jwt/blob/main/jwt-sign218Views0likes0CommentsPOC: Validate JWT with iRule
Code is community submitted, community supported, and recognized as ‘Use At Your Own Risk’. Short Description This is a proof of concept iRule to decode and validate a JWT submitted in the HTTP Authorization header. It supports only JWT's signed with RS256 and was roughly tested with Azure, Okta and ADFS tokens. It is not designed for production usage, especially there are more checks required to comply with https://datatracker.ietf.org/doc/html/rfc7519#section-7.2. Problem solved by this Code Snippet Decode and validate a JWT with an iRule. How to use this Code Snippet Attach it to a VS and adapt the public key(s) and key id(s). Code Snippet Meta Information Version: POC Coding Language: iRule Full Code Snippet https://github.com/JuergenMang/f5-irules-jwt/blob/main/jwt-validate514Views4likes2CommentsCitrixBleed Mitigation CVE-2023-4966
Code is community submitted, community supported, and recognized as ‘Use At Your Own Risk’. Short Description The Citrix Bleed exploit https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-4966against Netscaler ADC and Netscaler Gateway is being seen in the wild and impacting many organisations https://www.malwarebytes.com/blog/news/2023/11/citrix-bleed-widely-exploitated-warn-government-agencies. If you have a BIG-IP providing access to your Citrix platform, you can gain visibility of this explit and potentially mitigate malicious requests. Problem solved by this Code Snippet This iRule will catch requests to the exploit URL and create a log and iStat, and potentially drop malicious requests where the Host header is set to be a large length. How to use this Code Snippet Create the iRule and assign it to the virtual server in front of the Citrix device. Code Snippet Meta Information Version: TMOS v11+ Coding Language: iRule Full Code Snippet when RULE_INIT priority 500 { # This is an iRule to be used to capture and possibly mitigate against known Citrix Bleed attacks # https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-4966 # There is no support implied in using this iRule, you use it at your own risk # Version 1 Peter White # Note that all requests to /oauth/idp/.well-known/openid-configuration will be logged in /var/log/ltm for later checking of source address etc # and all requests with a hostname of more than 100 characters will be assumed to be malicious # Set the variable below to 1 or 0 to turn on blocking of known malicious requests set static::cb_block 1 # Set the host header max length. Note that the PoC uses a length of 24576 set static::cb_host_max_length 100 # Log prefix - set the log prefix for the warning logs for this iRule set static::cb_log_prefix "CB" } when HTTP_REQUEST priority 100 { if { [HTTP::path] equals "/oauth/idp/.well-known/openid-configuration" } { log local0.warn "$static::cb_log_prefix [virtual name] [IP::client_addr] [TCP::client_port] [whereis [IP::client_addr] continent] [whereis [IP::client_addr] country]" # Note that you can see the iStat using the command 'tmsh show ltm virtual <virtual server name>' and look at User-defined stats at the bottom ISTATS::incr "ltm.virtual [virtual name] counter CB_log" 1 if { $static::cb_block && ([string length [HTTP::header Host]] > $static::cb_host_max_length) } { drop } } }189Views2likes0CommentsAfter applied ASM Policy to Virtual Server, connections will reset with Internal error in log
Whether the ASM policy is in Transparent mode or Blocking, when applied to Virtual Server, the connection is reset. The packet captures shows: Internal error (ASM requested abort (plugin abort error))] tmm1[29648]: 01230140:3: RST sent from *.*.*.*:443 to *.*.*.*:51570, [0x223b824:820] Internal error (ASM requested abort (plugin abort error)) However, when I remove the ASM policy from the VS , the service works fine. Has anyone had any experience getting this sort of setup working? TMOS Version : 16.0.1204Views0likes0CommentsiRule to modify a content-security-policy header
Code is community submitted, community supported, and recognized as ‘Use At Your Own Risk’. Short Description This short iRule snippet can change specific directives in a content-security-policy header. The script is only roughly tested, but maybe we can improve it together. Full Code Snippet when HTTP_RESPONSE_RELEASE priority 800 { # init set csp_fields "" set csp(directives) "" set csp(values) "" # configure lappend csp(directives) "frame-ancestors" lappend csp(values) "*" # iterate through directives from backend set org_csp_fields [split [HTTP::header Content-Security-Policy] ";"] foreach field $org_csp_fields { set directive [getfield [string trim $field] " " 1] set idx [lsearch -exact $csp(directives) $directive] if { $idx > -1 } { # append enforced value lappend csp_fields "$directive [lindex $csp(values) $idx]" } else { # append original value lappend csp_fields $field } } # add missing directives set i 0 foreach field $csp(directives) { set idx [lsearch -glob $csp_fields "${field}*"] if { $idx == -1 } { # missing, add it lappend csp_fields "${field} [lindex $csp(values) $i]" } incr i } # replace the header HTTP::header remove Content-Security-Policy HTTP::header insert Content-Security-Policy [join $csp_fields "; "] }2.1KViews2likes2Comments