# Pointer 1 **Code** ``` #include <stdio.h> #include <stdlib.h> #include <string.h> int check_key(char *); int sthIdontknow(char, char); int main(void) { char *usrInp; printf("Key? "); usrInp = (char *)malloc(33); scanf("%s", usrInp); int len = strlen(usrInp); if (len == 32) { int (*check)(char *) = check_key; if (check(&usrInp)) { printf("Correct key.\n"); printf("Flag is: flag{%s}\n", usrInp); } else printf("Wrong key.\n"); } else printf("Invalid.\n"); free(usrInp); return 0; } int check_key(char *key) { char sth[] = "pearldarkk"; char mySth[] = {0x45, 0xd, 0x50, 0x1c, 0x5d, 0xa, 0x46, 0x2d, 0x5e, 0x1f, 0x44, 0x17, 0x54, 0x2d, 0x6, 0x11, 0x54, 0x6, 0x34, 0x7, 0x41, 0xe, 0x52, 0x2d, 0x19, 0x16, 0x3e, 0x1, 0x6, 0x5a, 0x1c, 0x56}; void *c1 = sth, *c2 = key; while (c2 < key + 1 && !(sthIdontknow(*(char *)(c1 + (((char *)c2 - key) % 0xA)), *(char *)c2) ^ *mySth)) { c2 = (char *)c2 + 1; ++*mySth; } if (c2 == key + 1) return 1; return 0; } int sthIdontknow(char b, char k) { char b2; for (size_t i = 0; i < 8; ++i) { if (((b >> i) & 1) == ((k >> i) & 1)) b2 = ((1 << i) ^ -1) & b & 255; else b2 = ((1 << i) & 255) | b; b = (char)b2; } return b; } ``` Đọc chương trình, mình thấy được rằng chương trình yêu cầu cần nhập vào 1 chuỗi có có 32 kí tự và chuỗi mình nhập vào chính là flag. Bài này yêu cầu xét 2 hàm `int check_key(char *key){}` và `int sthIdontknow(char b, char k){}` **int check_key()** `key` là input ta nhập vào , `sth[]` và `mySth[]` là 2 thứ chương trình dùng để check **int sthIdontknow()** Hàm sẽ xor từng kí tự của chuỗi in put ta nhập vào với `sth[] = "pearldarkk"`. Kết quả trả ra chính là `mySth[]` => Ta chỉ cần xor `mySth[]` ngược lại với `sth[]` là ra được flag input cần tìm ## Script ``` #include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { int sth[] = {0x70, 0x65, 0x61, 0x72, 0x6c, 0x64, 0x61, 0x72, 0x6b, 0x6b}; int flag[100]; int mysth[] = {0x45, 0xd, 0x50, 0x1c, 0x5d, 0xa, 0x46, 0x2d, 0x5e, 0x1f, 0x44, 0x17, 0x54, 0x2d, 0x6, 0x11,0x54, 0x6, 0x34, 0x7, 0x41, 0xe, 0x52, 0x2d,0x19, 0x16, 0x3e, 0x1, 0x6, 0x5a, 0x1c, 0x56}; for(int i = 0; i<32;i++) { flag[i] = mysth[i] ^ sth[(i)%10]; printf("%c", flag[i]); } return 0; } ``` > Flag là: flag{5h1n1n'_5t4r5_ju5t_l1k3_ur_sm1l3} -------------------------------------------------------- # Pointer 2 ``` #include <stdio.h> #include <stdlib.h> #include <string.h> int fuzz(char *); int main(int argc, char **argv) { printf("Let's see if you passed the right flag...\n"); if (argc == 2) if (strlen(*(argv + 1)) == 32) if (!fuzz(*(argv + 1))) printf("Wrong Direction."); else if (!strncmp(*(argv + 1), "302753d5b52596eb75b8", 0x14)) if (!strncmp(*(argv + 1) + 20, "9c11cc30e5c7", 12)) printf("True."); else printf("Try again."); else printf("Try again."); else printf("Try again."); else printf("Try again."); } int fuzz(char *key) { char char1[10], char2[10], char3[10], char4[10]; memset(char1, 0, 10); memset(char2, 0, 10); memset(char3, 0, 10); memset(char4, 0, 10); strncpy(char1, key, 8); strncpy(char2, key + 8, 8); strncpy(char3, key + 16, 8); strncpy(char4, key + 24, 8); memset(key, 0, 32); strcat(key, char3); strcat(key, char1); strcat(key, char4); strcat(key, char2); return 1; } ``` Ở bài này khi chạy chương trình ta phải chuyển vào 1 tham số, `argc` phải bằng 2, `argv` là mảng liệt kê các con trỏ. Hàm `fuzz()` đơn giản là chia input mà ta truyền vào làm 4 phần bằng nhau rồi sắp xếp theo thứ tự là 3>1>4>2. Sau đó ta sẽ đối chiếu lại với `"302753d5b52596eb75b8"+"9c11cc30e5c7"` thì sẽ ra flag >Flag: flag{b52596ebcc30e5c7302753d575b89c11}