buu re部分wp(一)(未完待续)

一、[GWCTF 2019] xxor
二、[ACTF ] usualcrypto
三、[GXYCTF 2019] luck_guy

抽空来总结一下这几天做的几道题,因为对大小端序不是很了解总是解不对,唉,认识到了要注意大小端序的重要性。

(大一废物,写的不好还请师傅们指点!)

一、[GWCTF 2019] xxor

主函数就是把我们输入的六个数数变换后的数和sub_400770中的六个数进行比对,相等就对了,所以顺着逻辑推回去。

关键的地方都写注释了,看图哦~
在这里插入图片描述

在这里插入图片描述
所以先要把变换后的数组解出来,看到有大佬用的z3,我太菜了,不会不会。。。其实三个方程三个未知数,手解也不难(好吧,我承认我还是高中水平呜呜呜。。)
在这里插入图片描述
然后把伪代码复制粘贴改一改嗯。。。
(注:dword类型在C++里好像是unsigned long)

#include<iostream>
using namespace std;

unsigned long a1[6] = {
    
     -548868226 ,550153460 ,3774025685 ,1548802262 ,2652626477, -2064448480};
unsigned long flag[6] = {
    
     };

void sub_400686(unsigned long* a1, unsigned long* a, int a2[4])
{
    
    
    __int64 result; // rax
    unsigned int v3; // [rsp+1Ch] [rbp-24h]
    unsigned int v4; // [rsp+20h] [rbp-20h]
    unsigned long v5; // [rsp+24h] [rbp-1Ch]
    unsigned int i; // [rsp+28h] [rbp-18h]

    v3 = *a1;
    v4 = *a;
    v5 = 1166789954 * 64; //v5 = 0;
    for (i = 0; i <= 63; ++i)
    {
    
    
        v4 -= (v3 + v5 + 20) ^ ((v3 << 6) + a2[2]) ^ ((v3 >> 9) + a2[3]) ^ 0x10;
        v3 -= (v4 + v5 + 11) ^ ((v4 << 6) + *a2) ^ ((v4 >> 9) + a2[1]) ^ 0x20;
        v5 -= 1166789954;
    }
    *a1 = v3;
    *a = v4;
}


int main()
{
    
    
    unsigned long k, m;
    int unk[4] = {
    
     2,2,3,4 };

    for (int j = 0; j < 5; j += 2)
    {
    
    
        k = a1[j];     //dword_601078 = *((unsigned long *)&v6 + j);
        m = a1[j + 1];   //dword_60107C = *((unsigned long *)&v6 + j + 1);
                                   //a2 = (char**)&unk_601060;
        sub_400686(&k, &m, unk);     //sub_400686(&dword_601078, &unk_601060);
        flag[j] = k;                 //*((_DWORD*)&v11 + j) = dword_601078;
        flag[j + 1] = m;            //*((_DWORD*)&v11 + j + 1) = dword_60107C;
    }
    for (int i = 0; i <= 5; ++i)
    {
    
    
        printf("%c%c%c", *((char*)&flag[i] + 2), *((char*)&flag[i] + 1), *(char*)&flag[i]);
    }
    return 0;
}

最后就要提一下大小端序的问题了,我一开始用的cout就错了,输出是
在这里插入图片描述
很认真地观察它的话(然而我没有),就会发现它每三个一组(共六组),顺序颠倒了,所以要用printf倒着输出。
在这里插入图片描述
二、[ACTF 2020] usualCrypto

主函数就是把输入的字符串经过sub_401080中的变换后和byte_40E0E4比对,相等即输入正确。

直接看sub_401080函数,一开始的sub_401000是base64换表,可以动态调试得到表。在call sub_401000处下断点,F7步入,然后一直F7单步走,循环几次后,直到要跳转到retn,就是表已经换完了,进入byte_40E0A0查看得到表。
在这里插入图片描述
在这里插入图片描述
中间就是base64加密了,最后还有个sub_401030函数,之前遇到过加减32的变换,不难看出来是大小写变换,数字不变。
在这里插入图片描述
换表base64的题还是用python方便(用C++会很麻烦!),后来看别的师傅的wp,python居然还自带换大小写的功能!呜呜呜我要学python。。。(脚本如下:

import base64
import string

KK='zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9'.swapcase()

flag=''
string1="ABCDEFQRSTUVWXYPGHIJKLMNOZabcdefghijklmnopqrstuvwxyz0123456789+/"
string2="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

flag=KK.translate(str.maketrans(string1,string2))
flag=base64.b64decode(flag)

print(flag)

emm习惯性用C++的我还是用C++做了一遍(太复杂就不贴脚本了)
在这里插入图片描述
三、[GXYCTF 2019] luck_guy

这道题挺友好的嗯
先看patch me,到了跳转的地方改个标志位则跳到get_flag
(不过为什么我要patch它,而不是直接看get_flag呢?想不通。。。
在这里插入图片描述
其实看一下函数,只要你输入的lucky num是偶数就行了emmmm
在这里插入图片描述
进入get_flag,如注释顺序应该是4-5-1
在这里插入图片描述
写脚本,同样要注意大小端序!!

emmm f2的前面好像有个空格,但我加空格的话又不太对,但是它是最后一个啊,那不就是"}"么,我就干脆把它删了。。反推回去的话它是一个del。。。。

#include<iostream>
using namespace std;
#include<cstring>

int main()
{
    
    
    char f1[20] = "GXY{do_not_";
    char f2[8] = "fo`guci";
    char f3[8] = "NULLlll";
    char v1;
    int k = 6;
    for (int j = 0; j <= 7; ++j)
    {
    
    
        if (j % 2 == 1)
            v1 = f2[j] - 2;
        else
            v1 = f2[j] - 1;
        f3[k] = v1;
        k--;
    }
    f3[7] = '\0';
    cout << strcat(f1, f3) << "}";

    
    return 0;
}

昨天还看了一道去年极客大挑战的web,学到了加 Referer头伪造访问地址,和XFF从本地请求。。。唉,最近看了很多wp也认识到了小白跟师傅们的差距,就。。挺绝望的。。。希望我能坚持到成功入门吧

猜你喜欢

转载自blog.csdn.net/m0_51357657/article/details/113419426