[WUSTCTF2020]level3 笔记与自省

本文讲述了作者通过IDA分析一个包含base64编码和O_OLookAtYou函数的程序,揭示了初始化函数__libc_start_main中的加密策略。通过查找并理解O_OLookAtYou函数,发现它是对base64_table进行的奇特置换,从而成功解密隐藏的flag。
摘要由CSDN通过智能技术生成

解题过程:

    直接放入IDA分析,跳入main函数,得到如下内容

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char *v3; // rax
  char v5; // [rsp+Fh] [rbp-41h]
  char v6[56]; // [rsp+10h] [rbp-40h] BYREF
  unsigned __int64 v7; // [rsp+48h] [rbp-8h]

  v7 = __readfsqword(0x28u);
  printf("Try my base64 program?.....\n>");
  __isoc99_scanf("%20s", v6);
  v5 = time(0LL);
  srand(v5);
  if ( (rand() & 1) != 0 )
  {
    v3 = base64_encode(v6);
    puts(v3);
    puts("Is there something wrong?");
  }
  else
  {
    puts("Sorry I think it's not prepared yet....");
    puts("And I get a strange string from my program which is different from the standard base64:");
    puts("d2G0ZjLwHjS7DmOzZAY0X2lzX3CoZV9zdNOydO9vZl9yZXZlcnGlfD==");
    puts("What's wrong??");
  }
  return 0;
}

    显然,最底下有一串形似base64编码的字符串

d2G0ZjLwHjS7DmOzZAY0X2lzX3CoZV9zdNOydO9vZl9yZXZlcnGlfD==

    解码发现无法正确得到内容,猜测是映射表被更改过

    观察发现一个明显怪异的函数:“O_OLookAtYou”

__int64 O_OLookAtYou()
{
  __int64 result; // rax
  char v1; // [rsp+1h] [rbp-5h]
  int i; // [rsp+2h] [rbp-4h]

  for ( i = 0; i <= 9; ++i )
  {
    v1 = base64_table[i];
    base64_table[i] = base64_table[19 - i];
    result = 19 - i;
    base64_table[result] = v1;
  }
  return result;
}

    直接放入VS得到置换后结果:

int main()
{
    char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    for (int i = 0; i <= 9; ++i)
    {
        char v1 = base64_table[i];
        base64_table[i] = base64_table[19 - i];
        char result = 19 - i;
        base64_table[result] = v1;
    }
    cout << base64_table;//TSRQPONMLKJIHGFEDCBAUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
}

    得到新表,直接对密文进行解密即可得到flag

--------------------------------------------------------------------------------------------

    明确一点,当main函数找不到期望的内容的时候,应该从start函数开始看

    main函数为用户代码的入口,但在此之前应有许多函数库需要初始化,这些初始化工作则从start函数开始

// positive sp value has been detected, the output may be wrong!
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void))
{
  __int64 v3; // rax
  int v4; // esi
  __int64 v5; // [rsp-8h] [rbp-8h] BYREF
  char *retaddr; // [rsp+0h] [rbp+0h] BYREF

  v4 = v5;
  v5 = v3;
  __libc_start_main(main, v4, &retaddr, _libc_csu_init, _libc_csu_fini, a3, &v5);
  __halt();
}

    本题中,__libc_start_main()函数调用了包括main在内的三个函数(但第三个函数进入后会发现里面什么都没有)

void __fastcall _libc_csu_init(unsigned int a1, __int64 a2, __int64 a3)
{
  signed __int64 v4; // rbp
  __int64 i; // rbx

  v4 = &_do_global_dtors_aux_fini_array_entry - _frame_dummy_init_array_entry;
  init_proc();
  if ( v4 )
  {
    for ( i = 0LL; i != v4; ++i )
      (_frame_dummy_init_array_entry[i])(a1, a2, a3);
  }
}

    v4变量使用了两个标签,不妨进入去看看 

.init_array:0000000000601E08 __frame_dummy_init_array_entry dq offset frame_dummy
.init_array:0000000000601E08                                         ; DATA XREF: LOAD:00000000004000F8↑o
.init_array:0000000000601E08                                         ; LOAD:0000000000400210↑o ...
.init_array:0000000000601E08                                         ; Alternative name is '__init_array_start'
.init_array:0000000000601E10                 dq offset O_OLookAtYou
.init_array:0000000000601E10 _init_array     ends
.init_array:0000000000601E10
.fini_array:0000000000601E18 ; ELF Termination Function Table
.fini_array:0000000000601E18 ; ===========================================================================
.fini_array:0000000000601E18
.fini_array:0000000000601E18 ; Segment type: Pure data
.fini_array:0000000000601E18 ; Segment permissions: Read/Write
.fini_array:0000000000601E18 _fini_array     segment qword public 'DATA' use64
.fini_array:0000000000601E18                 assume cs:_fini_array
.fini_array:0000000000601E18                 ;org 601E18h
.fini_array:0000000000601E18 __do_global_dtors_aux_fini_array_entry dq offset __do_global_dtors_aux

    0000000000601E10地址处引用了O_OLookAtYou函数的地址

    这一系列函数通过_libc_csu_init函数中的for循环去使用

    当然,实际上看看表有没有被更改只需要对base64_table查看其交叉引用即可

    所以最后还是自己瞎忙活一通,算是吃个瘪长个教训吧......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值