re入门小题

re入门小题

IDA pro 7.7 全插件版,Lazy IDA为无名侠的版本。

IDA配置看IDA篇。

题目源自b站无名侠

默认有C语言,汇编和python基础

1. base64变表

base64编码原理

类似于进制转换,256->64进制

数据取每6bit->v(0-64)->编码表取出下标v对应的字符

下载T5.exe,ida打开,左栏ctrl+F搜索main相关函数。

在这里插入图片描述

快捷键N改一波名称

在这里插入图片描述

逻辑:异或->base64->比较字符串

跟踪sub_455A94,找到sub_45A3F0函数

在这里插入图片描述

跟踪off_529000,其存放一个字符串地址的偏移量,继续跟踪

在这里插入图片描述

标准编码表
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/

魔改之后的编码表
ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/

只需将魔改之后的编码对应到标准编码表的相同位置,之后再正常解码就行。(比如Z对应到A)

import base64
import time

t1="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
t2="ZYXABCDEFGHIJKLMNOPQRSTUVWzyxabcdefghijklmnopqrstuvw0123456789+/"
c='Wj1gWE9xPSGUQ0KCPCGET09WR1qSzZ'
flag=''
for i in c:
    flag+=t1[t2.index(i)]
flag=bytearray(base64.b64decode(flag+"=="))
for i in range(len(flag)):
    flag[i]^=i
print(bytes(flag))
#b'flag{YOU_FIND_IT_HAHA}'

2. IDA动态调试

ida打开T6.exe

在这里插入图片描述

int __cdecl main_0(int argc, const char **argv, const char **envp)
{
  size_t i; // [esp+190h] [ebp-340h]
  char Str2[264]; // [esp+3A4h] [ebp-12Ch] BYREF
  char Str1[32]; // [esp+4ACh] [ebp-24h] BYREF

  qmemcpy(Str1, &unk_50DE50, 28u);//内存复制28位
  printf("[6] Hi CTFer,Input your flag:");
  scanf("%s", Str2);
  for ( i = 0; i < j__strlen(Str1); ++i )
    Str1[i] = ((i + 1) ^ Str1[i]) - i;
  if ( !j__strcmp(Str1, Str2) )
    printf("you are right\n");
  else
    printf("you are wrong\n");
  return 0;
}

F2打断点,debugger选择local windows debugger,F9开启调试

在这里插入图片描述

输入12345678,在出现的汇编页面F5出伪代码。

在这里插入图片描述

跟踪Str1

在这里插入图片描述

点击字符串开头F,按快捷键A,将其解析成字符串。

在这里插入图片描述

或者选中一片内存,右键->convert->convert to python list(Byte)alt+0查看结果

在这里插入图片描述

a2=[0x46, 0x6C, 0x61, 0x67, 0x7B, 0x54, 0x68, 0x69, 0x73, 0x5F, 0x49, 0x53, 0x5F, 0x54, 0x37, 0x5F, 0x44, 0x45, 0x42, 0x55, 0x47, 0x5F, 0x45, 0x41, 0x53, 0x59, 0x7D]
print(bytes(a2))

Flag{This_IS_T7_DEBUG_EASY}

3. 动态调试解RC4

流密码RC4加密解密是同一个算法

ida打开rc4.exe,搜main函数,改一波名。

观察到sub_FEF057是一个反调试函数且只执行一次,接收用户输入44个字符。

v7要与input最后的值相同。

在这里插入图片描述

直接运行rc4.exe,此时反调试函数已执行,在下图位置打断点。

在这里插入图片描述

debugger->attach to process,选择rc4的进程,以附加形式调试正在运行的程序

在这里插入图片描述
在这里插入图片描述

复制上去,F9运行,跟踪一波input的值(可以shift+F12),记录地址,再F9到第二个断点,此时RC4已完成,查看input的值

867DB6A7C7741F7EF97D8DF3295498D5E9B4B8895B620FC958902BD01E431A94C78A253280FD61950893EBA6

可以在运行到第一个断点时,将input对应的内存右键->paste data成上面的值来验证RC4加密解密算法为同一个。

跟踪v7的值

E415C4EDA62F5610BB13EBAD7556C7BBBBE9B9CC023A509F369069BE7C4244CAC6D4245CD2B924C11893B3EA

同理,在第一个断点通过paste data,再F9运行到第二个断点,可以看到RC4之后的值

在这里插入图片描述

SYC{Pjx_s_Wom3n_cl0thing_1s_S0oo0o0_cute!1i}

4. IDA代码修复与数组识别

打开T7.exe

锁定main函数,它启动了一个定时器来反调试。

在这里插入图片描述

if ( sub_401000(Str, "flag{") != Str || Source[32] != '}' )可以看出Str与Source其实是一个数组,快捷键Y修改Str的长度为52。

跟踪sub_401270,它的返回值未被接收,故快捷键Y改函数返回值类型为void。

*(_BYTE *)(a3 + *(_DWORD *)(a1 + 4 * v4)) = a2[v4];之中的a3应该修改为char *类型来指向一个数组,其中的a1应当为指向4字节(DWORD)的指针int *

在这里插入图片描述

改完后,代码变清晰,a3作为输出,与输入a2存在映射关系。

在这里插入图片描述

同理,修改sub_4011F0,sub_401360的返回值类型为void

跟踪sub_4011F0的dword_404040,右键->array将其转换为数组合,

在这里插入图片描述

此时可得到整个代码的主要逻辑:取flag{}中间的值->异或->映射->比较字符串

import base64
import time
a23=bytearray(b"23gjf13au98hk3a1090zp8qjs41h39jp")
a1=[0x00000004, 0x0000000F, 0x0000000B, 0x0000001E, 0x0000000E, 0x00000014, 0x0000001F, 0x00000009, 0x00000017, 0x00000002, 0x00000019, 0x0000001C, 0x00000012, 0x00000010, 0x00000000, 0x00000008, 0x00000011, 0x00000001, 0x00000015, 0x00000003, 0x0000000A, 0x0000001D, 0x0000000C, 0x00000016, 0x00000018, 0x0000000D, 0x0000001B, 0x00000005, 0x00000007, 0x00000006, 0x00000013, 0x0000001A]
a2=[0]*32
bt_404040=[0x00000053, 0x00000045, 0x0000005C, 0x0000001E, 0x00000050, 0x00000013, 0x0000002F, 0x00000078, 0x00000004, 0x00000053, 0x00000058, 0x0000004A, 0x00000043, 0x00000001, 0x00000041, 0x0000002A, 0x00000008, 0x00000040, 0x00000067, 0x0000002F, 0x0000000C, 0x0000004A, 0x00000012, 0x0000002E, 0x00000041, 0x0000006C, 0x00000005, 0x00000054, 0x00000040, 0x00000012, 0x0000005B, 0x0000004F]
v4=0
while (v4<32):
    a2[v4]=a23[a1[v4]]
    v4+=1
for i in range(32):
    a2[i]^=bt_404040[i]
print(b"flag{"+bytes(a2)+b"}")
#b'flag{5t4t1c_An4lys1s_1s_E4sy_2_me!!!~}'

5. UPX脱壳

upx是一种开源的压缩壳软件

加壳:upx a1.exe

脱壳:upx -d a1.exe (很多时候不管用)

在这里插入图片描述

手动脱壳目标

  1. 找到程序入口点(OEP)
  2. 在原始程序入口地址处设置硬件断点(硬件断点不会修改程序)

ida64打开helloupx11文件,发现其为elf文件,不能在windows运行,故拖入kali虚拟机

ls -al
chmod 777 ./helloupx11 添加可执行权限

在这里插入图片描述

ida查看一下字符串,可以看到是upx加壳

在这里插入图片描述

我们需要用到ida运程调试服务器。在IDA Pro 7.7.220118 SP1\dbgsrv目录下有个linux_server64,将其拖入kali中。

./linux_ser* 启动监听
ifconfig 查看虚拟机ip地址

ida选择remote linux debugger,并输入虚拟机ip,如果端口占用则ps查看进程id再kill -9 PID杀进程

在这里插入图片描述

F2在开头打个软件断点,然后开始调试,F4执行到retn按F7,一直跟踪直到看到如下内存(要转成code才看得到)。

在这里插入图片描述

跟踪unk_401D55,按c解析成代码,再按p创建函数,再按F5查看伪代码

在这里插入图片描述

辨识一波
qword_4190E8[355] -> printf
sub_401190 -> strlen
sub_401130 -> strcmp

跟踪aFlagBffab77df5,看到flag为flag{bffab77df5cea353e2325bb4437c3d0b}

硬件断点

在401D55的endbr64处F2,再右键->edit breakpoint,点上hardware,使其成为硬件断点。

重新开启调试,跟踪到硬件断点处,按U取消定义,选中一片内存按C,按P,按F5看逻辑。

在这里插入图片描述

参考

三叶草二进制招新培训5 - Base64 变表逆向

在这里插入图片描述

  • 13
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值