add xmasspirit solve
This commit is contained in:
@@ -9,4 +9,24 @@ letter?
|
|||||||
|
|
||||||
## Flag
|
## Flag
|
||||||
|
|
||||||
|
HTB{4ff1n3_c1ph3r_15_51mpl3_m47h5}
|
||||||
|
|
||||||
|
- See letter.pdf
|
||||||
|
|
||||||
|
## How to solve
|
||||||
|
|
||||||
|
See `decrypt.py`
|
||||||
|
|
||||||
## Progress
|
## Progress
|
||||||
|
|
||||||
|
### Code analysis:
|
||||||
|
- Choose a `randint` `a` from `1` to `mod`, that is not divisible by mod.
|
||||||
|
- Choose a `randint` `b` from `1` to `mod`.
|
||||||
|
- for each byte in `dt`
|
||||||
|
- calculate `(a * byte + b) % mod`
|
||||||
|
- append to output bytes
|
||||||
|
- return bytes when done
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
|
||||||
|
- `s_next = (a * s_prev + b) mod p` is a linear congruential generator
|
||||||
|
|||||||
0
crypto/XMASSpirit/challenge.py
Normal file → Executable file
0
crypto/XMASSpirit/challenge.py
Normal file → Executable file
43
crypto/XMASSpirit/decrypt.py
Executable file
43
crypto/XMASSpirit/decrypt.py
Executable file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/bin/env python
|
||||||
|
|
||||||
|
# the modulus for the lcg prng
|
||||||
|
n = 256
|
||||||
|
# the header of the pdf v1.5 file
|
||||||
|
header = [ 0x25, 0x50, 0x44, 0x46, 0x2d, 0x31, 0x2e ]
|
||||||
|
# primes from 1 to 256
|
||||||
|
primes = [ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251 ]
|
||||||
|
# the lookup table was previously generated, get_factors determines that a=169, b=160
|
||||||
|
lookup = {160:0, 73:1, 242:2, 155:3, 68:4, 237:5, 150:6, 63:7, 232:8, 145:9, 58:10, 227:11, 140:12, 53:13, 222:14, 135:15, 48:16, 217:17, 130:18, 43:19, 212:20, 125:21, 38:22, 207:23, 120:24, 33:25, 202:26, 115:27, 28:28, 197:29, 110:30, 23:31, 192:32, 105:33, 18:34, 187:35, 100:36, 13:37, 182:38, 95:39, 8:40, 177:41, 90:42, 3:43, 172:44, 85:45, 254:46, 167:47, 80:48, 249:49, 162:50, 75:51, 244:52, 157:53, 70:54, 239:55, 152:56, 65:57, 234:58, 147:59, 60:60, 229:61, 142:62, 55:63, 224:64, 137:65, 50:66, 219:67, 132:68, 45:69, 214:70, 127:71, 40:72, 209:73, 122:74, 35:75, 204:76, 117:77, 30:78, 199:79, 112:80, 25:81, 194:82, 107:83, 20:84, 189:85, 102:86, 15:87, 184:88, 97:89, 10:90, 179:91, 92:92, 5:93, 174:94, 87:95, 0:96, 169:97, 82:98, 251:99, 164:100, 77:101, 246:102, 159:103, 72:104, 241:105, 154:106, 67:107, 236:108, 149:109, 62:110, 231:111, 144:112, 57:113, 226:114, 139:115, 52:116, 221:117, 134:118, 47:119, 216:120, 129:121, 42:122, 211:123, 124:124, 37:125, 206:126, 119:127, 32:128, 201:129, 114:130, 27:131, 196:132, 109:133, 22:134, 191:135, 104:136, 17:137, 186:138, 99:139, 12:140, 181:141, 94:142, 7:143, 176:144, 89:145, 2:146, 171:147, 84:148, 253:149, 166:150, 79:151, 248:152, 161:153, 74:154, 243:155, 156:156, 69:157, 238:158, 151:159, 64:160, 233:161, 146:162, 59:163, 228:164, 141:165, 54:166, 223:167, 136:168, 49:169, 218:170, 131:171, 44:172, 213:173, 126:174, 39:175, 208:176, 121:177, 34:178, 203:179, 116:180, 29:181, 198:182, 111:183, 24:184, 193:185, 106:186, 19:187, 188:188, 101:189, 14:190, 183:191, 96:192, 9:193, 178:194, 91:195, 4:196, 173:197, 86:198, 255:199, 168:200, 81:201, 250:202, 163:203, 76:204, 245:205, 158:206, 71:207, 240:208, 153:209, 66:210, 235:211, 148:212, 61:213, 230:214, 143:215, 56:216, 225:217, 138:218, 51:219, 220:220, 133:221, 46:222, 215:223, 128:224, 41:225, 210:226, 123:227, 36:228, 205:229, 118:230, 31:231, 200:232, 113:233, 26:234, 195:235, 108:236, 21:237, 190:238, 103:239, 16:240, 185:241, 98:242, 11:243, 180:244, 93:245, 6:246, 175:247, 88:248, 1:249, 170:250, 83:251, 252:252, 165:253, 78:254, 247:255}
|
||||||
|
|
||||||
|
def get_factors(ct):
|
||||||
|
for b in range(1, n):
|
||||||
|
for prime in primes:
|
||||||
|
for i in range(1, len(header)):
|
||||||
|
if((header[i] * prime + b) % n != ct[i]):
|
||||||
|
break
|
||||||
|
if(i+1 == len(header)):
|
||||||
|
print(f'a:{prime} b:{b}')
|
||||||
|
return (prime, b)
|
||||||
|
return (0,0)
|
||||||
|
|
||||||
|
def generate_lookuptable(a, b):
|
||||||
|
for i in range(0, 256):
|
||||||
|
lt = (i * a + b) % 256
|
||||||
|
print(f'{lt}:{i},', end=" ")
|
||||||
|
|
||||||
|
def decrypt(ct):
|
||||||
|
res = b''
|
||||||
|
for byte in ct:
|
||||||
|
dec = lookup[byte]
|
||||||
|
res += bytes([dec])
|
||||||
|
return res
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# open encrypted file
|
||||||
|
ct = open('encrypted.bin', 'rb').read()
|
||||||
|
#a,b = get_factors(ct)
|
||||||
|
#generate_lookuptable(169, 160)
|
||||||
|
dec = decrypt(ct)
|
||||||
|
# write decrypted file
|
||||||
|
with open('letter.pdf', 'wb') as f:
|
||||||
|
f.write(dec)
|
||||||
BIN
crypto/XMASSpirit/letter.pdf
Normal file
BIN
crypto/XMASSpirit/letter.pdf
Normal file
Binary file not shown.
Reference in New Issue
Block a user