CTF-兴趣是最好的老师 write up

目的:利用010,IDA分别进行对文件的改写和文件的反编译

010editor的简介

010Editor  是一个全新的十六进位文件编辑器 它有别于传统的十六进位编辑器在于它可用'范本'来解析二进位文件, 从而让你读懂和编辑它. 它还可用来比较一切可视的二进位文件.

IDA简介

IDA(interactive Disassembler)交互式反汇编器,IDA最主要的特性是交互和多处理器。操作者可以通过对IDA的交互来指导IDA更好地反汇编,IDA并不自动解决程序中的问题,但它会按用户的指令找到可疑之处,用户的工作是通知IDA怎样去做。比如人工指定编译器类型,对变量名、结构定义、数组等定义等。这样的交互能力在反汇编大型软件时显得尤为重要。多处理器特点是指IDA支持常见处理器平台上的软件产品。IDA支持的文件类型非常丰富,除了常见的PE格式,还支持Windows,DOS,UNIX,Mac,Java,.NET等平台的文件格式

本文以该例题为例

兴趣是最好的老师--

首先将该PE文件改写为正确的,可运行的

然后运行文件,发现程序要求输入flag:

利用view-string,再利用search工具找到flag所在的函数

反编译后的伪C代码如下:

__int64 main_0()
{
  int v0; // edx
  __int64 v1; // ST00_8
  int v3; // [esp+0h] [ebp-1A0h]
  const char **v4; // [esp+4h] [ebp-19Ch]
  const char **v5; // [esp+8h] [ebp-198h]
  int v6; // [esp+Ch] [ebp-194h]
  int i; // [esp+D4h] [ebp-CCh]
  int v8; // [esp+E0h] [ebp-C0h]
  int v9; // [esp+ECh] [ebp-B4h]
  int v10; // [esp+F0h] [ebp-B0h]
  int v11; // [esp+F4h] [ebp-ACh]
  int v12; // [esp+F8h] [ebp-A8h]
  int v13; // [esp+FCh] [ebp-A4h]
  int v14; // [esp+100h] [ebp-A0h]
  int v15; // [esp+104h] [ebp-9Ch]
  int v16; // [esp+108h] [ebp-98h]
  int v17; // [esp+10Ch] [ebp-94h]
  int v18; // [esp+110h] [ebp-90h]
  int v19; // [esp+114h] [ebp-8Ch]
  int v20; // [esp+118h] [ebp-88h]
  int v21; // [esp+11Ch] [ebp-84h]
  int v22; // [esp+120h] [ebp-80h]
  int v23; // [esp+124h] [ebp-7Ch]
  int v24; // [esp+128h] [ebp-78h]
  int v25; // [esp+12Ch] [ebp-74h]
  int v26; // [esp+130h] [ebp-70h]
  int v27; // [esp+134h] [ebp-6Ch]
  int v28; // [esp+138h] [ebp-68h]
  int v29; // [esp+13Ch] [ebp-64h]
  int v30; // [esp+140h] [ebp-60h]
  char v31; // [esp+14Fh] [ebp-51h]
  char v32[17]; // [esp+178h] [ebp-28h]
  char v33; // [esp+189h] [ebp-17h]
  char v34; // [esp+18Ah] [ebp-16h]
  char v35; // [esp+18Bh] [ebp-15h]
  char v36; // [esp+18Ch] [ebp-14h]
  char v37; // [esp+18Dh] [ebp-13h]

  v31 = 0;
  v9 = 1;
  v10 = 4;
  v11 = 14;
  v12 = 10;
  v13 = 5;
  v14 = 36;
  v15 = 23;
  v16 = 42;
  v17 = 13;
  v18 = 19;
  v19 = 28;
  v20 = 13;
  v21 = 27;
  v22 = 39;
  v23 = 48;
  v24 = 41;
  v25 = 42;
  v26 = 26;
  v27 = 20;
  v28 = 59;
  v29 = 4;
  v30 = 0;
  printf("please enter flag:");
  while ( 1 )
  {
    v6 = getch();
    v32[v31] = v6;
    if ( !(_BYTE)v6 || v32[v31] == 13 )
      break;
    if ( v32[v31] == 8 )
    {
      printf("\b\b");
      --v31;
    }
    else
    {
      printf("%c", v32[v31++]);
    }
  }
  v8 = 0;
  for ( i = 0; i < 17; ++i )
  {
    if ( v32[i] != byte_415768[*(&v9 + i)] )
      v8 = 1;
  }
  if ( v33 != 49 || v34 != 48 || v35 != 50 || v36 != 52 || v37 != 125 )
    v8 = 1;
  v32[v31] = 0;
  printf("\r\n");
  if ( v8 )
  {
    printf("wrong\n");
    main(v3, v4, v5);
  }
  else
  {
    printf("success\n");
  }
  system("pause");
  HIDWORD(v1) = v0;
  LODWORD(v1) = 0;
  return v1;
}

 

分析函数可以得知,只有当变量V8=0时,flag才是正确的,所以我们需要满足v8=1不成立的条件,所以通过如下对于各变量的地址值,通过对各变量地址值作为所给字符串形成的字符数组的数组下标分别按计算的顺序取出,即可得到答案

首先先得到数组的值

脚本用C写的,如下

#include<iostream>
#include<cstring>
using namespace std;
int main()
{
	string a="sKfxEeft}f{gyrYgthtyhifsjei53UUrrr_t2cdsef66246087138\0087138";
	char cc[100];
	strncpy(cc,a.c_str(),a.length()+1);
	int num[100]={1,4,14,10,5,36,23,42,13,19,28,13,27,39,48,41,42,26,20,59,4,0};
	for(int i=0;i<17;i++)
	{cout<<cc[num[i]];}
	return 0;
}

python更简单:

a='sKfxEeft}f{gyrYgthtyhifsjei53UUrrr_t2cdsef66246087138\0087138'
b=[1,4,14,10,5,36,23,42,13,19,28,13,27,39,48,41,42,26,20,59,4,0]
for i in range(17):
    print(a[b[i]],end='')
print('1024}')

运行脚本可得到:

KEY{e2s6ry3r5s8f6

此时可以发现,末尾的部分即为第二个条件不成立:

 所以末尾加上'1024}'

最后得到flag:

KEY{e2s6ry3r5s8f61024}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值