逆向之攻防世界(新手区)(前8题,停更)

本人是个web,迫于生计,也前来学习一点逆向的知识,打算以攻防世界的ctf题来练手,以后会同步更攻防世界的逆向和mobile方向(萌新入门,不对的地方还请师傅多多指教),至于web,另外一个栏目已经有差不多的总结了,也在更新。

1.《re1》

逆向之攻防世界(新手区)(前8题,停更)_第1张图片

先打开查看运行情况

逆向之攻防世界(新手区)(前8题,停更)_第2张图片

然后我们放入exeinfope.exe中查看其可运行版本位,可看出为32位,以下有两种解法,ida和od。

逆向之攻防世界(新手区)(前8题,停更)_第3张图片

1.IDA

之后我们用ida32位的程序打开它,看到main这里之后,进行反汇编按F5,下下图为效果图。

逆向之攻防世界(新手区)(前8题,停更)_第4张图片

逆向之攻防世界(新手区)(前8题,停更)_第5张图片

根据审计顺序做了标记,1.可看到v9这输入值;2,3.strcmp函数将v5和v9进行比较,符合就进入下一步给出正确flag的提示“aflag_0”;4.我们向上寻找v5,发现可以看到开头的_mm_storeu_si128(),对其进行分析发现它将xmmword_413E34的值赋值给v5,所以我们跟进到xmmword_413E34中。

逆向之攻防世界(新手区)(前8题,停更)_第6张图片

这里是十六进制,按下r将其转换为字符串

 这里有个点是大端小端问题。

假设一个十六进制数0x12345678

大端的存储方式是:12,34,56,78,然后读取的时候也是从前往后读

小端的存储方式是:78,56,34,12,然后读取的时候是从后往前读取

最后的flag:DUTCTF{We1c0met0DUTCTF}

2. OD

首先,最简单的直接搜索类似于字符串“flag”的方法就不说了。

打开OD后,一路来到如下图,这里最好还是要结合ida和汇编代码进行分析

逆向之攻防世界(新手区)(前8题,停更)_第7张图片

我们在右侧程序输入后回车,就可以看到右面寄存器有了flag值,在这里cmp即相当于strcmp函数,对应的就可以在寄存器读到对应的比较值--flag

逆向之攻防世界(新手区)(前8题,停更)_第8张图片

2.《game》

逆向之攻防世界(新手区)(前8题,停更)_第9张图片

首先打开看看长啥样,之后用工具得出32位,下面我们分别用ida和od进行解题。

1.IDA

鉴于28行前代码无关紧要就不放在这里占空间了,同时说下如果IDA不能正确的获得自定义函数的名字,那么IDA会用sub__加上自定义函数的起始地址来定义函数的名字

逆向之攻防世界(新手区)(前8题,停更)_第10张图片

35行的v2被赋为输入的值,之后if使v2属于[0,8]

逆向之攻防世界(新手区)(前8题,停更)_第11张图片

在这里我们可以得出使byte_532E28每一位都是1,就会进入sub_457AB4(),我们猜测这可能就是出flag的地方。

继续跟进sub_457AB4()

逆向之攻防世界(新手区)(前8题,停更)_第12张图片

此处省略部分...

逆向之攻防世界(新手区)(前8题,停更)_第13张图片

基本可以推测出后面的为print函数,那么我们只要算出for循环里的就可以拿到flag了,上脚本

a = [123,32,......,126,0]
b = [18,64,......,16,0]
c = 0
flag = ''

while (c<56):
    a[c] ^= b[c]
    a[c] ^= 0x13
    flag = flag + chr(a[c])
    c = c + 1
print(flag)

 

2.OD

首先找到可能为最后flag的地址,跟进

逆向之攻防世界(新手区)(前8题,停更)_第14张图片

图标为1的就是跟进的地址了,我们看标2的地方就是开始我们这个函数的地址,跟着红箭头一路向上找就可以找到跳转的地址

记住这个地址:E37AB4,我们再去寻找失败的地方

继续跟进

到了这,我们只需要覆盖掉就可以直接到达出flag的函数,输入jmp 0xE37AB4

保存文件后输入任意数值即可,逆向之攻防世界(新手区)(前8题,停更)_第15张图片

3.《hello,ctf》

一堆定义,没有用

逆向之攻防世界(新手区)(前8题,停更)_第16张图片

题比较简单,就不细说了,都放在注释了

逆向之攻防世界(新手区)(前8题,停更)_第17张图片

4.《open-source》

根据题目指点,编译后直接对源代码进行分析,下面的注释就是解题过程

#include 
#include 

int main(int argc, char *argv[]) {
    if (argc != 4) {                          //判断输入参数,这里除程序名还需要写3个
    	printf("what?\n");
    	exit(1);
    }

    unsigned int first = atoi(argv[1]);        //第一处输入十进制51966
    if (first != 0xcafe) {
    	printf("you are wrong, sorry.\n");
    	exit(2);
    }

    unsigned int second = atoi(argv[2]);
    if (second % 5 == 3 || second % 17 != 8) {    //第二处逻辑判断,前后两个条件都不能符合
    	printf("ha, you won't get it!\n");
    	exit(3);
    }

    if (strcmp("h4cky0u", argv[3])) {            //第三处比较判断,直接输入h4cky0u
    	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;
}

第二处的脚本

for a range (0,100):
    if (a % 5 != 3 and a % 17 == 8):
        print (a)

得出a可为25,然后得到flag   

5.《insanity》

我醉了。。。小朋友你是否有很多问号

逆向之攻防世界(新手区)(前8题,停更)_第18张图片

6.《simple-unpack》

1.脱壳

逆向之攻防世界(新手区)(前8题,停更)_第19张图片

2.IDA二进制打开

逆向之攻防世界(新手区)(前8题,停更)_第20张图片

 

 

7.《logmein》

void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
  size_t v3; // rsi
  int i; // [rsp+3Ch] [rbp-54h]
  char s[36]; // [rsp+40h] [rbp-50h]
  int v6; // [rsp+64h] [rbp-2Ch]
  __int64 v7; // [rsp+68h] [rbp-28h]
  char v8[8]; // [rsp+70h] [rbp-20h]
  int v9; // [rsp+8Ch] [rbp-4h]

  v9 = 0;
  strcpy(v8, ":\"AL_RT^L*.?+6/46");
  v7 = 28537194573619560LL;                    
  v6 = 7;
  printf("Welcome to the RC3 secure password guesser.\n", a2, a3);
  printf("To continue, you must enter the correct password.\n");
  printf("Enter your guess: ");
  __isoc99_scanf("%32s", s);
  v3 = strlen(s);
  if ( v3 < strlen(v8) )
    sub_4007C0();
  for ( i = 0; i < strlen(s); ++i )
  {
    if ( i >= strlen(v8) )
      sub_4007C0();
    if ( s[i] != (char)(*((_BYTE *)&v7 + i % v6) ^ v8[i]) )  //看到sub_4007c0()为输出错误flag,所以只要满足两边相等即可
      sub_4007C0();
  }
  sub_4007F0();
}

很简单的一段逻辑,不对以上代码进行细致分析了,我们注意到的是在第二个if判断里,有一个对i大小的限制,这里duck不必,直接写脚本实现第三个if两边相等即可得到flag

int main(){

long long v7 = 28537194573619560;
char *a = (char *)&V7;
char V8[] = ":\"AL_RT^L*.?+6/46";

for(int i=0;V8[i]!=0;i++){
V8[i]=V8[i]^a[i%7];
}
cout<

8.《python-trade》

是个pyc文件,反编译一下,网址:https://tool.lu/pyc/   ,下面是反编译的源码

import base64

def encode(message):                     //加密过程,最后来个base64...
    s = ''
    for i in message:
        x = ord(i) ^ 32
        x = x + 16
        s += chr(x)
    
    return base64.b64encode(s)

correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'
flag = ''
print 'Input flag:'
flag = raw_input()
if encode(flag) == correct:
    print 'correct'
else:
    print 'wrong'

解密脚本:

import base64

flag = ""
correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'
b64_flag = base64.b64decode(correct)

for i in b64_flag:
    x = (i-16) ^ 32
    flag += chr(x)
print(flag)

本来是想写完新手区的WP,但是时间原因吧,后面几个题感觉也没有什么写的必要了,之后在本人博客更新免杀等,日后再见

 

你可能感兴趣的:(逆向之攻防世界(入门))