攻防世界-reverse

那年仲夏 提交于 2020-04-07 15:46:30

前言

终于完成例如reverse新手区试题,总结一下

第一题 Hello, CTF

下载文件直接IDA打开。main函数如下

int __cdecl main(int argc, const char **argv, const char **envp)
{
  signed int v3; // ebx
  char v4; // al
  int result; // eax
  int v6; // [esp+0h] [ebp-70h]
  int v7; // [esp+0h] [ebp-70h]
  char v8; // [esp+12h] [ebp-5Eh]
  char v9[20]; // [esp+14h] [ebp-5Ch]
  char v10; // [esp+28h] [ebp-48h]
  __int16 v11; // [esp+48h] [ebp-28h]
  char v12; // [esp+4Ah] [ebp-26h]
  char v13; // [esp+4Ch] [ebp-24h]

  strcpy(&v13, "437261636b4d654a757374466f7246756e");//关键代码
  while ( 1 )
  {
    memset(&v10, 0, 0x20u);
    v11 = 0;
    v12 = 0;
    sub_40134B(aPleaseInputYou, v6);
    scanf(aS, v9);
    if ( strlen(v9) > 17 )//如果长度超过了17则程序结束
      break;
    v3 = 0;
//猜测这个函数就是将字符转换为16进制
    do
    {
      v4 = v9[v3];
      if ( !v4 )
        break;
      sprintf(&v8, asc_408044, v4);//将十六进制转换为字符格式并传给v8
      strcat(&v10, &v8);
      ++v3;
    }
    while ( v3 < 17 );
    if ( !strcmp(&v10, &v13) )//关键代码
      sub_40134B(aSuccess, v7);
    else
      sub_40134B(aWrong, v7);
  }
  sub_40134B(aWrong, v7);
  result = stru_408090._cnt-- - 1;
  if ( stru_408090._cnt < 0 )
    return _filbuf(&stru_408090);
  ++stru_408090._ptr;
  return result;
}
 

int sprintf(char *str, const char *format, ...) 发送格式化输出到 str 所指向的字符串。
关键代码

if ( !strcmp(&v10, &v13) )
      sub_40134B(aSuccess, v7);

v13为437261636b4d654a757374466f7246756e。将其转换为字符串便是flag了。
获取flag:CrackMeJustForFun

第二题 open-source

这题给出的是有个源文件,用记事本打卡都可以。

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[]) {
    if (argc != 4) {
    	printf("what?\n");
    	exit(1);
    }
    //下面函数说明first是0xcafe
    unsigned int first = atoi(argv[1]);
    if (first != 0xcafe) {
    	printf("you are wrong, sorry.\n");
    	exit(2);
    }
//下面函数说明second 为25
    unsigned int second = atoi(argv[2]);
    if (second % 5 == 3 || second % 17 != 8) {//除5取余不得3,除17取余得8
    	printf("ha, you won't get it!\n");
    	exit(3);
    }
//argv[3]=h4cky0u
    if (strcmp("h4cky0u", argv[3])) {//strcmp相同返回0
    	printf("so close, dude!\n");
    	exit(4);
    }
    printf("Brr wrrr grr\n");
    unsigned int hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;
    printf("Get your key: ");
    printf("%x\n", hash);
    return 0;
}
hash = first * 31337 + (second % 17) * 11 + strlen(argv[3]) - 1615810207;
hash = 51966* 31337 + 8 * 11 + 7 - 1615810207;
first=int('cafe',16)//转换为十进制
second=25
argv3='h4cky0u'
hash=int(first * 31337 + (second % 17) * 11 + len(argv3) - 1615810207)
print(hex(hash))//转换为十六进制

第三题simple-unpack

发现存在壳子

upx解压

ida打开,发现flag

点击。flag如下

第四题logmein13

ida识别的伪代码

逆向解题py代码

v8= ":\"AL_RT^L*.?+6/46"
v7 = 'harambe'//X86结构是小端模式,故需要倒过来
v6 = 7
flag =''

for i in range(0,len(v8)):
	flag += chr(ord(v8[i])^ord(v7[i%v6]))
print flag

注: (*((_BYTE *)&v7 + i % v6)此处。们常用的X86结构是小端模式!!!!也是为何v7直接转换为字符是ebmarah,而在上面的py代码中v7 = 'harambe'。

C语言代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[]) {
    unsigned int i;
    char v8[18] = ":\"AL_RT^L*.?+6/46";
    __int64_t v7 = 28537194573619560;
    int v6 = 7;
    char s[18] = "";
    for (i = 0; i < strlen(v8); ++i) {
        s[i] = (char)(*((char*)&v7 + i % v6)^v8[i]);
    }
    printf("%s\n", s);
    system("PAUSE");
    return 0;
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!