NX 基本介绍
即 No- eXecute
,NX
的基本原理是将数据所在内存页(用户栈中)标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令.
如图所示,该程序的栈空间没有可执行x
权限,所以无法执行任何代码。
道理我们都懂,那么如果我们 关闭了NX
到底可以干什么呢,该如何利用呢?下面通过一个实验来说明。
实验基本信息
本次虽提供了源码,但在我们利用NX
防护关闭这个漏洞时, 是在不知道源代码,编译时没有附带-g
无法gdb
直接进行调试的基础上进行的。
源代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void init()
{
setvbuf(stdin,0,_IONBF,0);
setvbuf(stdout,0,_IONBF,0);
}
int main()
{
char buf[100] = {0};
init();
printf("[DEBUGING] buf: %p\n",buf);
printf("Hello,What's Your name?\n");
read(0,buf,0x100);
printf("I don't know you,so bye ;)\n");
return 0;
}
makefile
文件
提供
makefile
方便可以快速编译改代码
OBJS=pwn_2.c
CC=gcc
CFLAGS+=-fno-stack-protector -no-pie -z execstack # 关闭NX
pwn_2:$(OBJS)
$(CC) $^ $(CFLAGS) -o $@
clean:
$(RM) *.o # 可省略
checksec信息
如图所示NX disabled
NX防护已关闭
确定栈段具有可执行权限
提示
进行编译的时候,gcc 会提示:
‘read’ writing 256 bytes into a region of size 100 overflows the destination [-Wstringop-overflow=]
不用理会, 因为本身我们验证的就是栈溢出,所以此处提示数据会溢出是正确的。