首页
社区
课程
招聘
[原创] kctf 第六题 寻回宝剑 wp
2021-5-19 01:14 7321

[原创] kctf 第六题 寻回宝剑 wp

2021-5-19 01:14
7321

思考过程

拿到exe后,拿到ida中发现很多垃圾指令,不过仔细观察发现还是有固定的模式的,用idapython去了一些混淆,但是效果还是不够明显,指令还是很多,自己想了一个骚操作,就是可以利用ida的trace日志,里面是指令的执行过程等信息,然后用notepad的模糊替换,加上去除空行的功能,把指令清洗成下面这样
图片描述
没截图全,只是讲下方法。

算法分析

把指令清洗后,舒服了很多,不过靠上面那些还是不够,上面只是辅助我们的下断点以及调试,加快速度,然后发现算法的流程是这样的,输入84个字符,字符的范围在0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-/%=,同时要满足相邻的4位,满足x10x2a+y1<x20x2a+y2, 然后其实这个就是一个4242的表,然后呢,我们的输入,要保证让这个表每个点行列中只有它一个,唯一性,有点类似n皇后,不过和n皇后还是有区别的,然后就是相同的行间隔,列间隔不能相同,这里有个坑点,就是最后的比较,其实已经给出了前14行的点填法了,那么就缩小了范围,否则爆破跑不出来,放下exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include<iostream>
#include<cstring>
#include<map>
using namespace std;
const int maxm=2e3+5;
//02152S3X4Z5Q6C7T819/ADB%C*DL
//0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-*/%=
string temp="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+-*/%=";
string pre="02152S3X4Z5Q6C7T819/ADB%C*DL";
int to[maxm];
char rev[maxm];
int a[maxm];
int n=42;
int mp[maxm][maxm];
int cnt=0;
int used[maxm];
void init(){
    int idx=0;
    for(auto i:temp) {
        idx++;
        to[i] = idx;
        rev[idx] = i;
    }
    int len=pre.size();
    for(int i=0;i<len;i+=2){
        int pos=to[pre[i]];
        int val=to[pre[i+1]];
        a[pos]=val;
        used[val]=1;
    }
    int j=1;
    for(int i=1;i<=n;i++){
        if(a[i])continue;
        while(used[j])j++;
        a[i]=j;
        used[j]=1;
    }
    len/=2;
    cout<<"pre_len="<<len<<endl;
    for(int i=1;i<=14;i++){
        for(int j=1;j<i;j++){
            int x=i-j;
            int y=a[i]-a[j];
            if(y<0)y=-y,x=-x;
            x+=100;
            mp[x][y]=1;
        }
    }
}
void dfs(int cur){
    cnt++;
    if(cnt%1000000==0){
        cout<<"cnt="<<cnt<<endl;
    }
    //cout<<cur<<' '<<n<<endl;
    if(cur==n+1){
        for(int i=1;i<=n;i++){
            cout<<temp[i-1]<<rev[a[i]];
        }
        cout<<endl;
        return;
    }
    for(int i=cur;i<=n;i++){
        //cout<<cur<<' '<<i<<endl;
        int ok=1;
        for(int j=1;j<cur;j++){
            int x=cur-j;
            int y=a[i]-a[j];
            if(y<0)y=-y,x=-x;
            x+=100;
            if(mp[x][y]){
                ok=0;break;
            }
        }
        if(ok){
            for(int j=1;j<cur;j++){
                int x=cur-j;
                int y=a[i]-a[j];
                if(y<0)y=-y,x=-x;
                x+=100;
                mp[x][y]=1;
            }
            swap(a[i],a[cur]);
            dfs(cur+1);
            swap(a[i],a[cur]);
            for(int j=1;j<cur;j++){
                int x=cur-j;
                int y=a[i]-a[j];
                if(y<0)y=-y,x=-x;
                x+=100;
                mp[x][y]=0;
            }
        }
    }
}
int main(){
    init();
    for(int i=1;i<=n;i++){
        cout<<a[i]<<' ';
    }
    cout<<endl;
    dfs(15);
    return 0;
}

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回