【攻防世界005】parallel-comparator-200
這是一個源碼閱讀題,涉及Linux多線程和隨機函數的使用。
拿到題目,是如下的C代碼,主函數讀入密鑰,highly_optimized_parallel_comparsion是校驗函數,checking 是線程入口函數。
#include <stdlib.h> #include <stdio.h> #include <pthread.h>#define FLAG_LEN 20void * checking(void *arg) {char *result = malloc(sizeof(char));char *argument = (char *)arg;*result = (argument[0]+argument[1]) ^ argument[2];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;pthread_t thread[FLAG_LEN];char differences[FLAG_LEN] = {0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7};char *arguments[20];for (i = 0; i < FLAG_LEN; i++) {arguments[i] = (char *)malloc(3*sizeof(char));arguments[i][0] = first_letter;arguments[i][1] = differences[i];arguments[i][2] = user_string[i];pthread_create((pthread_t*)(thread+i), NULL, checking, arguments[i]);}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};for (i = 0; i < FLAG_LEN; i++) {pthread_join(*(thread+i), &result);generated_string[i] = *(char *)result + just_a_string[i];free(result);free(arguments[i]);}int is_ok = 1;for (i = 0; i < FLAG_LEN; i++) {if (generated_string[i] != just_a_string[i])return 0;}return 1; }int main() {char *user_string = (char *)calloc(FLAG_LEN+1, sizeof(char));fgets(user_string, FLAG_LEN+1, stdin);int is_ok = highly_optimized_parallel_comparsion(user_string);if (is_ok)printf("You win!\n");elseprintf("Wrong!\n");return 0; }通過閱讀源碼,可知key的長度是20。random函數沒有指定種子,所以每次運行的結果都是一樣的,通過在Linux上實現一個demo,我們可以得到 initialization_number 和 first_letter 的值,其中 first_letter 永遠是 108。
highly_optimized_parallel_comparsion 函數末尾的循環是最終校驗,要求 generated_string 和 just_a_string 這兩個字符串要相等,just_a_string 的值是固定的,根據這行代碼 generated_string[i] = *(char *)result + just_a_string[i] 我們可以推理得到線程返回值必須恒為0。
現在已經知道 checking 的返回值必須恒為0,通過閱讀代碼我們可以知道,argument[0] 永遠是 108,argument[1] 是固定通過 differences 數組獲得的,那么 argument[2] 可以很容易算出來,這個就是正確的key。
下面給出腳本:
differences = [0, 9, -9, -1, 13, -13, -4, -11, -9, -1, -7, 6, -13, 13, 3, 9, -13, -11, 6, -7] just_a_string = [115, 116, 114, 97, 110, 103, 101, 95, 115, 116, 114, 105, 110, 103, 95, 105, 116, 95, 105, 115]for i in range(20):x = 0 ^ (108 + differences[i])print(chr(x), end="") 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的【攻防世界005】parallel-comparator-200的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【攻防世界004】dmd-50
- 下一篇: 【攻防世界006】secret-gala