南宁re SMC

这题flag长度29,切成4部分,分4步验证:

第一步验证,前8位
image.png

因为这是南宁的一个比赛,已经知道了flag的格式, 所以前8位直接可以知道是gxnnctf{,接下来第二步验证
image.png

简单的亦或操作:

    int v5[5];
    v5[0] = 61;
    v5[1] = 11;
    v5[2] = 95;
    v5[3] = 8;
    v5[4] = 67;
    int i=8;
    for(int j=0;j<5;j++){
        cout<<(v5[j]^110)<<" "<<(char)(v5[j]^110)<<" ";
    }

第三步验证,这一步作为OD动态调试试手我觉得挺好的
image.png

这里v11,v12都是可以直接知道的,check数组在这里直接看不出,但是动态调试的时候就可以发现它其实是"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"(这串字符在IDA里直接看到的会少了个A)
image.png

这里的主要操作就是将接下来的9位flag每三位通过4个运算去切取check然后存到v13中去,每3位flag生成4位,具体是这样的

    t=0;
    v13[t++]=check[(第一个 >> 2) & 0x3f] 
    v13[t++]=check[(第二个 >> 4 ) & 0xf | 16 * (第一个 & 3)]
    v13[t++]=check[4 * (第二个 & 0xF) | (第三个 >> 6) & 3]
    v13[t++]=check[第三个 & 0x3f] 

然后是验证切出来的12位
image.png

这里的&v11[1] 我一开始以为是v11[1]的低8位(因为v11是已知的,下意识的就想用现成的)但是其实v11[1]做为一个地址,这里我们需要从OD动态调试取得数据
image.png

EDX存的就是 &v11[1] + v9 了单步12次拿出来跟上面的计算就可以写出脚本了,这里我用了比较笨的方法选择3个3个跑

for(int i=32;i<=126;i++){
        for(int j=32;j<=126;j++){
            for(int k=32;k<=126;k++){
                if(check[(i >> 2) & 0x3f]==(char)a[0]){
                    if(check[(j >> 4) & 0xf | 16 * (i & 3)] == (char)a[1]){
                        if(check[4 * (j & 0xf) | (k >> 6) & 3] == (char)a[2]){
                            if(check[k & 0x3f]==(char)a[3]){
                                cout<<(char)i<<" "<<(char)j<<" "<<(char)k<

接下来最后一步验证,也需要从OD中获得数据
image.png

跟第三步一样动态跑出 &v3 + result -22 就行了
image.png

记下EBX的6个数据

int a[6]={0x61,0x65,0x32,0x66,0x67,0x23};
    for(int i=0;i<6;i++)
        cout<<(char)(a[i]-2)<<" ";
结合四步跑出来的flag就是 gxnnctf{Se1f-M0difying_c0de!}

你可能感兴趣的:(南宁re SMC)