# Rev Combined Writeups baby rev, super password cracker, and bored xorboard combined writeup (YBN CTF 2024) ## baby rev basic rev challenge ### Challenge Details > Title: baby rev \ > Description: heres a simple rev challenge! \ > Attachments: `https://ctf.ybn.sg/files/4468f0f63a52b92590e0000d951c4f66/thread` \ > Instance: - Run ```bash strings thread | grep "YBN24{" ``` ![image](https://hackmd.io/_uploads/r1WCnqsXyx.png) Flag: :::spoiler Flag YBN24{s3per_s3cur3_p4ssw0rd_but_h0w_d0_1_st0r3_it?} ::: ## super password cracker basic rev challenge ### Challenge Details > Title: super password checker \ > Description: I created a cool password checker! Check it out! \ > Attachments: `https://ctf.ybn.sg/files/1a31e9b8a6d0012febbcef9acbd0a13c/super_password_checker`\ > Instance: - ### Writeup Run ```bash strings thread ``` Scroll up until you see: ![image](https://hackmd.io/_uploads/B1aJpcsmye.png) Extract flag: ``` }yAd_y4eH v3_y4D_lH LA_sGniRH ts_kc47sH _gnIpp1LH F{42NBY ``` Flag: :::spoiler Flag YBN24{FL1ppIng_s74ck_stRinGs_ALl_D4y_3ve4y_dAy} ::: ## board xorboard XOR Encryption challenge and binary decompilation (YBN CTF 2024) ### Challenge Details > Title: bored xorboard \ > Description: I'm soo boredddddddddddddddddddddddddddddddddd.... \ > Attachments: `https://ctf.ybn.sg/files/db5c771ee092eb628cbc1794cb342585/bored` \ > Instance: - ### Writeup Decompiling in Binary Ninja, we see that the main function is as follows: ```c int32_t main(int32_t argc, char** argv, char** envp) { puts("I'm soo boredddddddddddddddddddd…"); puts("Wanna playy?"); puts("You guess what I'm thinking, and…"); int64_t var_20 = 0; int64_t var_10 = 0; void var_128; __isoc99_scanf("%255s", &var_128); if (strlen(&var_128) == 0x36) { for (int32_t i = 0; i <= 0x35; i += 1) { if (*(i + &data_4080) != (*(&var_128 + i) ^ *(i + &data_4040))) { puts(i / 0xe * 0x1e + "\x1b[31mThats not it\x1b[0m"); break; } var_10 += 1; } } else puts("noooooooooooope :)"); printf("Your score is: %ld!\n", var_10); if (var_10 == 0x36) { puts("\x1b[32mYou got it!"); puts("You got it!\x1b[0m"); } return 0; } ``` The password checking logic is here ```c __isoc99_scanf("%255s", &var_128); ... if (strlen(&var_128) == 0x36) { for (int32_t i = 0; i <= 0x35; i += 1) { if (*(i + &data_4080) != (*(&var_128 + i) ^ *(i + &data_4040))) { puts(i / 0xe * 0x1e + "\x1b[31mThats not it\x1b[0m"); break; } var_10 += 1; } } ... if (var_10 == 0x36) { puts("\x1b[32mYou got it!"); puts("You got it!\x1b[0m"); } ``` Here's how it looks like made a little more understandable: ```py var_128 = input() def check(s: str): for i in range(54): if data_4080[i] != (ord(s[i]) ^ data_4040[i]): return False return True ``` Also, `data_4040` and `data_4080` are here: ![image](https://hackmd.io/_uploads/BJrPT5oXyl.png) Which I transcribed as: ```py data_4040 = [ 16, 81, 150, 239, 172, 93, 210, 27, 136, 169, 78, 135, 164, 53, 10, 51, 0, 1, 6, 31, 156, 13, 66, 75, 120, 89, 190, 183, 148, 229, 122, 99, 240, 177, 118, 79, 140, 189, 178, 123, 104, 9, 46, 231, 132, 149, 234, 147, 224, 97, 230, 127, 124, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] data_4080 = [ 73, 19, 216, 221, 152, 38, 188, 43, 252, 193, 127, 233, 195, 106, 102, 2, 107, 50, 89, 108, 172, 96, 113, 20, 0, 105, 204, 196, 203, 145, 74, 60, 183, 212, 65, 16, 254, 140, 214, 36, 39, 111, 113, 133, 180, 231, 143, 247, 208, 12, 200, 81, 82, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] ``` Both variables are of the same length (54) so no need to worry about that. Basically the check function checks if data_4080 is equivalent to data_4040 XOR s. \ So we want to solve for the flag in: \ $\hspace{2cm}\text{data_4080} = \text{data_4040} \oplus \text{flag}$ \ which can rewrite as: \ $\hspace{2cm}\text{flag} = \text{data_4080} \oplus \text{data_4040}$ Implementing this in Python: ```py from pwn import xor # Plaintext data_4040 = [ 16, 81, 150, 239, 172, 93, 210, 27, 136, 169, 78, 135, 164, 53, 10, 51, 0, 1, 6, 31, 156, 13, 66, 75, 120, 89, 190, 183, 148, 229, 122, 99, 240, 177, 118, 79, 140, 189, 178, 123, 104, 9, 46, 231, 132, 149, 234, 147, 224, 97, 230, 127, 124, 109, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] # Ciphertext data_4080 = [ 73, 19, 216, 221, 152, 38, 188, 43, 252, 193, 127, 233, 195, 106, 102, 2, 107, 50, 89, 108, 172, 96, 113, 20, 0, 105, 204, 196, 203, 145, 74, 60, 183, 212, 65, 16, 254, 140, 214, 36, 39, 111, 113, 133, 180, 231, 143, 247, 208, 12, 200, 81, 82, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ] def check(s: str): for i in range(54): if data_4080[i] != (ord(s[i]) ^ data_4040[i]): return False return True key = xor(data_4040, data_4080).rstrip(b'\x00').decode() print(key) print(f"Password Check: {check(key)}") ``` Flag: :::spoiler Flag YBN24{n0th1ng_l1k3_s0m3_x0rs_t0_Ge7_r1d_Of_b0red0m...} ::: \ \ \ Main Writeups Page: https://hackmd.io/@ctf-lol/ybnctf2024