攻防世界
Reverse

1.Hello,CTF

拖入exe
在这里插入图片描述

无壳,拖入32位IDA
发现输入字符串大于17,程序结束0x11 = 17
小于17,则v10与v13比较,相同则输出:aSuccess
而v13一定大于17 ,v13=437261636b4d654a757374466f7246756e
进制转换,发现每位都在1-9 a-f之内,猜测为16位,转换如图
在这里插入图片描述

而题目描述为菜鸡发现Flag似乎并不一定是明文比较的
得到flag为CrackMeJustForFun

2.re1

拖入exe无壳,拖入32位IDA,找到main函数F5反汇编
在这里插入图片描述

看到有个strcmp函数,比较v5和v9,然后判断v3,根据v3给出相应的结果
双击跟进aFlagGet,证明思路正确
跟进xmmword_413E34
在这里插入图片描述

xmmword的值已经出来了:那么v5的值就是3074656D30633165577B465443545544h了
v5应该是16进制表示的,看下strcmp函数,有个将v5转换为字符串的函数
找到在线16进制转换字符串
在这里插入图片描述

通过文字倒序得到DUCTF{We1c0met0
发现flag并不完整,想到题干
在这里插入图片描述

故猜测flag为DUCTF{We1c0met0DUCTF}

3.logmein

拖入exe,无壳,拖入64位IDA,找到main函数,F5反汇编
在这里插入图片描述

__isoc99_scanf(“%32s”, s);
这一行代码就是我们输入的flag
将我们输入的flag的每一位与v7[i%v6]^v8[i]比较,如果有任意一位不相等,则输出“Incorrect password!”
把v7转换成字符型,IDA上直接显示的是
v7 = ‘ebmarah’;
需要注意的是,x86系列的CPU都是以小端序储存数据的,即低位字节存入低地址,高位字节存入高地址,所以正确的字符串应该反过来,即
v7=’harambe’;
脚本:

v7 = 'harambe'
v8 = ':\"AL_RT^L*.?+6/46'
flag = ''
for i in range(len(v8)):
    c = ord(v7[i % 7]) ^ ord(v8[i])
    flag += chr(c)
   
print(flag)

得到flag为RC3-2016-XORISGUD

4.Getit

拖入exe,无壳,拖入64位IDA
在这里插入图片描述

双击跟进p[j]
在这里插入图片描述

可以看到p[i]数组存放的是无序的整数,也就是说每次在/tmp/flag.txt文件中写入的flag是不按顺序写的,且每次只出现一个字符,需要自己排序。
双击跟进t
在这里插入图片描述

发现harifCTF{????????????????????????????????}
53h转换成字符串为‘S’
脚本:

key1="c61b68366edeb7bdce3c6820314b7498"
v5=0
flag=""
while v5 < len(key1):
   if v5 & 1:
      v3=1
   else:
      v3=-1
   flag+=chr(ord(key1[v5])+v3)
   v5+=1
print(flag)

运行得到b70c59275fcfa8aebf2d5911223c6589
所以flag为SharifCTF{b70c59275fcfa8aebf2d5911223c6589}
看到的其他解法:
法二:GDB动态调试
首先我们知道了下面strlen(&t)的t是flag程序运行后生成的flag,那我们把鼠标放在那一行上看一下下面的反汇编行数,如下所示是400824,那么我们在反汇编窗口跟上。
在这里插入图片描述
在这里插入图片描述

可以看到反汇编中400824行的确是_strlen函数,而它上面就是把&t移入了edi,所以在GDB中我们断点400824,然后查看edi寄存器即可。
所需命令:

b *0x400824
r

这里用的是hyperpwn插件:
在这里插入图片描述

可以看到flag就在RDI寄存器里
法三:C语言脚本

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

#pragma warning(disable:4996)

int main(void)
{
    char v3;
    __int64 v5;
    char s[] = "c61b68366edeb7bdce3c6820314b7498";
    char t[] = "SharifCTF{????????????????????????????????}";

    v5 = 0;
    while (v5 < strlen(s)) {
        if (v5 & 1)
            v3 = 1;
        else
            v3 = -1;
        *(t + v5 + 10) = s[v5] + v3;
        v5++;
    }
    printf("%s", t);

    system("PAUSE");
    return 0;
}

法四:在IDA动态截停
在这里插入图片描述

5.no-strings-attached

拖入exe,无壳,拖入32位IDA
找到main函数,F5反汇编
在这里插入图片描述

双击跟进authenticate()函数,分析如下

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

  s2 = (wchar_t *)decrypt(&s, &dword_8048A90); //decrypt表示加密
  if ( fgetws(ws, 0x2000, stdin) ) //进行输入
  {
    ws[wcslen(ws) - 1] = 0;
    if ( !wcscmp(ws, s2) ) //判断输入的ws是否等于加密过后的s2
      wprintf((int)&unk_8048B44); //如果ws=s2,得到unk_8048B44,跟进得到success!
    else
      wprintf((int)&unk_8048BA4);
  }
  free(s2);
}

当 ws 和 s2 相等时,会输出正确结果,那么s2就是flag,而s2经过了decrypt()加密。
那么跟进decrypt()函数:
在这里插入图片描述

它先把参数 s 复制给 dest,与就是s=dest,然后把 dest 的每个值减去 a2 的值,然后再返回加密后的 dest。那么,我们就把s与a2找出来,相减就得到flag。
双击跟进s
在这里插入图片描述

选中按shift+e提取出来
在这里插入图片描述

根据得到的信息写c脚本:

#include <stdio.h>
int main()
{
    int x=0,i=0,j=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 b[] =
    {
       1,  20,   0,   0,   2,  20,   0,   0,   3,  20,
       0,   0,   4,  20,   0,   0,   5,  20,   0,   0,
    };
    while(i < 152)
    {

       x = s[i ++] - b[j ++ % 20];
       if(x>32)
        printf("%c",x);

    }
    return 0;
}

在这里插入图片描述
得到flag为9447{you_are_an_international_mystery}
python脚本为:

s = [5178, 5174, 5175, 5179, 5248, 5242, 5233, 5240, 5219, 5222, 5235, 5223, 5218, 5221, 5235, 5216, 5227, 5233, 5240, 5226, 5235, 5232, 5220, 5240, 5230, 5232, 5232, 5220, 5232, 5220, 5230, 5243, 5238, 5240, 5226, 5235, 5243, 5248]
a = [5121, 5122, 5123, 5124, 5125]
v6 = len(s)
v7 = len(a )
v2 = len(s)

v4=0
while v4<v6:
    
    for i in range(0,5):
        if(i<v7 and v4<v6):
            s[v4]-=a[i]
            v4 += 1
        else:
            break
for i in range (38):
    print(chr(s[i]),end="")