[Attachment](https://plaidctf.com/files/prospectin.cdc5496a4fa3697a4e15149f7493ebfb7e576f674e9ebff8990fc2fa0129375b.tgz) Script for **Prospecting** challege: ``` import random import string import copy FLAG_LEN = 64 FLAG_PREFIX = "PCTF{" FLAG_SUFFIX = "}" CHARSET = string.printable.strip() POP_SIZE = 400 GENERATIONS = 10000 MUTATION_RATE = 0.03 ELITE_COUNT = 100 def prospect(buf, fn): fn(buf[0x1b] == 0x32) fn(0xaa == (buf[0x1f] ^ buf[0x18])) fn(0x90 == (buf[0x1f] + buf[0x2e])) fn(0x81 == (buf[0x3b] + buf[0x24])) fn(buf[0xd] == 0xbe) fn(0x64 == buf[0x20]) fn(0x31 == buf[0x1a]) fn(0x39 == buf[0x2a]) fn((buf[0x2d] + buf[0x3f]) == 0x93) fn(buf[0x32] == 0x31) fn(0x38 == (buf[1] + buf[0xf])) fn(0x8e == (buf[0xd] ^ buf[0x23])) fn(0x71 == (buf[1] ^ buf[0x2e])) fn(0xb4 == buf[0x2a]) fn(0x36 == buf[0x13]) fn(buf[0x1c] == buf[0x30]) fn(3 == (buf[0xa] ^ buf[0x21])) fn(buf[0x1e] == 0x76) fn(0x32 == buf[5]) fn((buf[1] ^ buf[0x30]) == 0x85) fn(buf[2] == 0x54) fn(0xe1 == buf[0x17]) fn((buf[9] ^ buf[0x36]) == 0x81) fn(0x61 == (buf[0x35] + buf[0x1a])) fn((buf[0x12] ^ buf[0x39]) == 7) fn((buf[0x12] ^ buf[5]) == 0x56) fn((buf[0xe] + buf[0x35]) == 0x66) fn(0x54 == (buf[0x30] ^ buf[0x38])) fn(0xe5 == buf[0x34]) fn(0x6f == buf[0x24]) fn((buf[0x25] + buf[0x1e]) == 0x66) fn(buf[0x32] == 0x31) fn(0x38 == buf[0x17]) fn(0x34 == buf[0x27]) fn(0x97 == (buf[0x38] + buf[0x13])) fn(0x2d == (buf[0x13] ^ buf[0x32])) fn(0xa4 == (buf[0x22] + buf[1])) fn(0xf4 == (buf[0x2f] + buf[0x26])) fn((buf[0x1b] + buf[0x2f]) == 0x97) fn(0x96 == (buf[0x2f] + buf[0xa])) fn(0x72 == buf[2]) fn(buf[0x3b] == 0x36) fn(0xb1 == buf[0x1c]) fn(8 == (buf[8] ^ buf[0x3a])) fn(0x3a == (buf[2] ^ buf[0x2e])) fn(buf[0x3b] == 0x44) fn(0x12 == buf[0x39]) fn((buf[0x11] ^ buf[0x28]) == 0x5b) fn(buf[0x29] == 0x2a) fn(0x33 == buf[0x29]) fn((buf[0x1a] + buf[0x26]) == 0x3f) fn(0x60 == (buf[0x3d] ^ buf[0])) fn(0x24 == buf[0x15]) fn(0x2d == (buf[5] + buf[0x2b])) fn(buf[0x39] == 0x63) fn(5 == (buf[0x37] ^ buf[0x34])) fn(0x7b == buf[4]) fn((buf[0x10] + buf[9]) == 0xad) fn((buf[0x16] + buf[0x2d]) == 0x98) fn(buf[0x18] == 0x32) fn(buf[0x30] == 0x35) fn(0x5b == (buf[0x36] ^ buf[0x13])) fn(0x99 == (buf[0x36] + buf[0xe])) fn(0xd2 == buf[0x35]) fn((buf[0] ^ buf[0x30]) == 0x65) fn((buf[0x2a] + buf[0x31]) == 0x9a) fn((buf[0x14] + buf[0x1d]) == 0x96) fn(0xda == (buf[0x28] ^ buf[0x32])) fn(0x96 == (buf[0x3c] + buf[0x20])) fn((buf[0x27] + buf[7]) == 0x98) fn(buf[0x32] == buf[0xa]) fn(0x52 == (buf[0x39] ^ buf[0xa])) fn(buf[0x38] == 0x61) fn(buf[0x14] == 0x61) fn((buf[0x3e] ^ buf[8]) == 1) fn(0x30 == (buf[0x2c] ^ buf[0x22])) fn(buf[0x21] == 0x32) fn((buf[0x2f] ^ buf[0x31]) == 4) fn(0x53 == (buf[0x1b] ^ buf[0x16])) fn((buf[0] + buf[0x29]) == 0x83) fn(0xf1 == buf[0x12]) fn(0x35 == buf[0x1c]) fn(buf[0x10] == 0xd3) fn(0x99 == (buf[6] + buf[0x2f])) fn((buf[0x1c] + buf[0x19]) == 0xaf) fn((buf[0x3f] + buf[0x13]) == 0xb3) fn(0x35 == buf[0x1d]) fn(buf[0x3d] == 0x30) fn((buf[0xf] + buf[0x19]) == 0x85) fn(0x4f == (buf[0x14] ^ buf[0x3d])) fn((buf[0x1b] ^ buf[0x32]) == 3) fn((buf[0x3e] + buf[0x33]) == 0x62) fn((buf[0x14] + buf[0x2c]) == 0xc5) fn(0xc9 == (buf[0x2b] + buf[0x12])) fn((buf[9] + buf[0x24]) == 0x68) fn(buf[9] == buf[0x13]) fn((buf[0x13] ^ buf[0x21]) == 4) fn((buf[0x37] + buf[0]) == 0x85) fn(buf[0x16] == 0x61) fn(0x39 == buf[0x11]) fn(buf[0xa] == 0x31) fn(0x30 == buf[0x35]) fn((buf[0x31] + buf[0x3d]) == 0xe9) fn(0x31 == buf[0x32]) fn((buf[0x37] + buf[3]) == 0xbf) fn(0x99 == (buf[0x2d] + buf[0x19])) fn(0x32 == buf[0x2e]) fn(0x97 == (buf[0x18] + buf[0x2b])) fn(buf[0x1a] == 0x31) fn(0x36 == buf[0xe]) fn((buf[3] + buf[0x3e]) == 0x76) fn(buf[0x1b] == 0x32) fn(0x4a == (buf[0x3f] ^ buf[0x2d])) fn((buf[0x2c] + buf[0xe]) == 0xf0) fn(buf[9] == 0xd8) fn((buf[0x3a] + buf[0x3e]) == 0x62) fn(0x93 == (buf[0x3d] + buf[0x16])) fn(2 == (buf[0x33] ^ buf[0x35])) fn(0x32 == buf[0x1b]) fn(7 == (buf[0x32] ^ buf[0x3b])) fn(0x30 == buf[0x34]) fn(buf[0x21] == 0x79) fn(buf[0x3d] == 0x33) fn((buf[0x15] + buf[0x31]) == 0xc5) fn(0x53 == buf[0x24]) fn(buf[0xf] == 9) fn(0xb4 == (buf[0] + buf[0x20])) fn(0x68 == (buf[0xe] + buf[0x33])) fn((buf[0x2b] ^ buf[0xe]) == 0xfb) fn(0x4f == buf[0x3a]) fn(0x3e == buf[0xa]) fn(0xec == buf[0x2f]) fn(0x37 == buf[0x2d]) fn(0xff == (buf[0x16] + buf[0x3b])) fn(0x28 == (buf[0x18] ^ buf[2])) fn(0xd1 == buf[0x30]) fn((buf[0x37] ^ buf[7]) == 0xe8) fn(0x65 == buf[0x2f]) fn((buf[5] + buf[0x39]) == 0xfc) fn((buf[0x18] + buf[5]) == 0x64) fn(2 == (buf[0x22] ^ buf[0x36])) fn(0x36 == buf[9]) fn(0x32 == buf[5]) fn(0x31 == buf[0x1a]) fn(0x32 == buf[0x3c]) fn((buf[4] + buf[7]) == 0xdf) fn(0x34 == buf[0x1f]) fn(0x59 == (buf[0x32] ^ buf[0x34])) fn(0x39 == buf[0x3a]) fn(0x53 == (buf[0xc] ^ buf[0x2b])) fn(buf[7] == 0x61) fn((buf[0x35] ^ buf[7]) == 0x54) fn(0x6a == (buf[0x3b] + buf[6])) fn((buf[0x11] + buf[0x1c]) == 0x6e) fn(0x7b == buf[4]) fn(0x65 == buf[0x23]) fn((buf[0x24] + buf[0x2c]) == 0x96) fn(0x7d == buf[0x3f]) fn(0x5d == (buf[0x1b] ^ buf[0x29])) fn(buf[0x28] == 0x62) fn((buf[0x18] ^ buf[0x15]) == 0x63) fn(0x52 == (buf[0x15] ^ buf[0x13])) fn(0x31 == buf[0xa]) fn((buf[0x25] + buf[6]) == 0x67) fn(buf[6] == 0x7b) fn(0x93 == buf[0x38]) fn((buf[9] ^ buf[0x1d]) == 3) fn(buf[0x2f] == 0xc7) fn(buf[0x1d] == 0x35) fn(0x7d == buf[0x3f]) fn((buf[0x33] + buf[0x26]) == 0x47) fn(0x93 == (buf[0x3c] + buf[0x14])) fn((buf[1] ^ buf[0xf]) == 0x74) fn(0x16 == (buf[0xb] ^ buf[0x3a])) fn(0x31 == buf[0x32]) fn(0xcd == (buf[0] + buf[0x3f])) fn(buf[0x3c] == 0x32) fn(0x63 == buf[0x36]) fn(0x4b == buf[7]) fn((buf[0x1d] ^ buf[0x28]) == 0x57) fn(0x39 == buf[0x3a]) fn(0x56 == (buf[0x21] ^ buf[0x2c])) fn(buf[0x11] == 0x96) fn(buf[0x13] == 0xab) fn((buf[0x3b] + buf[0x33]) == 0xaf) fn(0x7f == buf[0x15]) fn(0xd1 == (buf[0x23] ^ buf[0xb])) fn(0x62 == buf[0x28]) fn((buf[0x12] ^ buf[0xd]) == 0x5e) fn(buf[7] == 0x16) fn((buf[0x36] + buf[6]) == 0x97) fn(buf[0x32] == 0x31) fn(buf[0x2d] == 0x37) fn((buf[0x13] + buf[5]) == 0x68) fn(buf[4] == 0x1a) fn(buf[0x3e] == 0x30) fn((buf[0xc] ^ buf[0x18]) == 4) fn((buf[0x2e] + buf[0x20]) == 0x96) fn(buf[0x22] == 0x61) fn(buf[3] == 0x46) fn(0x97 == (buf[0xb] + buf[0x2f])) fn(0x32 == buf[0x2e]) fn(0x60 == buf[0x19]) fn(buf[9] == 0x36) fn(0x3a == buf[0x1a]) fn((buf[0x37] ^ buf[0x2a]) == 0xc) fn(0x57 == (buf[0x22] ^ buf[0x13])) fn(0x61 == buf[0x38]) fn((buf[0x2b] ^ buf[0x1f]) == 0x51) fn(0x35 == buf[0x37]) fn(0xa9 == buf[9]) fn(0x78 == (buf[0x2e] + buf[3])) fn(0x1f == buf[0x30]) fn(0x9d == (buf[0x23] + buf[0x17])) fn(0x6d == buf[0x24]) fn(6 == (buf[0x1e] ^ buf[0x1c])) fn(0x30 == buf[0x35]) fn(0xf7 == buf[0x14]) fn(buf[0x32] == 0x31) fn((buf[0x3c] + buf[0x2d]) == 0x69) fn(5 == (buf[0x29] ^ buf[0xc])) fn((buf[9] ^ buf[0x2a]) == 0x85) fn(buf[0x20] == 0x64) fn(0x30 == buf[0x35]) fn(0x67 == (buf[0x26] + buf[0x37])) fn(buf[0x20] == buf[0xd]) fn(0x32 == buf[0x24]) fn(buf[0x17] == 0x9b) fn(0x64 == buf[0xd]) fn(buf[8] == 0x31) fn(buf[0x24] == 0x32) fn(0xc3 == buf[0xe]) fn((buf[0x29] + buf[0x15]) == 0x97) fn(0x6a == (buf[0x2d] + buf[0x25])) fn(0x32 == buf[0x20]) fn(buf[0x2c] == 0x64) fn(0x54 == buf[2]) fn(0x54 == (buf[0x23] ^ buf[0x32])) fn(buf[0x33] == 0x32) fn(0x35 == buf[0x30]) fn(buf[0x29] == 0x33) fn(buf[0x1b] == 0x32) fn(0x97 == (buf[0x31] + buf[0x3b])) fn(buf[0x24] == 0x32) fn(buf[0x16] == 0x61) fn((buf[0x37] + buf[4]) == 0x12) fn(0x9e == buf[0x2e]) fn(0x55 == (buf[0x16] ^ buf[0x1f])) fn(0x43 == buf[0x32]) fn(0x38 == buf[0x17]) fn(0xc == buf[0x34]) fn(0x30 == buf[0x34]) fn(buf[0x16] == 0x61) fn(0x36 == buf[0xe]) fn(0x54 == buf[2]) fn(0x50 == (buf[8] ^ buf[0x16])) fn((buf[0x23] + buf[0]) == 0xa7) fn((buf[0x27] + buf[2]) == 0xc7) fn(7 == (buf[0x29] ^ buf[6])) fn((buf[0x21] + buf[0xb]) == 0xa5) fn(0x62 == buf[0x19]) fn(0x31 == buf[0x1a]) fn((buf[0x14] + buf[0x1b]) == 0x23) fn((buf[6] ^ buf[0x23]) == 0x9c) fn(4 == (buf[0xe] ^ buf[0xb])) fn(0x34 == buf[0x27]) fn((buf[0x28] + buf[0x1f]) == 0x96) fn(buf[0x39] == 0x63) fn(buf[7] == 0x64) fn(buf[0xe] == 0x36) fn(buf[5] == 0x43) fn((buf[0x17] ^ buf[0x16]) == 0x59) fn(0x64 == buf[0x15]) fn((buf[0x16] ^ buf[0x2c]) == 5) fn(0x30 == buf[0x35]) fn(0x34 == buf[0x1f]) fn(0x61 == buf[0x16]) fn(0x7a == (buf[0x2e] + buf[8])) fn((buf[0x19] ^ buf[3]) == 0x24) fn(buf[0x2b] == 0x65) fn(0xf == buf[0x2c]) fn(0x57 == (buf[0x10] ^ buf[0x15])) fn((buf[9] ^ buf[0x3e]) == 6) fn(buf[0x1b] == 0x32) fn((buf[0x12] + buf[0x36]) == 0xd1) fn(buf[0x20] == 0x64) fn((buf[0x39] + buf[0x12]) == 0xc7) fn(1 == (buf[0x2b] ^ buf[0x20])) fn(buf[0x11] == 0xa4) fn((buf[8] ^ buf[9]) == 7) fn(buf[0x28] == 0x62) fn((buf[0x38] + buf[4]) == 0xa) fn((buf[0x15] + buf[0x1c]) == 0x99) fn(buf[0xc] == 0x7c) fn(0xe1 == (buf[0x3f] + buf[0x12])) fn(buf[0x1b] == 0x32) fn(buf[0x17] == 0x38) fn(0xc8 == (buf[0x2c] + buf[0x12])) fn((buf[9] + buf[0x13]) == 0x6c) fn((buf[0x3d] + buf[0xb]) == 0xe7) fn(0x64 == buf[0x15]) fn((buf[0x39] + buf[0x1f]) == 0x97) fn(0x57 == (buf[0x1c] ^ buf[0x28])) fn(0x37 == buf[0x2d]) fn(0xc9 == (buf[0xd] + buf[0x2f])) fn(buf[0x12] == 0x64) fn(buf[0xf] == 0x37) fn((buf[0x3a] ^ buf[0x10]) == 0xa) fn(0x34 == (buf[0] ^ buf[0x15])) fn((buf[0x3e] + buf[0x31]) == 0x91) fn(buf[0x2e] == 0x32) fn(0xa8 == (buf[0x39] + buf[0])) fn(0x32 == buf[0x24]) fn(0x31 == buf[0x32]) fn(buf[0x30] == 0x35) fn(buf[0x2a] == 0x39) fn((buf[0x3d] + buf[0x23]) == 0x95) fn((buf[0x1b] + buf[1]) == 0x75) fn(buf[0x30] == 0x35) fn((buf[0x23] ^ buf[0x21]) == 0x51) fn((buf[0x1d] ^ buf[0x39]) == 0x56) fn(buf[0x17] == 0x4b) fn((buf[0x1f] + buf[0xd]) == 0xac) fn(buf[0x27] == 0x4a) fn(0x34 == buf[0x27]) fn(0x73 == buf[0x21]) fn(buf[7] == 0x64) fn(0x50 == buf[0]) fn(buf[0x16] == 0x61) fn((buf[0x3e] + buf[0x37]) == 0x65) fn(buf[0x34] == 0x30) fn((buf[7] + buf[0x16]) == 0xcc) fn((buf[0x1a] ^ buf[0xe]) == 7) fn(0x54 == buf[2]) fn(buf[0x2e] == 0x32) fn(0x30 == buf[0x34]) fn(6 == (buf[0x36] ^ buf[0x23])) fn((buf[0x1f] ^ buf[0x22]) == 0x55) fn(buf[0x21] == 0x32) fn((buf[0x28] + buf[0x21]) == 0x94) fn(buf[7] == 0x64) fn(buf[0xf] == 0x37) fn(0x54 == (buf[0xa] ^ buf[0x2b])) fn(buf[0xf] == 0x37) fn(0x68 == (buf[0x1d] + buf[0x1e])) fn(1 == (buf[0x2b] ^ buf[0xd])) fn((buf[0x3a] + buf[0x18]) == 0xd9) fn(0x69 == (buf[0x11] + buf[0x3d])) fn(0xa6 == buf[0x29]) fn((buf[0x36] ^ buf[0x18]) == 0x51) fn(0x30 == buf[0x3e]) fn((buf[0x39] + buf[0x25]) == 0x96) fn(0x4b == (buf[0x3d] ^ buf[4])) fn((buf[0x25] + buf[0x34]) == 0x63) fn(0x3d == (buf[0x15] ^ buf[0x1a])) fn(buf[0x32] == 0xe9) fn(7 == (buf[5] ^ buf[0x1d])) fn(buf[0x1f] == 0x34) fn(buf[0x35] == 1) fn((buf[0xf] + buf[7]) == 0x9b) fn(0x33 == buf[0x29]) fn(0x97 == (buf[0x23] + buf[0x1b])) fn(buf[0x2a] == 0x39) fn(buf[0x1b] == 0x32) fn(buf[0x2f] == 0x65) fn((buf[0x2d] ^ buf[0x1e]) == 4) fn(0x33 == buf[0x1e]) fn(buf[0x16] == 0x61) fn(0x61 == buf[0x31]) fn(0x98 == (buf[0x1f] + buf[0x15])) fn(buf[0x18] == 0x32) fn(buf[0xf] == 0x37) fn(buf[0x23] == 0xcb) fn((buf[4] + buf[0x25]) == 0xae) fn(buf[0x31] == 0x61) fn((buf[7] ^ buf[0x1f]) == 0x50) fn((buf[0xf] + buf[0x13]) == 0x6d) fn((buf[0x1e] ^ buf[0x16]) == 0xc7) fn(1 == (buf[0x10] ^ buf[0x3c])) fn(0x36 == buf[0xc]) fn(buf[0x1c] == 1) fn((buf[0x2c] + buf[0x3a]) == 0x9d) fn((buf[0x31] ^ buf[0x25]) == 0x52) fn(buf[6] == 0x34) fn(0x32 == buf[0x26]) fn(0x30 == buf[0x3e]) fn(0x57 == (buf[0x25] ^ buf[0x15])) fn(0x94 == (buf[0x28] + buf[5])) fn(0x93 == (buf[0xb] + buf[0x22])) fn(0x99 == buf[0x2b]) fn((buf[0x16] + buf[0x1b]) == 0x88) fn(buf[0x2e] == buf[0x26]) fn((buf[0x30] ^ buf[0x3d]) == 5) fn(0x56 == buf[0xc]) fn((buf[0x2c] ^ buf[0x1c]) == 0x51) fn(0x37 == buf[0x2d]) fn(0x67 == (buf[0x25] ^ buf[2])) fn(0x7b == (buf[0x36] ^ buf[0x10])) fn((buf[0x2d] ^ buf[0x12]) == 0x91) fn(0x64 == buf[0x12]) def get_score(buf): global score score = 0 def fn_chal(x): global score if x: score += 1 prospect(list(buf.encode()), fn_chal) return score def random_flag(): middle_len = FLAG_LEN - len(FLAG_PREFIX) - len(FLAG_SUFFIX) middle = ''.join(random.choices(CHARSET, k=middle_len)) return FLAG_PREFIX + middle + FLAG_SUFFIX def mutate(flag): flag = list(flag) for i in range(len(flag)): if random.random() < MUTATION_RATE and i >= len(FLAG_PREFIX) and i < FLAG_LEN - len(FLAG_SUFFIX): flag[i] = random.choice(CHARSET) return ''.join(flag) def crossover(parent1, parent2): idx = random.randint(len(FLAG_PREFIX), FLAG_LEN - len(FLAG_SUFFIX) - 1) child = parent1[:idx] + parent2[idx:] return child population = [random_flag() for _ in range(POP_SIZE)] for gen in range(GENERATIONS): scored = [(flag, get_score(flag)) for flag in population] scored.sort(key=lambda x: x[1], reverse=True) best = scored[0] print(f"Generation {gen} | Score : {best[1]}") if best[1] >= 281: print(f"\nFlag : {best[0]}") break new_population = [f for f, _ in scored[:ELITE_COUNT]] while len(new_population) < POP_SIZE: p1, p2 = random.choices(new_population, k=2) child = mutate(crossover(p1, p2)) new_population.append(child) population = new_population ```