0x01 dmd-50

img

输入字符串,md5后若为780438d5b6e29db0898bc4f0225935c0则输出正确

img

https://www.cmd5.com/解密

img

但是输入grape不对。

这是因为grape两次md5后才得到780438d5b6e29db0898bc4f0225935c0,而题目中要md5一次就得到780438d5b6e29db0898bc4f0225935c0。卡在这里了。

看了题解才醒悟,将grape md5一次后的得到的字符串,不就可以md5一次得到780438d5b6e29db0898bc4f0225935c0吗。

img

flag就是b781cbb29054db12f88f08c6e161c199,没有前缀。

比较简单,可惜我脑袋没转过弯来。

0x02 Shuffle

img

直接拿到flag。

这种题太浪费时间了。

(话不要说得太满。——《毛选》)

0x03 re2-cpp-is-awesome

题目描述:他们说c++是复杂的,证明他们说的是错的!

忍不住吐槽:其实他们说的是对的。。。

主函数:

img

看着花里胡巧的是吧。

其实那些很长的语句,大多是c++的STL,逆向的时候看着是长,但是正向编程的时候就是一个简单的函数或方法。

这道题比较基础,我没怎么看懂其中的STL,也能做出来

关键代码

img

char_2是char_1,而char_1

img

初步估计就是输入的字符串

判断输入字符串和off_6020A0[dword_6020C0[i_1]]是否相等。off_6020A0是字符型指针,指向

img

dword_6020C0是int数组。

所以就是从dword_6020C0中获取偏移量,再在字符串中获取字符,与输入字符串逐一比较。

获取dword_6020C0的IDC脚本

static main()
{
    auto i,fp;
    fp = fopen("d:\\1.txt","wb");
    auto start = 0x6020c0;
    auto size = 0x60213B - 0x6020c0;
    for(i=start;i<start+size;i++)
    {
        fputc(Byte(i),fp);
    }
    fp.close();
}

解密脚本

s = r'''L3t_ME_T3ll_Y0u_S0m3th1ng_1mp0rtant_A_{FL4G}_W0nt_b3_3X4ctly_th4t_345y_t0_c4ptur3_H0wev3r_1T_w1ll_b3_C00l_1F_Y0u_g0t_1t'''
n = []
with open('1.txt', 'rb')as f:
    data = f.read()
for i,b in enumerate(data):
    if i % 4 == 0:
        n.append(b)
flag = ''
for i in n:
    flag += s[i]
print(flag)

ALEXCTF{W3_L0v3_C_W1th_CL45535}

是不是逻辑很简单?

0x04 crackme

img

见到了一个新壳,nsPack,网上找了个脱壳工具。

img

傻瓜式脱壳

img

不过好像脱的不是很干净,ida打开时弹出几个报错窗口

img

img

不过还是能正常加载出函数来的。

很简单的异或。

img

img

a = [0x74] + [ord(i) for i in 'his_is_not_flag']
b = [0x12,4,8,0x14,0x24,0x5c,0x4a,0x3d,0x56,0x0a,0x10,0x67,0,0x41,0,1,0x46,0x5a,0x44,0x42,0x6e,0x0c,0x44,0x72,0x0c,0x0d,0x40,0x3e,0x4b,0x5f,2,1,0x4c,0x5e,0x5b,0x17,0x6e,0x0c,0x16,0x68,0x5b,0x12]
for i in range(42):
    print(chr(a[i % 16] ^ b[i]),end='')

0x05 re-for-50-plz-50

本题考查mips架构下的逆向。

https://blog.csdn.net/yang_hong_/article/details/51016867

img

这种汇编我没接触过,肯定看不懂呀。

看了题解才发现,就是字符串异或0x37。

x86,x86-64都还没学好,这类型的题先放一放吧。

s = 'cbtcqLUBChERV[[Nh@_X^D]X_YPV[CJ'
for i in s:
    print(chr(ord(i) ^ 0x37),end='')

Reversing-x64Elf-100

1575355115328

加密算法:移位后+1.

很简单的算法。

解密脚本:

v3 = "Dufhbmf"+"pG`imos"+"ewUglpt"
a1 = ''
for i in range(12):
    a1 += v3[(i%3)*7 + (2*(i//3))]
for i in a1:
    print(chr(ord(i)-1),end='')

最初是用c++写的(就是把IDA中的代码改了改),但是不正确。原因在于v3,v4,v5的地址未必连续。

错误脚本:

#include <iostream>
using namespace std;
int main(){
    signed int i; // [rsp+14h] [rbp-24h]
    const char *v3; // [rsp+18h] [rbp-20h]
    const char *v4; // [rsp+20h] [rbp-18h]
    const char *v5; // [rsp+28h] [rbp-10h]
    char a1[16];

    v3 = "Dufhbmf";
    v4 = "pG`imos";
    v5 = "ewUglpt";
    for ( i = 0; i <= 11; ++i ){
          a1[i] = (&v3)[i % 3][2 * (i / 3)];      
    }
    for ( i = 0; i <= 11; ++i ){
          cout<<char(a1[i]-1);  
      }
    return 0;    
} 

IgniteMe

主函数:

看着花里胡巧的,其实关键代码不多。

1575357537830

sub_4011C0:

1575357574529

没啥可说的,直接放解密脚本:

byte_4420B0 = [0x0d,0x13,0x17,0x11,0x2,0x1,0x20,0x1d,0x0c,0x2,0x19,0x2f,0x17,0x2b,0x24,0x1f,0x1e,0x16,0x9,0x0f,0x15,0x27,0x13,0x26,0x0a,0x2f,0x1e,0x1a,0x2d,0x0c,0x22,0x4]
string = list(map(ord, 'GONDPHyGjPEKruv{{pj]X@rF'))
flag = []
for i in range(24):
    flag.append((((string[i] ^ byte_4420B0[i]) - 72) ^ 0x55) & 0x7f)
print(flag)
for i in range(len(flag)):
    if 65 <= flag[i] <= 90:
        flag[i] += 32
    elif 97 <= flag[i] <= 122:
        flag[i] -= 32
print(''.join(map(chr, flag)))

注意一点,异或的运算优先级低于减号。我被这一点坑了十分钟。

srm-50

1575383190071

简直就是明文存储的flag.

把上图中的字符读出来,就是flag.

Windows_Reverse1

1578758322072

加密后的字符串已知,加密如下:

1578758380059

很简单的替换,只是byte_402ff8无法看到数据。

动态轻松获取:

1578758467193

s =   ' '*32 + '~}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(\'&%$#"!'
ss = 'DDCTF{reverseME}'
flag = ''
for i in range(len(ss)):
    flag += chr(s.index(ss[i]))
print(flag)

拿到flag{ZZ[JX#,9(9,+9QY!}后,我没敢提交,没见过这么怪的flag(swpuctf2019 mobile2除外)

Last modification:January 12th, 2020 at 12:02 am