easy-UPX++

176次阅读
没有评论

easy-UPX++

附件解压获得main.exe 检查一下有没有壳

easy-UPX++

Big sec. 02 [ FDSA ] , Don't try : upx.exe -d option ( min. 3.91 UPX required !!! )

easy-UPX++魔改壳

easy-UPX++

直接打开010手动修改

成功脱壳

easy-UPX++

easy-UPX++

main逻辑分析

整型变量 v3 i
字符串型变量 v4
标准输入流 v5 v6
字符串型变量 encoded input

执行 _main()  //可能是初始化
执行 patch_base64_chars_from_self()  //不知道是什么 也没有参数传入 后续分析
初始化input
将输入的字符传入input
获取input的长度
将长度赋值给 v3
执行 base64_encode() 传入v3 并将结果赋值给 encoded

起循环 逐字符遍历过去 以 str的长度为界限 //str是什么?
	v4赋值为 加密过后的第i位
	进行判断 v4是否和 str[i]相等
		如果错误就停止执行

输出正确

综上 也是一个flag校验程序

void __cdecl patch_base64_chars_from_self()  //从程序自身获取base64加密表
{
  std::ostream *v0; // rax
  std::ostream *v1; // rax
  std::ostream *v2; // rax
  std::ostream *v3; // rax
  _BYTE *v4; // rdx
  _BYTE *v5; // rdx
  _BYTE *v6; // rdx
  __int64 v7; // [rsp+0h] [rbp-80h] BYREF
  char buffer[272]; // [rsp+20h] [rbp-60h] BYREF
  _BYTE v9[208]; // [rsp+130h] [rbp+B0h] BYREF
  _BYTE v10[272]; // [rsp+200h] [rbp+180h] BYREF
  std::fpos<int> v11; // [rsp+310h] [rbp+290h] BYREF
  char *bytecode; // [rsp+320h] [rbp+2A0h]
  std::streamsize size; // [rsp+328h] [rbp+2A8h]
  int i_1; // [rsp+334h] [rbp+2B4h]
  int i_0; // [rsp+338h] [rbp+2B8h]
  int i; // [rsp+33Ch] [rbp+2BCh]

  GetModuleFileNameA(0LL, (LPSTR)&v7 + 32, 0x104u);  //读取文件
  std::ifstream::basic_ifstream(v9, buffer, 4LL);   //打开文件
  if ( (unsigned __int8)std::ios::operator!(v10) )
  {
    v0 = (std::ostream *)std::operator<<<std::char_traits<char>>(refptr__ZSt4cerr, "ERROR:OPEN ");
    v1 = (std::ostream *)std::operator<<<std::char_traits<char>>(v0, buffer);
    refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(v1);
  }
  else
  {
    std::istream::seekg(v9, 0LL, std::_Ios_Seekdir::_S_end);
    std::istream::tellg(&v11);
    size = std::fpos<int>::operator long long(&v11);
    std::istream::seekg(v9, 0LL, std::_Ios_Seekdir::_S_beg);
    bytecode = (char *)operator new[](size, refptr__ZSt7nothrow);
    if ( bytecode )
    {
      std::istream::read(v9, bytecode, size);
      if ( (unsigned __int8)std::ios::operator!(v10) )
      {
        v3 = (std::ostream *)std::operator<<<std::char_traits<char>>(refptr__ZSt4cerr, "ERROR:READ");
        refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(v3);
        if ( bytecode )
          operator delete[](bytecode);
      }
      else
      {
        for ( i = 0; i <= 3; ++i )
        {
          v4 = (_BYTE *)std::string::operator[](&base64_chars, i);
          *v4 = bytecode[i + 392];    //替换ABCD 为392-395的字符
        }
        for ( i_0 = 0; i_0 <= 3; ++i_0 )
        {
          v5 = (_BYTE *)std::string::operator[](&base64_chars, i_0 + 10);
          *v5 = bytecode[i_0 + 432];   //替换KLMN 为 432-435的字符
        }
        for ( i_1 = 0; i_1 <= 3; ++i_1 )
        {
          v6 = (_BYTE *)std::string::operator[](&base64_chars, i_1 + 19);
          *v6 = bytecode[i_1 + 472];    //替换TUVW 为 472-475的字符
        }
        if ( bytecode )
          operator delete[](bytecode);
      }
      std::ifstream::close(v9);
    }
    else
    {
      v2 = (std::ostream *)std::operator<<<std::char_traits<char>>(refptr__ZSt4cerr, "ERROR:ALLOC");
      refptr__ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(v2);
      std::ifstream::close(v9);
    }
  }
  std::ifstream::~ifstream(v9);
}

easy-UPX++

easy-UPX++

获取到的字符串大概率是初始化的加密表

with open("main2.exe", "rb") as f:
    data = f.read()
base64_table = list("QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm0123456789+/")
# 替换规则
for i in range(4):
    base64_table[i]        = chr(data[392 + i])
    base64_table[10 + i]   = chr(data[432 + i])
    base64_table[19 + i]   = chr(data[472 + i])
print("".join(base64_table))

VCXZTYUIOPFDSAGHJKLREWQBNMqwertyuiopasdfghjklzxcvbnm0123456789+/

str的内容如下

.data:0000000000473010 str             db 57h, 64h, 73h, 61h, 4Eh, 42h, 50h, 37h, 2 dup(57h)
.data:0000000000473010                                         ; DATA XREF: main+8A↑o
.data:0000000000473010                                         ; main+E0↑o
.data:000000000047301A                 db 43h, 4Eh, 42h, 33h, 72h, 68h, 72h, 55h, 69h, 79h, 4Dh
.data:0000000000473025                 db 70h, 4Bh, 6Bh, 53h, 33h, 30h, 3Dh, 0

payload

import base64

alt_b64 = "VCXZTYUIOPFDSAGHJKLREWQBNMqwertyuiopasdfghjklzxcvbnm0123456789+/"
std_b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

dec_table = str.maketrans(alt_b64, std_b64)

ciphertext = "WdsaNBP7WWCNB3rhrUiyMpKkS30="

translated = ciphertext.translate(dec_table)
decoded = base64.b64decode(translated)

print("标准Base64串:", translated)
print("解码结果:", decoded)
正文完
 0
评论(没有评论)