add xmasspirit solve

This commit is contained in:
aaron
2021-12-04 01:44:49 +01:00
parent 935da1c9cd
commit 6a66280e54
4 changed files with 73 additions and 10 deletions

View File

@@ -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
View File

43
crypto/XMASSpirit/decrypt.py Executable file
View 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)

Binary file not shown.