吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4298|回复: 5
收起左侧

[CTF] 【reverse IDA使用技巧】IDA动态调试Linux_ELF配置+例题:SCUCTF新生赛2021-DebugMe

  [复制链接]
hans7 发表于 2022-9-12 09:37
本帖最后由 hans7 于 2022-9-12 09:44 编辑

依赖

作者:hans774882968以及hans774882968以及hans774882968

本文juejin:https://juejin.cn/post/7142302432326860830/

本文52pojie:https://www.52pojie.cn/thread-1686855-1-1.html

本文csdn:https://blog.csdn.net/hans774882968/article/details/126813166

IDA动态调试ELF配置

首先我们需要一台虚拟机,理论上云服务器也没问题,但用本地的虚拟机更方便。大致跟着参考链接2走一遍就行,但本文会指出一些需要注意的地方。

首先,把IDA安装目录/dbgsrv/linux_server64复制到虚拟机的某目录下(记为<x>/linux_server64),把它运行起来。它默认会占用23946端口。

接下来需要知道虚拟机的Hostname。

获取远程主机的Hostname

如果是云服务器就不用走这一步了,但对于本地虚拟机来说这一步是必要的。参考链接2使用了已不再维护(而且在Ubuntu20.04中不可用)的ifconfig命令。对于Ubuntu20.04,应使用ip a命令。输出信息很长,但我们只需要关注输出中inet 某ip地址的部分。如果你发现你的输出中只有inet 127.0.0.1inet 10.0.2.15,这说明主机不能通过ip访问虚拟机,需要走下一步的流程。

VirtualBox虚拟机设置桥接模式,与宿主机互相ping通

根据参考链接1的两个链接,选择你在用的wifi来设置即可。设置完毕后,不需要重启虚拟机,再次使用ip a命令即可看到Hostname。

填写IDA的Debug application setup
  1. Application:你要调试的ELF的完整路径。对于远程调试会话,该路径为调试服务器上的路径。如果选择不使用完整路径,远程服务器将搜索它的当前工作目录。比如:<x>/RE3_DebugMe
  2. Directory:对于远程调试,此字段表示远程目录。比如:<x>
  3. Parameters:用于指定在进程启动时传递给它的任何命令行参数。对于远程调试会话,进程输出将在用于启动调试服务器的控制台中显示。具体ELF具体分析吧。
  4. Hostname:远程调试服务器主机或IP地址。在上面两步中获取。
  5. Port:远程调试服务器监听的TCP端口号,保持默认即可。
  6. Password:远程调试服务器所需的密码,本地虚拟机不需要。

点击OK按钮,IDA会立刻载入ELF开始调试。

例题:SCUCTF新生赛2021-DebugMe

file命令:ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, not stripped

用IDA打开可立刻看到main函数:

int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // eax
  int v4; // edi
  unsigned int v5; // esi
  unsigned int v6; // ecx
  unsigned int v7; // eax
  unsigned int v8; // eax
  int v9; // eax
  int v10; // r9d
  char v11; // si
  char v12; // dl
  char v13; // si
  int v14; // r11d
  char v15; // si
  int v16; // r9d
  char v17; // al
  char v18; // al
  __int64 v20; // [rsp+0h] [rbp-30h]
  int i; // [rsp+8h] [rbp-28h]
  unsigned int v22; // [rsp+Ch] [rbp-24h]
  int v23; // [rsp+10h] [rbp-20h]
  int v24; // [rsp+14h] [rbp-1Ch]
  char *nptr; // [rsp+18h] [rbp-18h]
  const char **v26; // [rsp+20h] [rbp-10h]
  int v27; // [rsp+28h] [rbp-8h]
  int v28; // [rsp+2Ch] [rbp-4h]

  v28 = 0;
  v27 = argc;
  v26 = argv;
  if ( argc == 1 )
  {
    puts("Usage: ./AnotherOs <your number>");
  }
  else if ( v27 == 2 )
  {
    nptr = (char *)v26[1];
    v24 = strtol(nptr, 0LL, 10);
    v3 = ~((unsigned __int16)~(*(_DWORD *)(&v20 - 2) & ~((*((_DWORD *)&v20 - 4) | 0xE15) & (~(unsigned __int16)*((_DWORD *)&v20 - 4) | 0xF1EA))) & (unsigned __int16)~(~(unsigned __int16)*((_DWORD *)&v20 - 4) & (*((_DWORD *)&v20 - 4) | 0xE15) & (~(unsigned __int16)*((_DWORD *)&v20 - 4) | 0xF1EA))) & 0x672 | (~*((_DWORD *)&v20 - 4) ^ (~(unsigned __int8)*((_DWORD *)&v20 - 4) & 0x62 | *(_DWORD *)(&v20 - 2) & 0x2ABDF188)) & 0x2ABDF1EA;
    v4 = *((_DWORD *)&v20 - 4);
    v5 = ~(~(~(~v4 & ~((~v23 | 0x2ABDF1EA) & (v23 | 0xD5420E15))) & ~(v4 & (~v23 | 0x2ABDF1EA) & (v23 | 0xD5420E15)) & ~(~(~v4 & v3) & ~(v4 & ~v3))) & ~(~(~(~v4 & ~((~v23 | 0x2ABDF1EA) & (v23 | 0xD5420E15))) & ~(v4 & (~v23 | 0x2ABDF1EA) & (v23 | 0xD5420E15))) & ~(~v4 & v3) & ~(v4 & ~v3)));
    v6 = v5 & (v5 ^ ~(v4 & ~((v4 | 0xD5420E15) & (~v4 | 0x2ABDF1EA))) & ~(~v4 & (v4 | 0xD5420E15) & (~v4 | 0x2ABDF1EA))) | (~v4 ^ (~v4 & v5 | v4 & ~(~(~v4 & ~((~v23 | 0x2ABDF1EA) & (v23 | 0xD5420E15))) & ~(v4 & (~v23 | 0x2ABDF1EA) & (v23 | 0xD5420E15)) & ~(~(~v4 & v3) & ~(v4 & ~v3))) & ~(~(~(~v4 & ~((~v23 | 0x2ABDF1EA) & (v23 | 0xD5420E15))) & ~(v4 & (~v23 | 0x2ABDF1EA) & (v23 | 0xD5420E15))) & ~(~v4 & v3) & ~(v4 & ~v3)))) & 0x2ABDF1EA;
    v7 = ~((v4 | 0xD5420DCA) & (~v4 | 0x2ABDF235) & ~(~(~v4 & v6) & ~(v4 & ~v6))) & ~(~((v4 | 0xD5420DCA) & (~v4 | 0x2ABDF235)) & ~(~v4 & v6) & ~(v4 & ~v6));
    v8 = ~v7 & (~v7 ^ ~(v4 & ~((v4 | 0xD5420E15) & (~v4 | 0x2ABDF1EA))) & ~(~v4 & (v4 | 0xD5420E15) & (~v4 | 0x2ABDF1EA))) | (~v4 ^ (~v4 & ~v7 | v4 & v7)) & 0x2ABDF1EA;
    v9 = ~(~(~v4 & v8) & ~(v4 & ~v8));
    v22 = ~(~(~(~v4 & ~((~v23 | 0x2ABDF1EA) & (v23 | 0xD5420E15))) & ~(v4 & (~v23 | 0x2ABDF1EA) & (v23 | 0xD5420E15)) & v9) & ~(~(~(~v4 & ~((~v23 | 0x2ABDF1EA) & (v23 | 0xD5420E15))) & ~(v4 & (~v23 | 0x2ABDF1EA) & (v23 | 0xD5420E15))) & ~v9));
    if ( v24 == v22 )
    {
      puts("Correct! Here is your flag:");
      for ( i = 0; i < 34; ++i )
      {
        v10 = *((_DWORD *)&v20 - 4);
        v11 = enc[i] & (enc[i] ^ ~(v10 & ~((v10 | 0x15) & (~(_BYTE)v10 | 0xEA))) & ~(~(_BYTE)v10 & (v10 | 0x15) & (~(_BYTE)v10 | 0xEA))) | (~(_BYTE)v10 ^ (~(_BYTE)v10 & enc[i] | v10 & ~enc[i])) & 0xEA;
        v12 = ~(~(_BYTE)v10 & v11) & ~(v10 & ~v11);
        enc[i] = ~(~((v10 | 0x57) & (~(_BYTE)v10 | 0xA8) & ~v12) & ~(~((v10 | 0x57) & (~(_BYTE)v10 | 0xA8)) & v12));
        v13 = enc[i];
        v14 = *((_DWORD *)&v20 - 4);
        v15 = v13 & (v13 ^ ~(v14 & ~((v14 | 0x15) & (~(_BYTE)v14 | 0xEA))) & ~(~(_BYTE)v14 & (v14 | 0x15) & (~(_BYTE)v14 | 0xEA))) | (~(_BYTE)v14 ^ (~(_BYTE)v14 & v13 | v14 & ~v13)) & 0xEA;
        enc[i] = ~(~(~(~(_BYTE)v14 & ~((~key[i] | 0xEA) & (key[i] | 0x15))) & ~(v14 & (~key[i] | 0xEA) & (key[i] | 0x15)) & ~(~(~(_BYTE)v14 & v15) & ~(v14 & ~v15))) & ~(~(~(~(_BYTE)v14 & ~((~key[i] | 0xEA) & (key[i] | 0x15))) & ~(v14 & (~key[i] | 0xEA) & (key[i] | 0x15))) & ~(~(_BYTE)v14 & v15) & ~(v14 & ~v15)));
        v16 = *((_DWORD *)&v20 - 4);
        v17 = enc[i] & (enc[i] ^ ~(v16 & ~((v16 | 0x15) & (~(_BYTE)v16 | 0xEA))) & ~(~(_BYTE)v16 & (v16 | 0x15) & (~(_BYTE)v16 | 0xEA))) | (~(_BYTE)v16 ^ (~(_BYTE)v16 & enc[i] | v16 & ~enc[i])) & 0xEA;
        v18 = ~(~(~(_BYTE)v16 & v17) & ~(v16 & ~v17));
        enc[i] = ~(~(~(~(_BYTE)v16 & 0xA8) & ~(v16 & 0x57) & v18) & ~(~(~(~(_BYTE)v16 & 0xA8) & ~(v16 & 0x57)) & ~v18));
        putchar(enc[i]);
      }
      putchar(10);
    }
    else
    {
      puts("You have inputted a wrong number.");
      puts("Difficult huh? try to Use IDA Remote Debugger to pass this input!");
      puts("The flag will be automatically decoded and printed!");
    }
  }
  return 0;
}

我们的目标就是动态调试,拿到v22的值,并修改v24的值。

Debug application setup的时候,Parameters给一个不错的整数114514。程序载入之后,我们点击导航栏下面的一个叫Use source-level debugging的图标,并按F5反汇编,开启源码级调试。于是我们很快可以得到下图:


1-v22的值.jpg

接下来改v24。似乎IDA的调试器不能很方便地跳转到某个地址,这里考虑通过汇编来修改寄存器。

找到if(v24 == v22)对应的汇编代码:

.text:00000000004008B3 mov     eax, [rbp+var_1C] ; v24
.text:00000000004008B6 cmp     eax, [rbp+var_24] ; v22
.text:00000000004008B9 jz      short loc_4008ED

在执行完0x4008b3的语句时,将rax的值改成0x5ad,即可进入期望的代码块。接下来可以继续在c伪代码处调试。


2-flag.jpg

免费评分

参与人数 5吾爱币 +11 热心值 +5 收起 理由
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
hanlaoshi + 1 + 1 谢谢@Thanks!
笙若 + 1 + 1 谢谢@Thanks!
zhao7643442 + 1 + 1 用心讨论,共获提升!
ddddhm + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| hans7 发表于 2022-9-12 09:46
目前我在这插图是用的md块+attach块+md块的方式,不知道有没有更优雅的办法,如果不用图床的话qwq

点评

上传论坛,然后用discuz的插入方式贴图就行了,文章还保持用MD格式。  详情 回复 发表于 2022-9-21 16:53
DD0G 发表于 2022-9-12 13:13
kuangnuyishi 发表于 2022-9-12 22:35
pikapika233 发表于 2022-9-13 00:42
感谢分享!
Hmily 发表于 2022-9-21 16:53
hans7 发表于 2022-9-12 09:46
目前我在这插图是用的md块+attach块+md块的方式,不知道有没有更优雅的办法,如果不用图床的话qwq

上传论坛,然后用discuz的插入方式贴图就行了,文章还保持用MD格式。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-23 11:25

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表