首页
社区
课程
招聘
[原创]KCTF2022第二题WP
发表于: 2022-5-13 09:51 12903

[原创]KCTF2022第二题WP

2022-5-13 09:51
12903

程序运行一下,输入一个字符串然后输出一波结果,看剧情应该是经典砍传奇,让我想起来之前PWNHUB的比赛砍了两天传奇。

IDA打开后找不到程序运行起来的提示字符串,修改一下编码为CP936即可显示

首先根据我们输入的数据计算出来了一个数字v39,

接着生成了一个256大小的table,并使用输入的数据计算出来一个数字

然后把输入转换了一下,数字字符会被转换成数字,其他字符则转成了’>’,

然后根据输入会有一个200大小的数组变换,跟我们输入的前3位字符异或结果进行比对,在比对位置打断点, 多次调试发现结果等于7的时候才能通过检查,所以设置开头3位字符在经过上述变换后,异或结果为7即可

然后是第二个check,检查输入的第四位变换后是否为20,所以直接算出来第四位字符是K(20+55),第五位和第六位check同理,得到>AAKCT:

然后又是一个check:

跟前面原理一样,得到>AAKCTF

下一个运算经过调试发现是将输入的数据分别按位和他自己的位数取余,结果为0,即一个9位数,前n位能被n整除,所以找了一个脚本:

得到很多结果,接着往下看,


是一个冒泡排序,结果会和0123456789比对,这就要求我们上面脚本求出来的结果只包含1234567890,筛选一下结果:

得到:381654729
所以目前flag是>BBKCTF381654729,前三位目前还不确定,往下看:

之前计算出来的数字进行了比对,所以可以把之前的算法抄下来进行一波爆破:

得到flag:421KCTF381654729
后面还有一个检查,脑抽了没看清逻辑被坑了一把,不然有机会拿个一血,yue:

下意识以为这个v20必须大于0才行,经过调试发现这个v20是上述flag后面剩余的字符数量,然后导出来了下面异或比对的两个表,异或结果为[0, 0, 0x9d…],所以后面补了1到2个0,然后这个9d调了半天都输入不进去,甚至试了好几个中文字符,然后查了一下比赛规则只能有ascii,对着加了一个和两个0的flag爆破了半天,最后发觉问题删掉后面的0,直接爆出来了,僵硬。

/*
    输出一个N位数,使它的前n位能被n整除
    回溯
    2014-4-8 21:51:23
*/
 
#include <stdio.h>
 
int n;
char str[15];
 
void backTrack(int k){
    if(k == n + 1){
        for(int i = 1; i <= n; ++i) putchar(str[i]);
        putchar('\n');
        return;
    }
    for(int i = 1; i < 10; ++i){
        int temp = 0;
        for(int j = 1; j < k; ++j)
            temp = temp * 10 + str[j] - '0';
        temp = temp * 10 + i;
        if(temp % k == 0){
            str[k] = i + '0';
            backTrack(k + 1);
        }
    }
}
 
int main(){
    scanf("%d", &n);
    backTrack(1);
    return 0;
}
/*
    输出一个N位数,使它的前n位能被n整除
    回溯
    2014-4-8 21:51:23
*/
 
#include <stdio.h>
 
int n;
char str[15];
 
void backTrack(int k){
    if(k == n + 1){
        for(int i = 1; i <= n; ++i) putchar(str[i]);
        putchar('\n');
        return;
    }
    for(int i = 1; i < 10; ++i){
        int temp = 0;
        for(int j = 1; j < k; ++j)
            temp = temp * 10 + str[j] - '0';
        temp = temp * 10 + i;
        if(temp % k == 0){
            str[k] = i + '0';
            backTrack(k + 1);
        }
    }
}
 
int main(){
    scanf("%d", &n);
    backTrack(1);
    return 0;
}
f = open("./result")
 
l = f.readline()
while l:
    if l.count('1') == 1 and l.count('2') == 1 and l.count('3') == 1 and l.count('4') == 1 and l.count('5') == 1 and l.count('6') == 1 and l.count('7') == 1:
        print(l)
    l = f.readline()
f = open("./result")
 
l = f.readline()
while l:
    if l.count('1') == 1 and l.count('2') == 1 and l.count('3') == 1 and l.count('4') == 1 and l.count('5') == 1 and l.count('6') == 1 and l.count('7') == 1:

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2022-5-13 09:53 被BeFunLab编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (2)
雪    币: 217
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
大佬,想问问下方代码中为啥要异或0x80000000来判断是否加上0xff000000,加这个0xff000000又是何意呢?
        if v11 & 0x80000000:
            temp = (v11 >> 8) + 0xff000000
        else:
            temp = v11 >> 8
2022-5-21 10:58
0
雪    币: 193
活跃值: (268)
能力值: ( LV5,RANK:73 )
在线值:
发帖
回帖
粉丝
3
云觞 大佬,想问问下方代码中为啥要异或0x80000000来判断是否加上0xff000000,加这个0xff000000又是何意呢? if v11 & 0x80000000: ...
与0x80000000是为了判断v11是否是负数,即判断最高位符号位是否为1,如果是1则说明是负数,在python里进行右移会在高位补0,而我们对于负数右移高位应该补1,所以在右移8位之后,要把高位补进来的8位0变成8位1,也就是加0xff000000
2022-5-23 16:39
0
游客
登录 | 注册 方可回帖
返回
//