找回密码
 立即注册
注册 登录
×
热搜: 活动 交友 discuz
查看: 104|回复: 1

2019_UNCTF BabyXor

[复制链接]

1

主题

3

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 2022-11-24 20:29:50 | 显示全部楼层 |阅读模式
@TOC 1.WriteUp 2.知识点

声明一点以下可能说的不是很友好,所以如有敏感词汇请评论我,作者会改


WriteUp

下载压缩包,解压得到babyXor.exe文件,习惯步骤:exe文件用PEiD查壳



在这里插入图片描述

UPolyX v0.5 * 作为菜鸡说实话第一见这种壳,以前都是upx壳,所以先用万能脱壳工具FFI进行脱壳



在这里插入图片描述

原谅我这个新手看不懂,所以貌似是无法识别这个壳,那就只能手动脱壳 使用esp脱壳大法,这是今天的一个收获之一 将exe拖到od



在这里插入图片描述

直接调试到jmp那里



在这里插入图片描述

使用od脱壳插件



在这里插入图片描述

脱壳后形成脱壳后的exe文件 由于菜所以只能用ida进行伪代码查看,大神就直接通过od进行分析代码结构,无疑让人羡慕
int __cdecl main_0()
{
  int v0; // ST5C_4
  int v1; // ST6C_4
  char *v2; // ST68_4
  void *v3; // ST64_4
  size_t v4; // eax
  int v5; // ST60_4

  sub_4010B4((int)&unk_4395F0, "世界上最简单的Xor");
  sub_40107D(sub_40102D);
  if ( --stru_436270._cnt < 0 )
  {
    _filbuf(&stru_436270);
  }
  else
  {
    v0 = (unsigned __int8)*stru_436270._ptr;
    ++stru_436270._ptr;
  }
  v1 = sub_40108C(&unk_435DC0, 56);
  v2 = (char *)sub_401041((int)&unk_435DC0, (int)&dword_435DF8, 0x38u);
  v3 = malloc(0x64u);
  v4 = strlen(v2);
  memcpy(v3, v2, v4);
  v5 = sub_4010C3(&unk_435DC0, v2, &dword_435E30, 56);
  sub_40101E(v1, v2, v5);
  return 0;
}根据某个大神的解题思路得到启发,看这些简单一点的代码就应该有flag答案的地方从下往上看函数,看了半天也没有发现flag的踪迹,那就先分析重要函数吧
sub_4010C3(&unk_435DC0, v2, &dword_435E30, 56);
(char *)sub_401041((int)&unk_435DC0, (int)&dword_435DF8, 0x38u);
sub_40108C(&unk_435DC0, 56);
sub_40107D(sub_40102D);
sub_4010B4((int)&unk_4395F0, "世界上最简单的Xor");找到这些重要的函数先不着急,先看传参,并找出其关联
sub_40108C(&unk_435DC0, 56);访问&unk_435DC0



在这里插入图片描述

显然是一个数组,不过在此之间,和我一样的菜鸡注意了,怎么找值 1.找类型,此处类型为db,及占4个字节,及是以四个字节为媒介进行分开 2.看地址,上图是一个地址一个地址进行分开 3.看端序,及所谓小端序(高到低)和大端序(低到高) 又上面3个要点可以得到 435DC0=[0x66,0x6d,0x63,0x64,0x7f,0x37,0x35,0x30,0x30,0x6b,0x3a,0x3c,0x3b,0x20]
(char *)sub_401041((int)&unk_435DC0, (int)&dword_435DF8, 56u);访问&dword_435DF8



在这里插入图片描述

435DF8=[0x37,0x6f,0x38,0x62,0x36,0x7c,0x37,0x33,0x34,0x76,0x33,0x62,0x64,0x7a]
sub_4010C3(&unk_435DC0, v2, &dword_435E30, 56);访问dword_435E30 得到 435E30=[0x1a,0,0,0x51,0x5,0x11,0x54,0x56,0x55,0x59,0x1d,0x9,0x5d,0x12,0,0] 关联:
v2 = (char *)sub_401041((int)&unk_435DC0, (int)&dword_435DF8, 56u);
sub_4010C3(&unk_435DC0, v2, &dword_435E30, 56);可以得到v2的值对sub_4010C3有影响,但是sub_40108C(&unk_435DC0, 56);没有与其有任何关联,所以软柿子肯定要捏一捏,在这之前先可以判断
sub_40107D(sub_40102D);
sub_4010B4((int)&unk_4395F0, "世界上最简单的Xor");这二个函数应该是打印窗口所以暂时可以不要管
//sub_40108C(&unk_435DC0, 56);
char *__cdecl sub_401190(int a1, unsigned int a2)
{
  char *v3; // [esp+4Ch] [ebp-Ch]
  signed int i; // [esp+54h] [ebp-4h]

  v3 = (char *)malloc(a2 >> 2);
  for ( i = 0; i < (signed int)(a2 >> 2); ++i )
    sprintf(&v3, "%c", i ^ *(_DWORD *)(a1 + 4 * i));//435DC0的值与i进行异或得到的结果赋值给v3这个字符串数组
  return v3;
}我们先脚本输出结果一下



在这里插入图片描述

???????flag出现了,而且是断片的,这时就瞬间明白了三个函数可能是进行拼凑flag
//sub_401041((int)&unk_435DC0, (int)&dword_435DF8, 0x38u);
char *__cdecl sub_401240(int a1, int a2, size_t a3)
{
  signed int i; // [esp+4Ch] [ebp-Ch]
  char *v5; // [esp+50h] [ebp-8h]

  v5 = (char *)malloc(a3);//初始化字符串v5
  sprintf(v5, "%c", *(_DWORD *)a2);//将435DF8[0]=v5[0]
  for ( i = 1; i < (signed int)(a3 >> 2); ++i )
    sprintf(&v5, "%c", *(_DWORD *)(a1 + 4 * i) ^ *(_DWORD *)(a2 + 4 * i) ^ *(_DWORD *)(a1 + 4 * i - 4));//v5=435DC0^435DF8^435DC0[i-1]
  return v5;
}得到v5=[55, 100, 54, 101, 45, 52, 53, 54, 52, 45, 98, 100, 99, 97]
//sub_4010C3(&unk_435DC0, v2, &dword_435E30, 56);
char *__cdecl sub_401320(int a1, int a2, int a3, unsigned int a4)
{
  int i; // [esp+4Ch] [ebp-10h]
  char *v6; // [esp+50h] [ebp-Ch]
  char *v7; // [esp+54h] [ebp-8h]

  v7 = (char *)malloc(a4 - 1);
  v6 = (char *)malloc(4 * a4 - 1);
  for ( i = 0; i < (signed int)((a4 >> 2) - 1); ++i )
  {
sprintf(&v6, "%c", *(_DWORD *)(a3 + 4 * i + 4) ^ *(char *)(i + a2));//这里的a2等于上面的v5,所以v6=435E30[i+1]^v5
    sprintf(&v7, "%c", i ^ v6);
  }
  sprintf(&byte_439558, "%c", dword_435E30 ^ dword_435DF8);
  strcat(&byte_439558, v7);
  return &byte_439558;
}Python-writeup:
a1=[0x66,0x6d,0x63,0x64,0x7f,0x37,0x35,0x30,0x30,0x6b,0x3a,0x3c,0x3b,0x20]
a2=[0x37,0x6f,0x38,0x62,0x36,0x7c,0x37,0x33,0x34,0x76,0x33,0x62,0x64,0x7a]
a3=[0x1a,0,0,0x51,0x5,0x11,0x54,0x56,0x55,0x59,0x1d,0x9,0x5d,0x12,0,0]
s=''
s2=[]
for x in range(0,14):
    s+=chr(x ^ a1[x])
print(s)
s+=chr(a2[0])
s2.append(a2[0])
for  x in range(1,14):
    s+=chr(a1[x]^a2[x]^a1[x-1])
    s2.append(a1[x]^a2[x]^a1[x-1])
print(s2)
s+=chr(a3[0]^a2[0])
for x in range(0,13):
    s+=chr(x^(a3[x+1]^s2[x]))

print(s)最终得到flag{2378b077-7d6e-4564-bdca-7eec8eede9a2}


知识点

esp脱壳大法

条件:当按f8后esp变红即可用esp脱壳大法



在这里插入图片描述

使用教程 1.先用先用dd命令转到堆栈刚才esp中的内容指的位置,即dd 0019ff64。随即在该处下硬件断点,如图:



在这里插入图片描述

2.按F9运行,然后我们F8单步走,到了有大跳转时不要再按F8了(这是向上跳转的),我们必须跳过去,因为接下来就有可能是程序的OEP领空



在这里插入图片描述



在这里插入图片描述
回复

使用道具 举报

0

主题

4

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 2025-3-2 17:44:02 | 显示全部楼层
为了三千积分!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋| 黑客通

GMT+8, 2025-4-6 10:43 , Processed in 0.091348 second(s), 23 queries .

Powered by Discuz! X3.4

Copyright © 2020, LianLian.

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