cve-2019-19781_port80_GET_vulnerability_path_check.pcap
This pcap has two http request/response pairs, I’ll focus only on the http requests as this is the data which is of interest to the two signature in question.
this pcap and suricata variables
In this pcap, all traffic to sourced from 127.0.0.2
and destined to 127.0.0.1
, which by default is not part of the $HOME_NET
or $HTTP_SERVERS
variables. There are a couple ways to address this, but in my testing, I opted to just add 127.0.0.1
to the $HOME_NET
variable. Proper variables is critical to the correct evaluation of the rules. In my opinion this is singly the most overlooked configuration item notice leading to False Negatives and False Positives.
Emerging Threats generally considers $HOME_NET
to be loosely defined as “The network you are trying to defend/protect”. In this case, given the ‘server’ is being exploited, we can include 127.0.0.1
in $HOME_NET
which, in the below configuration, will force 127.0.0.2
to be considered $EXTERNAL_NET
vars:
# more specific is better for alert accuracy and performance
address-groups:
HOME_NET: "[127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12]"
EXTERNAL_NET: "!$HOME_NET"
HTTP_SERVERS: "$HOME_NET"
first request
00000000 47 45 54 20 2f 76 70 6e 2f 2e 2e 2f 76 70 6e 73 GET /vpn /../vpns
00000010 2f 63 66 67 2f 73 6d 62 2e 63 6f 6e 66 20 48 54 /cfg/smb .conf HT
00000020 54 50 2f 31 2e 31 0d 0a 48 6f 73 74 3a 20 31 30 TP/1.1.. Host: 10
00000030 2e 31 30 2e 31 2e 32 35 31 0d 0a 55 73 65 72 2d .10.1.25 1..User-
00000040 41 67 65 6e 74 3a 20 63 75 72 6c 2f 37 2e 36 34 Agent: c url/7.64
00000050 2e 31 0d 0a 41 63 63 65 70 74 3a 20 2a 2f 2a 0d .1..Acce pt: */*.
00000060 0a 63 69 70 2d 68 65 61 64 65 72 3a 20 31 30 2e .cip-hea der: 10.
00000070 31 30 2e 31 2e 36 32 20 20 20 20 20 0d 0a 0d 0a 10.1.62 ....
sid:2029206
correctly alerts on this traffic (once variables are defined), but an explanation of how suricata “normalizes” the http.uri
buffer follows
If we attempt to use the normalized http.uri
, the buffer ends up “normalzing” the directory traversal, and the http.uri buffer actually becomes
00000000 2F 76 70 6E 73 2F 63 66 67 2F 73 6D 62 2E 63 6F |/vpns/cfg/smb.co|
00000010 6E 66 |nf
while http.uri.raw, which is unnormalized shows up as
00000000 2F 76 70 6E 2F 2E 2E 2F 76 70 6E 73 2F 63 66 67 |/vpn/../vpns/cfg|
00000010 2F 73 6D 62 2E 63 6F 6E 66 |/smb.conf |
Alerts
We only expect 2029206 to alert on this traffic, and it does.
01/13/2020-10:32:30.621624 [**] [1:2029206:4] ET EXPLOIT Possible Citrix Application Delivery Controller Arbitrary Code Execution Attempt (CVE-2019-19781) [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 127.0.0.2:28147 -> 127.0.0.1:80
second request
00000080 47 45 54 20 2f 76 70 6e 2f 2e 2e 2f 56 50 6e 73 GET /vpn /../VPns
00000090 2f 63 66 67 2f 73 6d 62 2e 63 6f 6e 66 20 48 54 /cfg/smb .conf HT
000000A0 54 50 2f 31 2e 31 0d 0a 48 6f 73 74 3a 20 31 30 TP/1.1.. Host: 10
000000B0 2e 31 30 2e 31 2e 32 35 31 0d 0a 55 73 65 72 2d .10.1.25 1..User-
000000C0 41 67 65 6e 74 3a 20 63 75 72 6c 2f 37 2e 36 34 Agent: c url/7.64
000000D0 2e 31 0d 0a 41 63 63 65 70 74 3a 20 2a 2f 2a 0d .1..Acce pt: */*.
000000E0 0a 63 69 70 2d 68 65 61 64 65 72 3a 20 31 30 2e .cip-hea der: 10.
000000F0 31 30 2e 31 2e 36 32 20 20 20 20 20 0d 0a 0d 0a 10.1.62 ....
Except for the casing of the /VPns
, this traffic is the exact same as the first request. As such, one could expect sid:2029206
to alert, however, this is a very basic evasion. It can be corrected by applying a “nocase” modifier to the rule below (tracked as rev:5
)
alert http any any -> $HTTP_SERVERS any (msg:"ET EXPLOIT Possible Citrix Application Delivery Controller Arbitrary Code Execution Attempt (CVE-2019-19781)"; flow:established,to_server; http.uri; content:"/vpns/"; nocase; fast_pattern; http.uri.raw; content:"/../"; reference:url,support.citrix.com/article/CTX267679; reference:cve,2019-19781; classtype:attempted-admin; sid:2029206; rev:5; metadata:affected_product Windows_XP_Vista_7_8_10_Server_32_64_Bit, attack_target Client_Endpoint, created_at 2019_12_30, deployment Perimeter, deployment SSLDecrypt, former_category EXPLOIT, signature_severity Major, updated_at 2020_10_27;)
Alerts
After applying rev:5;
the rule we see two alerts for both requests.
01/13/2020-10:32:30.621624 [**] [1:2029206:5] ET EXPLOIT Possible Citrix Application Delivery Controller Arbitrary Code Execution Attempt (CVE-2019-19781) [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 127.0.0.2:28147 -> 127.0.0.1:80
01/13/2020-10:32:35.512774 [**] [1:2029206:5] ET EXPLOIT Possible Citrix Application Delivery Controller Arbitrary Code Execution Attempt (CVE-2019-19781) [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 127.0.0.2:28147 -> 127.0.0.1:80
citrix_dataset_clean_http_2_evasion.pcapng
This pcap consists of four unique TCP streams. Again, I’ll try to break them all down here, but will not go into as much detail.
- 192.168.116.1:33530 → 162.168.116.65:80
- 192.168.116.1:1034 → 162.168.116.65:80
- 192.168.116.1:1035 → 162.168.116.65:80
- 192.168.116.25:36238 → 192.168.116.1:5555
192.168.116.1:33530 → 162.168.116.65:80
These requests attempt to validate a vulnerable server.
This session contains multiple HTTP requests/response pairs, and while they do contain minor differences, for the purposes of these two signatures in questions, they are all the same
GET /vpn/js/%2E./.%2E/%76pns/cfg/smb.conf HTTP/1.1
User-Agent: PostmanRuntime/7.29.0
Accept: */*
Postman-Token: 8bf270c7-7142-41f9-b852-97feba79ee3c
Host: 192.168.116.65
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
RAW_URI_DUMP, 37
00000000 2F 76 70 6E 2F 6A 73 2F 25 32 45 2E 2F 2E 25 32 |/vpn/js/%2E./.%2|
00000010 45 2F 25 37 36 70 6E 73 2F 63 66 67 2F 73 6D 62 |E/%76pns/cfg/smb|
00000020 2E 63 6F 6E 66 |.conf |
URI_DUMP, 18
00000000 2F 76 70 6E 73 2F 63 66 67 2F 73 6D 62 2E 63 6F |/vpns/cfg/smb.co|
00000010 6E 66 |nf |
Alerts
None observed for this session - Traffic should fire sid:2029206
however, this is successfully evaded via the %76
and %2E
obfuscation within the http.uri.raw
buffer.
Tune
I think the best way to reliably cause this to alert would be to apply the url_decode part of normalization to the http.uri.raw
buffer, we can do this in Suricata 6.0+, as seen in rev:6
below, by using the url_decode
transformation.
alert http any any -> $HTTP_SERVERS any (msg:"ET EXPLOIT Possible Citrix Application Delivery Controller Arbitrary Code Execution Attempt (CVE-2019-19781)"; flow:established,to_server; http.uri; content:"/vpns/"; fast_pattern; nocase; http.uri.raw; url_decode; content:"/../"; reference:url,support.citrix.com/article/CTX267679; reference:cve,2019-19781; classtype:attempted-admin; sid:2029206; rev:6; metadata:affected_product Windows_XP_Vista_7_8_10_Server_32_64_Bit, attack_target Client_Endpoint, created_at 2019_12_30, deployment Perimeter, deployment SSLDecrypt, former_category EXPLOIT, signature_severity Major, updated_at 2020_10_27;)
However, Emerging Threats currently supports Suricata 6.0+ via the Suricata 5 ruleset, and therefore cannot currently make use of this transformation within our ruleset. In order to create a ruleset that would make use of keywords/transformations/etc supported by Suricata 6.0+, a new ruleset would have to be produced. ET calls this process “forking the ruleset”.
By deploying sid:2029206; rev:6;
as described above, we see the alerts fire for each HTTP request.
01/21/2022-15:36:34.072526 [**] [1:2029206:4] ET EXPLOIT Possible Citrix Application Delivery Controller Arbitrary Code Execution Attempt (CVE-2019-19781) [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 192.168.116.1:33530 -> 192.168.116.65:80
01/21/2022-15:36:35.221486 [**] [1:2029206:4] ET EXPLOIT Possible Citrix Application Delivery Controller Arbitrary Code Execution Attempt (CVE-2019-19781) [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 192.168.116.1:33530 -> 192.168.116.65:80
01/21/2022-15:36:36.444532 [**] [1:2029206:4] ET EXPLOIT Possible Citrix Application Delivery Controller Arbitrary Code Execution Attempt (CVE-2019-19781) [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 192.168.116.1:33530 -> 192.168.116.65:80
01/21/2022-15:36:37.296835 [**] [1:2029206:4] ET EXPLOIT Possible Citrix Application Delivery Controller Arbitrary Code Execution Attempt (CVE-2019-19781) [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 192.168.116.1:33530 -> 192.168.116.65:80
01/21/2022-15:36:38.071834 [**] [1:2029206:4] ET EXPLOIT Possible Citrix Application Delivery Controller Arbitrary Code Execution Attempt (CVE-2019-19781) [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 192.168.116.1:33530 -> 192.168.116.65:80
192.168.116.1:1034 → 162.168.116.65:80
This session uploads a python reverse shell to the proposed template file.
ASCII Post
POST /vpn/%2E./vpns/portal/scripts/newbm.pl HTTP/1.1
Host: 192.168.116.65
Accept-Encoding: identity
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
NSC_USER: ../../../netscaler/portal/templates/pedvsxnurk
NSC_NONCE: 6
Content-Length: 3661
Content-Type: application/x-www-form-urlencoded
http.uri.raw
unnormalized buffer
RAW_URI_DUMP, 38
00000000 2F 76 70 6E 2F 25 32 45 2E 2F 76 70 6E 73 2F 70 |/vpn/%2E./vpns/p|
00000010 6F 72 74 61 6C 2F 73 63 72 69 70 74 73 2F 6E 65 |ortal/scripts/ne|
00000020 77 62 6D 2E 70 6C |wbm.pl |
http.uri
normalized buffer
URI_DUMP, 29
00000000 2F 76 70 6E 73 2F 70 6F 72 74 61 6C 2F 73 63 72 |/vpns/portal/scr|
00000010 69 70 74 73 2F 6E 65 77 62 6D 2E 70 6C |ipts/newbm.pl |
http.headers
buffer
REQ_HEADERS_DUMP, 290
00000000 48 6F 73 74 3A 20 31 39 32 2E 31 36 38 2E 31 31 |Host: 192.168.11|
00000010 36 2E 36 35 0D 0A 41 63 63 65 70 74 2D 45 6E 63 |6.65..Accept-Enc|
00000020 6F 64 69 6E 67 3A 20 69 64 65 6E 74 69 74 79 0D |oding: identity.|
00000030 0A 55 73 65 72 2D 41 67 65 6E 74 3A 20 4D 6F 7A |.User-Agent: Moz|
00000040 69 6C 6C 61 2F 35 2E 30 20 28 4D 61 63 69 6E 74 |illa/5.0 (Macint|
00000050 6F 73 68 3B 20 49 6E 74 65 6C 20 4D 61 63 20 4F |osh; Intel Mac O|
00000060 53 20 58 20 31 30 2E 31 34 3B 20 72 76 3A 37 31 |S X 10.14; rv:71|
00000070 2E 30 29 20 47 65 63 6B 6F 2F 32 30 31 30 30 31 |.0) Gecko/201001|
00000080 30 31 20 46 69 72 65 66 6F 78 2F 37 31 2E 30 0D |01 Firefox/71.0.|
00000090 0A 4E 53 43 5F 55 53 45 52 3A 20 2E 2E 2F 2E 2E |.NSC_USER: ../..|
000000A0 2F 2E 2E 2F 6E 65 74 73 63 61 6C 65 72 2F 70 6F |/../netscaler/po|
000000B0 72 74 61 6C 2F 74 65 6D 70 6C 61 74 65 73 2F 70 |rtal/templates/p|
000000C0 65 64 76 73 78 6E 75 72 6B 0D 0A 4E 53 43 5F 4E |edvsxnurk..NSC_N|
000000D0 4F 4E 43 45 3A 20 36 0D 0A 43 6F 6E 74 65 6E 74 |ONCE: 6..Content|
000000E0 2D 4C 65 6E 67 74 68 3A 20 33 36 36 31 0D 0A 43 |-Length: 3661..C|
000000F0 6F 6E 74 65 6E 74 2D 54 79 70 65 3A 20 61 70 70 |ontent-Type: app|
00000100 6C 69 63 61 74 69 6F 6E 2F 78 2D 77 77 77 2D 66 |lication/x-www-f|
00000110 6F 72 6D 2D 75 72 6C 65 6E 63 6F 64 65 64 0D 0A |orm-urlencoded..|
00000120 0D 0A |.. |
Alerts
-
sid:2029255
successfully alerts on this session as expected given the /../
occurring in the http.header
buffer.
-
sid:2029206; rev:4;
does not alert and is successfully evaded due to the use of %2E
in the uri.
-
sid:2029206; rev:5;
does not alert and is successfully evaded due to the use of %2E
in the uri.
-
sid:2029206; rev:6;
successfully alerts on this traffic.
01/21/2022-15:36:47.276584 [**] [1:2029255:3] ET EXPLOIT Possible Citrix Application Delivery Controller Arbitrary Code Execution Attempt (CVE-2019-19781) M2 [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 192.168.116.1:1034 -> 192.168.116.65:80
01/21/2022-15:36:47.276584 [**] [1:2029206:6] ET EXPLOIT Possible Citrix Application Delivery Controller Arbitrary Code Execution Attempt (CVE-2019-19781) [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 192.168.116.1:1034 -> 192.168.116.65:80
Interestingly enough, there is actually another signature which has been produced to fire on this session, but also FNs. This is sid:2034279;
, it FNs for different reasons which do not involve uri normalization and as such, I’ll not bother explaining here, but will push an update to the rule. It’ll come out at rev:2;
192.168.116.1:1035 → 162.168.116.65:80
This session contains a single HTTP request which executes the uploaded python reverse shell
GET /vpn/%2E./vpns/portal/pedvsxnurk.xml HTTP/1.1
Host: 192.168.116.65
Accept-Encoding: identity
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
NSC_USER: tzynytmqli
NSC_NONCE: 6
Alerts
-
sid:2029206; rev:4;
does not alert and is successfully evaded due to the use of %2E
in the uri.
-
sid:2029206; rev:5;
does not alert and is successfully evaded due to the use of %2E
in the uri.
-
sid:2029206; rev:6;
successfully alerts on this traffic.
01/21/2022-15:36:34.012778 [**] [1:2029206:6] ET EXPLOIT Possible Citrix Application Delivery Controller Arbitrary Code Execution Attempt (CVE-2019-19781) [**] [Classification: Attempted Administrator Privilege Gain] [Priority: 1] {TCP} 192.168.116.1:1035 -> 192.168.116.65:80
192.168.116.25:36238 → 192.168.116.1:5555
This session contains the reverse shell traffic, showing a complete and successful exploit chain.
It’s not related to the question at hand, so I’ll skip it. Though an Alert does fire on the use of the id
command here. There are some additional signature opportunities, I’ll get those out as soon as I can.
01/21/2022-15:36:34.012778 [**] [1:2019284:3] ET ATTACK_RESPONSE Output of id command from HTTP server [**] [Classification: Potentially Bad Traffic] [Priority: 2] {TCP} 192.168.116.25:36238 -> 192.168.116.1:5555