攻防 re_parallel-comparator-200

攻防 re_parallel-comparator-200

是一个c语言源文件,打开看到具体代码:

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>		//linux的线程库 ,所以要在linux中才可运行

#define FLAG_LEN 20

void * checking(void *arg) {
    char *result = malloc(sizeof(char));
    char *argument = (char *)arg;
    *result = (argument[0]+argument[1]) ^ argument[2];		//对 first_letter、 differences[i]、 user_string[i]进行简单操作 
    return result;
}

int highly_optimized_parallel_comparsion(char *user_string)
{
    int initialization_number;
    int i;
    char generated_string[FLAG_LEN + 1];
    generated_string[FLAG_LEN] = '\0';

    while ((initialization_number = random()) >= 64);  //无用循环 
    
    int first_letter;
    first_letter = (initialization_number % 26) + 97;	//initialization_number从0~25取值 +97后ASCII对应小写的a~z 

    pthread_t thread[FLAG_LEN];			//创建数组型的线程标识符 ,20线程句柄 
    char differences[FLAG_LEN] = {0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7};	//定义20个元素的char数组 
    char *arguments[20];		//定义20个char型的指针数组 
    for (i = 0; i < FLAG_LEN; i++) {
        arguments[i] = (char *)malloc(3*sizeof(char));		//每个指针指向3个char字节划分的数组头 
        arguments[i][0] = first_letter;		//first_letter由于 initialization_number = random()而未确定 
        arguments[i][1] = differences[i];		//已确定 
        arguments[i][2] = user_string[i];		//用户输入字符,未确定 

        pthread_create((pthread_t*)(thread+i), NULL, checking, arguments[i]);	//调用上面checking函数对arguments三字节数组进行简单操作 
    }

    void *result;	//定义一个数组,用上面的异步线程赋值 
    int just_a_string[FLAG_LEN] = {115, 116, 114, 97, 110, 103, 101, 95, 115, 116, 114, 105, 110, 103, 95, 105, 116, 95, 105, 115};	//定义一个20个元素的数组 
    for (i = 0; i < FLAG_LEN; i++) {
        pthread_join(*(thread+i), &result);		//阻塞线程,让线程一个个执行 
        generated_string[i] = *(char *)result + just_a_string[i];		//把 just_a_string数组加到result中 赋值给 generated_string数组
        free(result);
        free(arguments[i]);
    }

    int is_ok = 1;
    for (i = 0; i < FLAG_LEN; i++) {
        if (generated_string[i] != just_a_string[i])		//这里比较generated_string和 just_a_string数组,而generated_string数组在前面赋值中= *(char *)result + just_a_string[i],所以result等于0才行
            return 0;
    }

    return 1;
}

int main()
{
    char *user_string = (char *)calloc(FLAG_LEN+1, sizeof(char));	//分配21个字符空间,除去0结尾就是20个字符 
    fgets(user_string, FLAG_LEN+1, stdin);	//获取用户输入 
    int is_ok = highly_optimized_parallel_comparsion(user_string);
    if (is_ok)
        printf("You win!\n");
    else
        printf("Wrong!\n");
    return 0;
}

这里补充一下里面出现的我个人没见过的函数:

#include <pthread.h>
int pthread_create(
                 pthread_t *restrict tidp,   //新创建的线程ID指向的内存单元。
                 const pthread_attr_t *restrict attr,  //线程属性,默认为NULL
                 void *(*start_rtn)(void *), //新创建的线程从start_rtn函数的地址开始运行
                 void *restrict arg //默认为NULL。若上述函数需要参数,将参数放入结构中并将地址作为arg传入。
                  );
pthread_create((pthread_t*)(thread+i), NULL, checking, arguments[i]);	//调用上面checking函数对arguments三字节数组进行简单操作 

解题思路

从后往前看,发现 is_ok == 1 的时候符合条件,找到和它相关的部分,即为以下函数:

int highly_optimized_parallel_comparsion(char *user_string)
{
    int initialization_number;
    int i;
    char generated_string[FLAG_LEN + 1];
    generated_string[FLAG_LEN] = '\0';

    while ((initialization_number = random()) >= 64);  //无用循环 
    
    int first_letter;
    first_letter = (initialization_number % 26) + 97;	//initialization_number从0~25取值 +97后ASCII对应小写的a~z 

    pthread_t thread[FLAG_LEN];			//创建数组型的线程标识符 ,20线程句柄 
    char differences[FLAG_LEN] = {0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7};	//定义20个元素的char数组 
    char *arguments[20];		//定义20个char型的指针数组 
    for (i = 0; i < FLAG_LEN; i++) {
        arguments[i] = (char *)malloc(3*sizeof(char));		//每个指针指向3个char字节划分的数组头 
        arguments[i][0] = first_letter;		//first_letter由于 initialization_number = random()而未确定 
        arguments[i][1] = differences[i];		//已确定 
        arguments[i][2] = user_string[i];		//用户输入字符,未确定 

        pthread_create((pthread_t*)(thread+i), NULL, checking, arguments[i]);	//调用上面checking函数对arguments三字节数组进行简单操作 
    }

    void *result;	//定义一个数组,用上面的异步线程赋值 
    int just_a_string[FLAG_LEN] = {115, 116, 114, 97, 110, 103, 101, 95, 115, 116, 114, 105, 110, 103, 95, 105, 116, 95, 105, 115};	//定义一个20个元素的数组 
    for (i = 0; i < FLAG_LEN; i++) {
        pthread_join(*(thread+i), &result);		//阻塞线程,让线程一个个执行 
        generated_string[i] = *(char *)result + just_a_string[i];		//把 just_a_string数组加到result中 赋值给 generated_string数组
        free(result);
        free(arguments[i]);
    }

    int is_ok = 1;
    for (i = 0; i < FLAG_LEN; i++) {
        if (generated_string[i] != just_a_string[i])		//这里比较generated_string和 just_a_string数组,而generated_string数组在前面赋值中= *(char *)result + just_a_string[i],所以result等于0才行
            return 0;
    }

    return 1;
}

当generated_string[i] == just_a_string[i]的时候返回1,is_ok == 1

又因为

generated_string[i] = *(char *)result + just_a_string[i];	

所以成功的条件是result == 0;然后寻找result有关的函数

pthread_create((pthread_t*)(thread+i), NULL, checking, arguments[i]);

在上面代码中,调用了checking函数:

void * checking(void *arg) {
    char *result = malloc(sizeof(char));
    char *argument = (char *)arg;
    *result = (argument[0]+argument[1]) ^ argument[2];		//对 first_letter、 differences[i]、 user_string[i]进行简单操作 
    return result;
}

arguments[ i ] [ 0 ] = first_letter; //(initialization_number % 26) + 97
arguments[ i ] [ 1 ] = differences[i]; //{0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7};
arguments[ i ] [ 2 ] = user_string[i]; //用户输入

因为result == 0,所以 (argument[0]+argument[1]) == argument[2]

first_letter + differences[i] == user_string[i]

由代码可知first_letter是一个范围在97~122的整数

综上编写如下c语言脚本(爆破方法):

#include <stdio.h>
int main()
{
	char differences[20] = {0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7};
	char flag[50] = {0};
	int i,j;
	for(i=97;i<122;i++)
	{
		for(j=0;j<20;j++)
		{
			
			flag[j] = i+differences[j];
			
			
		}
		printf("%d %s\n",i,flag);
	}
	
	
	
	
	
	
	return 0;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LpDFHSph-1648648273385)(C:\Users\春\AppData\Roaming\Typora\typora-user-images\image-20220330214932802.png)]

第108个看起来比较有意义,即为最终的flag

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zsc_02

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值