ctf——逆向新手题目9 (no-strings-attached) WP

首先用Exeinfo PE打开文件查看信息
在这里插入图片描述
这是 linux 的 32位 ELF 文件 直接用ida32打开,直接进主函数查看伪代码(F5)
在这里插入图片描述
主函数比较简单,各自看一下其功能
第一个 setlocale() 是一个初始化函数,是 c++ 中的自有函数 不影响解题
第二个

int banner()
{
  unsigned int v0; // eax

  v0 = time(0);
  srand(v0);
  wprintf(&unk_80488B0);
  rand();
  return wprintf(&unk_8048960);
}

进入后查看后发现这个函数仅仅是用于输出两句话,没有实际作用
第三个函数

int prompt_authentication()
{
  return wprintf(&unk_80489F8);
}

发现是输出以下的话:
please enter authentication details:
以上三个与解题无关,
关键函数为第四个

void authenticate()
{
  wchar_t ws[8192]; // [esp+1Ch] [ebp-800Ch]
  wchar_t *s2; // [esp+801Ch] [ebp-Ch]

  s2 = decrypt(&s, &dword_8048A90);
  if ( fgetws(ws, 0x2000, stdin) )
  {
    ws[wcslen(ws) - 1] = 0;
    if ( !wcscmp(ws, s2) )
      wprintf(&unk_8048B44);
    else
      wprintf(&unk_8048BA4);
  }
  free(s2);
}

查看代码,发现 decrypt 函数,百度中搜到这是一个解密函数,然后把解出的结果存到s2
先往后看
fgetws函数 是从指定的位置按行读取字符串的函数,结果存储在ws处,就是输入的信息
最后有一个 if 判断输出
ws和s2相等输出了 succes!

在这里插入图片描述
这是判断s2就是我们要得到的flag
我们就接着跟进decrypt函数,查看算法

wchar_t *__cdecl decrypt(wchar_t *s, wchar_t *a2)
{
  size_t v2; // eax
  signed int v4; // [esp+1Ch] [ebp-1Ch]
  signed int i; // [esp+20h] [ebp-18h]
  signed int v6; // [esp+24h] [ebp-14h]
  signed int v7; // [esp+28h] [ebp-10h]
  wchar_t *dest; // [esp+2Ch] [ebp-Ch]

  v6 = wcslen(s);
  v7 = wcslen(a2);
  v2 = wcslen(s);
  dest = (wchar_t *)malloc(v2 + 1);
  wcscpy(dest, s);
  while ( v4 < v6 )
  {
    for ( i = 0; i < v7 && v4 < v6; ++i )
      dest[v4++] -= a2[i];
  }
  return dest;
}

分析代码,传入的s和s2的长度,接着dest = s,再接着对dest处理后,返回出来就是s2的值
这时,我们只需要去找到传入的s和a2,编写脚本,即可得到flag

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

这是a2
在这里插入图片描述
由于字符串的结尾会以\0结尾,在数组后会多出4个0,删除后,就是我们要得到的值

#include <iostream>
using namespace std;
int main()
{
	int i = 0, j = 0, k = 0;
	int s[] =
	{
	 58,  20, 0,   0, 54,   20,   0,   0, 55,   20,   0,   0,
	 59,  20, 0,   0, 128,  20,   0,   0, 122,  20,   0,   0,
	 113, 20, 0,   0, 120,  20,   0,   0, 99,   20,   0,   0,
	 102, 20, 0,   0, 115,  20,   0,   0, 103,  20,   0,   0,
	 98,  20, 0,   0, 101,  20,   0,   0, 115,  20,   0,   0,
	 96,  20, 0,   0, 107,  20,   0,   0, 113,  20,   0,   0,
	 120, 20, 0,   0, 106,  20,   0,   0, 115,  20,   0,   0,
	 112, 20, 0,   0, 100,  20,   0,   0, 120,  20,   0,   0,
	 110, 20, 0,   0, 112,  20,   0,   0, 112,  20,   0,   0,
	 100, 20, 0,   0, 112,  20,   0,   0, 100,  20,   0,   0,
	 110, 20, 0,   0, 123,  20,   0,   0, 118,  20,   0,   0,
	 120, 20, 0,   0, 106,  20,   0,   0, 115,  20,   0,   0,
	 123, 20, 0,   0, 128,  20,   0,   0,
	};
	int a2[] =
	{
	   1,  20,   0,   0,   2,  20,   0,   0,   3,  20,0,   0,
	   4,  20,   0,   0,   5,  20,   0,   0,
	};
	while (i < 152)
	{

		k = s[i++] - a2[j++ % 20];
		if (k > 32)
			cout << (char)k;
	}
	return 0;
}

得到flag为
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值