PWN头秃之旅 - 1.Linux的保护机制
上篇office漏洞提到了栈溢出,查了下栈溢出属于PWN范畴,专门找了讲栈溢出的资料和书籍来看,尝试复现经典栈溢出(关闭地址随机化那种),尝试了N次,每次都失败了。>_<。都是卡在计算目标buffer的偏移这里,反正按照网上的方法都木有成功过,本机汇编出来的代码也看不懂,所以暂时放弃了。。。
今天准备做ctf,发现有pwn的题,新手区的第一题:
大佬们让我不要看PWN,不然会秃头,但是咱好奇啊,趁着脱发还不严重先看一下。题目肯定是不会的(不但不会做,还很理直气壮哈哈哈),先找网上的writeup一步一步学习吧,希望学完不要掉头发>_<
下载这个工具:https://github.com/slimm609/checksec.sh
checksec是一个bash脚本,用来检测可执行文件的属性,可执行文件属性包括:PIE, RELRO, PaX, Canaries, ASLR, Fortify Sourc
检测一下题目给出的附件:
hmmm...第一步就看不懂了...先停下来学习吧。
RELRO,CANARY,NX,PIE,FORTIFY都是Linux常用的保护机制。可在gcc编译时通过相应的选项进行设置。
FORTIFY
在编译的时候检查源码是否存在缓冲区溢出等错误。什么是缓冲区溢出?个人的粗浅理解是这样的,举个栗子:
#include <stdio.h> #include <string.h> int main(int argc, char* argv[]) { /* [1] */ char buf[256]; /* [2] */ strcpy(buf,argv[1]); /* [3] */ printf("Input:%s\n",buf); return 0; }
这段代码没有检查入参的长度,如果传入超过256个字符,就会造成缓冲区溢出。
NX(No-eXecute)
数据不可执行。原理是将数据所在内存页标识为不可执行,防止因为程序运行出现溢出而使得攻击者的shellcode可能会在数据区尝试执行的情况。NX在咱屡战屡败的经典栈溢出实验中有接触过,NX是对栈和堆的一种保护机制。实验需要关闭NX和地址随机化,否则执行shellcode时,CPU就会抛出异常,而不是去执行恶意指令。
Linux系统叫做NX,Windows系统中类似的机制叫DEP(Data Execute Prevention)。
PIE/ASLR
地址随机化。就是保证同一个程序任意两次运行时的堆栈基址是不同的。如果堆栈基址不变会怎样?不变就可能被攻击,因为攻击者能确认程序的内存地址,然后通过覆盖返回地址在等手段执行恶意代码。咱屡战屡败的经典栈溢出实验就是通过覆盖返回地址执行恶意代码。
STACK CANARY
栈保护。栈溢出保护是一种缓冲区溢出攻击缓解手段。启用栈保护后,函数开始执行的时候会先往栈里插入cookie信息,当函数真正返回的时候会验证cookie信息是否合法,如果不合法就停止程序运行。攻击者在覆盖返回地址的时候往往也会将cookie信息给覆盖掉,导致栈保护检查失败而阻止shellcode的执行。在Linux中我们将cookie信息称为canary。
简单来说就是通过验证cookie,来判断执行的代码是不是恶意代码。艾玛,我居然懂了,看来咱屡战屡败的经典栈溢出实验也不是一无是处。
RELRO(Relocation Read Only)
只读重定位。设置符号重定向表格为只读或在程序启动时就解析并绑定所有动态符号,从而减少对GOT攻击。GOT是全局函数表,它是干什么的请参考:https://www.zhihu.com/question/21249496。
在Linux中有"Partial RELRO" "Full RELRO"两种模式,默认开启Partical RELRO,开启Partical RELRO时,GOT是可写的,开启 FULL RELRO 时,GOT表是只读的。
RPATH
程序运行时的环境变量
Symbols
暂时没有查到相关资料
综合以上,对guess_num这个程序的检测结果:开启了NX,地址随机化,栈保护,以及Partial RELRO。
本文仅用于技术学习和交流,严禁用于非法用途,否则产生的一切后果自行承担。
如需转载,请注明出处,这是对他人劳动成果的尊重。