Showing posts with label crypto. Show all posts
Showing posts with label crypto. Show all posts

# GynvaelEN mission 018


# curl 'http://gynvael.coldwind.pl/c3459750a432b7449b5619e967e4b82d90cfc971_mission018/admin.php?password1=240610708&password2=10932435112'
Welcome back dear admin.
Your flag: I'm not sure this is how equality is supposed to work.

Now try with <a href='superadmin.php'>superadmin.php</a>!
# curl 'http://gynvael.coldwind.pl/c3459750a432b7449b5619e967e4b82d90cfc971_mission018/superadmin.php'
...
if (hash("sha256", $_GET['password']) ==
'0e12345678901234567890123456789012345678901234567890123456789012')
...
_:)

Source

https://www.youtube.com/watch?v=adHOlKKbFXM (2:00:22)

References

https://www.whitehatsec.com/blog/magic-hashes/

# GynvaelEN mission 017


zeros = '\x00'*32

base64.b64encode(zeros)
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA='

Cookie: mission017session=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
ivencrypted.encode('hex') = '927a00302d2e13896de885ece9f3445d2de83b880d2043a6ecc6e8bbb0a831dc'

result = ''
new = '{"access_level":"admin"}'
for i in range(len(new)):
 result += chr(ord(new[i]) ^ ord(ivencrypted[i]))

base64.b64encode(result) == 6VhhU05LYPoyhOCajJ9mZw+JX+VkTmHb

Cookie: mission017session=6VhhU05LYPoyhOCajJ9mZw%2BJX%2BVkTmHb
Decrypted cookie data: {"access_level":"admin"}
Flag: HMAC? What do you mean "HMAC"?

Source

https://www.youtube.com/watch?v=9xGgZUMNl2Y (2:05:00)

References

https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation

# GynvaelEN mission 016


Wav to image using RX-SSTV

Slow-scan TV is a method to transmit an image over radio using frequency modulation.
This is the partial message that contains the image:

? ? R O N
D I Y M A
U Z ? ? ?
B C K P ?
? ? V W X

Y DHXDMW BQLF KDYNV

Manual decryption

Y D = I A
HX  = ??
DM  = AY
W B = ? P
QL  = ??
F K = ? ?
DY  = IM
NV  = RX

I A??AY? P??? ?AIRX ---> I ALWAYS PLAY FAIRX

Source

https://www.youtube.com/watch?v=locDS3uHv_E (2:03:00)

References

https://en.wikipedia.org/wiki/Slow-scan_television

# GynvaelEN mission 015


# cat mission_15.py
import hashlib
import itertools
import png
import numpy as np

r = png.Reader(file = open('leak.png'))
(width, height, iterator, info) = r.read()

b = [0] * width

for i in iterator:
 row = i.tolist()
 for i in xrange(0, len(row), 3):
  value = row[i:i + 3]
  if value == [255, 0, 0]:
   b[i / 3] += 1

print ''.join([chr(c) for c in b])

hashes = [
 'e6d9fe6df8fd2a07ca6636729d4a615a',
 '273e97dc41693b152c71715d099a1049',
 'bd014fafb6f235929c73a6e9d5f1e458',
 'ab892a96d92d434432d23429483c0a39',
 'b56a807858d5948a4e4604c117a62c2d'
]

alphabet = ' !ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'

password = [' '] * 5
counter = 0

for result in itertools.product(alphabet, repeat = 5):
 word = ''.join(list(result))
 m = hashlib.md5()
 m.update(word)
 hd = m.hexdigest()
 if hd in hashes:
  pos = hashes.index(hd)
  print pos, word
  password[pos] = word
  counter += 1
  if counter == 5: break

print ''.join(password)

# python mission_15.py
<?php

if (!isset($_GET['password']) || !is_string($_GET['password'])) {
  die("bad password");
}

$p = $_GET['password'];

if (strlen($p) !== 25) {
  die("bad password");
}

if (md5($p) !== 'e66c97b8837d0328f3e5522ebb058f85') {
  die("bad password");
}

// Split the password in five and check the pieces.
// We need to be sure!
$values = array(
  0 => 'e6d9fe6df8fd2a07ca6636729d4a615a',
  5 => '273e97dc41693b152c71715d099a1049',
  10 => 'bd014fafb6f235929c73a6e9d5f1e458',
  15 => 'ab892a96d92d434432d23429483c0a39',
  20 => 'b56a807858d5948a4e4604c117a62c2d'
);

for ($i = 0; $i < 25; $i += 5) {
  if (md5(substr($p, $i, 5)) !== $values[$i]) {
    die("bad password");
  }
}

die("GW!");

2  are
0 Pie c
3 delic
1 harts
4 ious!
Pie charts are delicious!

Source

https://www.youtube.com/watch?v=BQRX3owv2JI (1:57:30)

# GynvaelEN mission 010


# cat mission_10.py
from pwn import *

host = '31.133.0.131' #'127.0.0.1'
port = 9393

def get_mask_len():
 i = 64
 while True:
  j = i * 8
  r = remote(host, port)
  r.sendlineafter('\n', 'A' * j)
  re = r.recvuntil('\n')
  r.close()
  if 'Meh' in re:
   break
  i += 1
 return j

def get_secret2():
 b1 = '00000001'
 mask = b1 * (ml / 8)
 r = remote(host, port)
 r.sendlineafter('\n', mask)
 re = r.recvuntil('\n')

 b0 = '0'
 bits = b0 * (ml / 8)
 r.sendline(bits)

 re = r.recvuntil('\n')
 if 'Access Granted' in re:
  for _ in range(4):
   print r.recvuntil('\n')
 r.close()

def get_bits():
 b = ''
 for i in range(len(mask)):
  if mask[i] == '1':
   b += secret1[i]
 return b

def check_result(m, b):
 r = remote(host, port)
 r.sendlineafter('\n', m)
 re = r.recvuntil('\n')
 r.sendline(b)
 re = r.recvuntil('\n')
 r.close()
 return re

def binary_to_str(binary):
 s = ''
 for i in range(0, len(binary), 8):
  b = ''
  for j in range(8):
   b = binary[i + j] + b
  s += chr(int(b, 2))
 return s

def get_secret1():
 for i in range(len(mask)):
  if mask[i] == '0':
   mask[i] = '1'
   tmask = ''.join(mask)
   for j in '01':
    secret1[i] = j
    bits = get_bits()
    if 'Access Granted' in check_result(tmask, bits):
     break


ml = get_mask_len()
get_secret2()

secret1 = ['0'] * ml
mask = [i for i in '00000001'] * (ml / 8)
get_secret1()

print binary_to_str(get_bits())

# python mission_10.py
You have received one secret message:

---

Just Another Secret Message

---

This Crypto Is Absolutely Secure And There Will Be No Problem With It.

Source

https://www.youtube.com/watch?v=Vs8PLpHCoNY (1:45:30)

# AlexCTF: CR5: Bring weakness - 300 pts


Get random numbers

# cat get.py 
from pwn import *

host = '195.154.53.62'
port = 7412

def give_me_the_next_number():
 r.sendlineafter('2: Give me the next number\n', '2')
 number = int(r.recvline())
 return number

r = remote(host, port)

for i in xrange(4):
 print give_me_the_next_number()

r.close()
# python get.py
855109115
895402096
2391280583
300480802

Linear congruential generator

random_n+1 = ((a * random_n) + c) % m
a = multiplier
c = increment
m = modulus

Get modulus

# cat get_modulus.py
from pwn import *

host = '195.154.53.62'
port = 7412

def give_me_the_next_number():
 r.sendlineafter('2: Give me the next number\n', '2')
 number = int(r.recvline())
 return number

def egcd(a, b):
 if a == 0:
  return (b, 0, 1)
 else:
  g, y, x = egcd(b % a, a)
 return (g, x - (b // a) * y, y)

results = []

for i in xrange(20):
 r = remote(host, port)
 last = give_me_the_next_number()
 current = give_me_the_next_number()
 tn = current - last
 last = current
 current = give_me_the_next_number()
 tn1 = current - last
 last = current
 current = give_me_the_next_number()
 tn2 = current - last
 u = abs(tn2*tn - tn1**2) # Important
 r.close()
 results.append(u)

print results

for i in xrange(0, 19):
 print egcd(results[i], results[i+1])[0]

# python get_modulus.py
[312571317250000395, 2949916660717308525, 640738713015133065, 435603004762385760, 2439656571633178950, 11411209872061185300L, 6407385815891338380, 610020832043386185, 1779427408702485555, 149150577634188375, 3371733426053132880, 402697709832197265, 2394242682672509175, 854013216788180865, 829159057095801915, 2030937970488420525, 9719562562552278360L, 4544082617950022895, 157160975107204845, 5385743285459484420L]
12884901885
12884901885
4294967295
8589934590
42949672950
17179869180
4294967295
4294967295
4294967295
4294967295
4294967295
4294967295
55834574835
4294967295
30064771065
4294967295
12884901885
244813135815
12884901885

Modulus = 4294967295 == 2**32 -1

Solve the equation with Wolfram Alfa and get (a, c)

r0 = 855109115
r1 = 895402096
r2 = 2391280583
r3 = 300480802
m = 4294967295
r1 = ((a*r0) + b) mod m
r2 = ((a*r1) + b) mod m
r3 = ((a*r2) + b) mod m

a = 6771334847
c = 6621298821

Get the flag

# cat get_flag.py
from pwn import *

host = '195.154.53.62'
port = 7412

def give_me_the_next_number():
 r.sendlineafter('2: Give me the next number\n', '2')
 number = int(r.recvline())
 return number

def guess_the_next_number(number):
 next = lcg(number)
 r.sendlineafter('2: Give me the next number\n', '1')
 r.sendlineafter('Next number (in decimal) is\n', str(next))
 return next

def lcg(seed):
 a = 6771334847
 c = 6621298821
 m = 4294967295
 return ((seed * a) + c) % m

r = remote(host, port)

seed = give_me_the_next_number()

for i in range(10):
 print seed
 seed = guess_the_next_number(seed)

print r.recvline()
r.close()

# python get_flag.py
604672456
322278383
3842182927
2626463750
2042127376
830485493
3402655117
2936071940
3380135806
3463756493
flag is ALEXCTF{f0cfad89693ec6787a75fa4e53d8bdb5}

References

https://en.wikipedia.org/wiki/Linear_congruential_generator
http://security.stackexchange.com/questions/4268/cracking-a-linear-congruential-generator

# AlexCTF: CR4: Poor RSA - 200 pts


Get modulus and exponent from public key

# openssl rsa -pubin -inform PEM -text -noout < key.pub
Public-Key: (399 bit)
Modulus:
    52:a9:9e:24:9e:e7:cf:3c:0c:bf:96:3a:00:96:61:
    77:2b:c9:cd:f6:e1:e3:fb:fc:6e:44:a0:7a:5e:0f:
    89:44:57:a9:f8:1c:3a:e1:32:ac:56:83:d3:5b:28:
    ba:5c:32:42:43
Exponent: 65537 (0x10001)

Factor the modulus with factordb

# python -c 'print 0x52a99e249ee7cf3c0cbf963a009661772bc9cdf6e1e3fbfc6e44a07a5e0f894457a9f81c3ae132ac5683d35b28ba5c324243'
833810193564967701912362955539789451139872863794534923259743419423089229206473091408403560311191545764221310666338878019
863653476616376575308866344984576466644942572246900013156919
965445304326998194798282228842484732438457170595999523426901

Generate a private key and decrypt the flag

# ipython

In [1]: import gmpy

In [2]: p = 863653476616376575308866344984576466644942572246900013156919

In [3]: q = 965445304326998194798282228842484732438457170595999523426901

In [4]: e = 65537L

In [5]: d = long(gmpy.invert(e,(p-1)*(q-1)))

In [6]: n = p * q

In [7]: from Crypto.PublicKey import RSA

In [8]: key = RSA.construct((n,e,d))

In [9: f = open('flag.b64')

In [10]: edata = f.read()

In [11]: f.close()

In [12]: import base64

In [13]: key.decrypt(base64.b64decode(edata))
Out[13]: 'ALEXCTF{SMALL_PRIMES_ARE_BAD}'

# NN2k16 CTF - moneymoneymoney (extra) (55pts)


# cat moneymoneymoney.py
#!/usr/bin/python

import base58
import bs4
import pyblake2
import re
import requests
import socket
import sys
import uu

def base58encode(hex_addr):
 ha = hex_addr[::-1]
 return base58.b58encode(ha.decode('hex'))


def crack_blake2(bh):
 a = ['0', '1', '2', '3','4','5','6','7','8','9','a','b','c','d','e','f']
 for i1 in a:
     for i2 in a:
  for i3 in a:
      for i4 in a:
   for i5 in a:
       for i6 in a:
    p = i1+i2+i3+i4+i5+i6
    if pyblake2.blake2b(p).hexdigest() == bh:
        return p

def get_bitcoins(addr):
 r = requests.get('https://blockchain.info/address/' + addr)
 soup = bs4.BeautifulSoup(r.text)
 tag = soup.findAll('span', {'data-c': True})
 m = re.findall('>(.*) BTC<', str(tag[1]))
 #return m[0].replace(',', '')
 return m[0]

def rot(text, n):
 I = 32
 F = 126
 a = []

 for i in xrange(I, F + 1):
  a.append(chr(i))

 result = ''
 for i in text:
  oi = ord(i)
  if I <= oi and oi <= F:
   r = (oi - I + n) % len(a)
   result += a[r]
  else:
   result += i
 return result

def shamir_secret(ss1, ss2):
 payload = {'message': ss1[2:] + '\r\n' + ss2[2:]}
 r = requests.post('http://asecuritysite.com/encryption/shamir_decode', data = payload)
 m = re.findall('share of 2: (.*?)\n<', r.text)
 flag = m[0]
 return flag

def uudecode(encoded):
 ui = 'uu.in'
 uo = 'uu.out'

 f = open(ui, 'w')
 f.write(encoded)
 f.close()

 uu.decode(ui, uo)

 f = open(uo)
 decoded = f.read()
 f.close()

 return decoded

def xor(text, key):
 r = ''
 lk = len(key)
 for i in range(len(text)):
  r += chr(ord(text[i]) ^ ord(key[i % lk]))
 return r


HOST = 'challenges.ka0labs.org'
PORT = 1337
DELIMITER = '-' * 32

server_socket = (HOST, PORT)

print server_socket
print DELIMITER

client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(server_socket)

data = client.recv(1024)

print data
print DELIMITER

m = re.findall('= (.*?)\.', data)
blake2_hash = m[0]

print '[+] blake2 hash = ' + blake2_hash 

x = crack_blake2(blake2_hash)

print '[+] x = ' + x
print DELIMITER

client.send(x + '\n')
data = client.recv(1024)
print data
print DELIMITER

m = re.findall('(1-000.*?)\.', data)
shamir_secret_1 = m[0]
print '[+] shamir secret 1 = ' + shamir_secret_1
print DELIMITER

data = client.recv(1024)
print data
print DELIMITER

m = re.findall('([0-9A-Z]+00A)', data)
challenge = m[0]
print '[+] shamir secret 1 = ' + shamir_secret_1
print '[+] challenge = ' + challenge
print DELIMITER

hex_challenge = challenge.decode('hex')
print '[+] hex_challenge = ' + hex_challenge
print DELIMITER

rot52 = rot(hex_challenge, 52)
print '[+] rot52 = ', rot52
print DELIMITER

uud = uudecode(rot52[22:])
print '[+] uudecode = ', uud
print DELIMITER

byte_uud = ''.join(map(chr, map(int, uud[11:].split(','))))
print '[+] byte_uud = ', repr(byte_uud)
print DELIMITER

xored = xor(byte_uud, 'ANDYRLZ')
print '[+] xored = ', xored
print DELIMITER

hex_addr = xored[18:]
bitcoin_addr = base58encode(hex_addr)
print '[+] bitcoin addr = ' + hex_addr + ' --> ' + bitcoin_addr
print DELIMITER

bitcoins = get_bitcoins(bitcoin_addr)
print '[+] bitcoins = ' + bitcoins
print DELIMITER

client.send(bitcoins + '\n')
data = client.recv(1024)
print data
print DELIMITER

m = re.findall('\((.*)\)', data)
shamir_secret_2 = m[0]
print '[+] shamir secret 2 = ' + shamir_secret_2
print DELIMITER
client.close()

flag = shamir_secret(shamir_secret_1, shamir_secret_2)
print '[+] flag = 8===D{' + flag + '}'


# python moneymoneymoney.py
('challenges.ka0labs.org', 1337)
--------------------------------

Welcome to the Dr. Utonium computer! As he usually says, passwords are out-of-style nowadays. So I'm going to test if you're my lovely boss through crypto challenges that only him can solve <3

First of all, let's fight fire with fire. BLAKE2B(X) = b8d1e72b927e9dd122fd4e7cb7574c9b768ad677cf9c0b5435d00c31f0be854efff199ab23dd8f8aa2843321345803b0ad7fd0c0cd3d4090038db421632a68cd. Let me know X. Hint: my $X =~ ^[0-9a-f]{6}$
Solution: 
--------------------------------
[+] blake2 hash = b8d1e72b927e9dd122fd4e7cb7574c9b768ad677cf9c0b5435d00c31f0be854efff199ab23dd8f8aa2843321345803b0ad7fd0c0cd3d4090038db421632a68cd
[+] x = 8d40cf
--------------------------------


Auto-attaching to session 2...
irssi | [email protected] (Ka0chat)
<+MojoJojo> Hi my little minion! I have info that can be useful for you. I don't know when, but I'm sure you are going to need what I found last month sniffing Utonium's communications: 1-000O4LkoDev88CEhevvRqbVSc/Fbh+BS47N0NL0jUoQneR9/Ah+yoYr3qDxzlHJ3EI0MITTz4kCwmxHdKye02rjZIMmduk=. I don't know what it means...:_S
Detaching...

--------------------------------
[+] shamir secret 1 = 1-000O4LkoDev88CEhevvRqbVSc/Fbh+BS47N0NL0jUoQneR9/Ah+yoYr3qDxzlHJ3EI0MITTz4kCwmxHdKye02rjZIMmduk=
--------------------------------

Hmmm...ok, here is your challenge. Hint: !yenom eht em wohS

49657021204E657874212074313C4C4B793144404C4B2E3133353A4B6161614B580A785D61607B535D4C5964626C20535D4B24564E5B7E564E5F7D564E4F7D574D7B7C575E5B77576D7B22577D7B21587D7B21594D7B7C574E4F77575E537C0A78564E537B564E5F77576E4B77574D7B7D564E4F7B575D7B7C576E4F77575E4B7E564E5B23564E4F7B585D7B7E586D7B20584D7B7C575E6B77575E4B200A78564E6F22564E5B23564E4F7B587D7B7E585D7B7C576E4B77575E4F25564E4F7B584D7B20595D7B7C575E6377575E4B22564E5723564E4F7C594D7B7C0A78576E5F77595E6777595E6F77584E4F77575E4B24564E4F7C586D7B7C575E6B77575E4F21564E5F22564E4F7B587D7B20576D7B22576D7B7E595D7B7C0A78576E5F77577E5777586E4F77575E4B7B564E4F7C586D7B22576D7B7C575E6F77575E4F24564E4F7C595D7B7C574E6777585E5377575E5322564E6F240A5E564E4F7C586D7B7C576E6377575E4F7E564E4F7B585D7B25594B4B4B0A4B0A313A300A

Solution: 
--------------------------------
[+] shamir secret 1 = 1-000O4LkoDev88CEhevvRqbVSc/Fbh+BS47N0NL0jUoQneR9/Ah+yoYr3qDxzlHJ3EI0MITTz4kCwmxHdKye02rjZIMmduk=
[+] challenge = 49657021204E657874212074313C4C4B793144404C4B2E3133353A4B6161614B580A785D61607B535D4C5964626C20535D4B24564E5B7E564E5F7D564E4F7D574D7B7C575E5B77576D7B22577D7B21587D7B21594D7B7C574E4F77575E537C0A78564E537B564E5F77576E4B77574D7B7D564E4F7B575D7B7C576E4F77575E4B7E564E5B23564E4F7B585D7B7E586D7B20584D7B7C575E6B77575E4B200A78564E6F22564E5B23564E4F7B587D7B7E585D7B7C576E4B77575E4F25564E4F7B584D7B20595D7B7C575E6377575E4B22564E5723564E4F7C594D7B7C0A78576E5F77595E6777595E6F77584E4F77575E4B24564E4F7C586D7B7C575E6B77575E4F21564E5F22564E4F7B587D7B20576D7B22576D7B7E595D7B7C0A78576E5F77577E5777586E4F77575E4B7B564E4F7C586D7B22576D7B7C575E6F77575E4F24564E4F7C595D7B7C574E6777585E5377575E5322564E6F240A5E564E4F7C586D7B7C576E6377575E4F7E564E4F7B585D7B25594B4B4B0A4B0A313A300A
--------------------------------
[+] hex_challenge = Iep! Next! t1<[email protected]:KaaaKX
x]a`{S]LYdbl S]K$VN[~VN_}VNO}WM{|W^[wWm{"W}{!X}{!YM{|WNOwW^S|
xVNS{VN_wWnKwWM{}VNO{W]{|WnOwW^K~VN[#VNO{X]{~Xm{ XM{|W^kwW^K 
xVNo"VN[#VNO{X}{~X]{|WnKwW^O%VNO{XM{ Y]{|W^cwW^K"VNW#VNO|YM{|
xWn_wY^gwY^owXNOwW^K$VNO|Xm{|W^kwW^O!VN_"VNO{X}{ Wm{"Wm{~Y]{|
xWn_wW~WwXnOwW^K{VNO|Xm{"Wm{|W^owW^O$VNO|Y]{|WNgwX^SwW^S"VNo$
^VNO|Xm{|WncwW^O~VNO{X]{%YKKK
K
1:0

--------------------------------
[+] rot52 =  }:EUT#:MIUTIep! Next! begin 666 -
M265P(2!.97AT(2 X+#0S+#4R+#$R,"PQ,30L,BPV,RPU-RPU."PQ,#$L,3(Q
M+#(P+#4L,C L,"PR+#$P,2PQ,C$L,3 S+#0W+#$P-2PS-BPT-"PQ,3@L,3 T
M+#DV+#0W+#$P-RPS-2PQ,C L,3$Y+#$P-"PT.2PQ,38L,3 V+#,W+#$Q."PQ
M,C4L.3<L.3DL-#$L,3 X+#$Q-BPQ,3@L,3$U+#4V+#$P-RPT,BPV,BPS.2PQ
M,C4L,S,L-C$L,3 P+#$Q-BPV,BPQ,3DL,3$X+#$Q.2PQ,#<L-3(L,3(V+#DX
3+#$Q-BPQ,C8L,3$S+#$P-2PY.   
 
end

--------------------------------
[+] uudecode =  Iep! Next! 8,43,52,120,114,2,63,57,58,101,121,20,5,20,0,2,101,121,103,47,105,36,44,118,104,96,47,107,35,120,119,104,49,116,106,37,118,125,97,99,41,108,116,118,115,56,107,42,62,39,125,33,61,100,116,62,119,118,119,107,52,126,98,116,126,113,105,98
--------------------------------
[+] byte_uud =  "\x08+4xr\x02?9:ey\x14\x05\x14\x00\x02eyg/i$,vh`/k#xwh1tj%v}ac)ltvs8k*>'}!=dt>wvwk4~bt~qib"
--------------------------------
[+] xored =  Iep! Next! FINAL! 5c3eb212c1b631c80d8981e6587a9fdf3ed68d6832f2850500
--------------------------------
[+] bitcoin addr = 5c3eb212c1b631c80d8981e6587a9fdf3ed68d6832f2850500 --> 18KphVHKBw2brgxc2SQtEWWijQYA8LMsFa
--------------------------------
[+] bitcoins = 0.67472019
--------------------------------
YEAH! 8===D{Shamir(2-00124TdmxdOWx6fO3Ju/OPaW1kutWmNKsWrhLxH2W+T7R4QfQ/+NzDebCfTltfTKbgukGlR4yweJn3UW1qw2s5TBCnSQUw=)}

--------------------------------
[+] shamir secret 2 = 2-00124TdmxdOWx6fO3Ju/OPaW1kutWmNKsWrhLxH2W+T7R4QfQ/+NzDebCfTltfTKbgukGlR4yweJn3UW1qw2s5TBCnSQUw=
--------------------------------
[+] flag = 8===D{Enc0ders_D0_N0t_G1v3_R34l_Secur1ty_But_S3cret_Shar1ng_M4ybe_D03s}


Known-plaintext attack

# ipython

In [1]: challenge = '49657021204E657874212074313C4C4B793144404C4B2E3133353A4B6161614B580A785D61607B535D4C5964626C20535D4B24564E5B7E564E5F7D564E4F7D574D7B7C575E5B77576D7B22577D7B21587D7B21594D7B7C574E4F77575E537C0A78564E537B564E5F77576E4B77574D7B7D564E4F7B575D7B7C576E4F77575E4B7E564E5B23564E4F7B585D7B7E586D7B20584D7B7C575E6B77575E4B200A78564E6F22564E5B23564E4F7B587D7B7E585D7B7C576E4B77575E4F25564E4F7B584D7B20595D7B7C575E6377575E4B22564E5723564E4F7C594D7B7C0A78576E5F77595E6777595E6F77584E4F77575E4B24564E4F7C586D7B7C575E6B77575E4F21564E5F22564E4F7B587D7B20576D7B22576D7B7E595D7B7C0A78576E5F77577E5777586E4F77575E4B7B564E4F7C586D7B22576D7B7C575E6F77575E4F24564E4F7C595D7B7C574E6777585E5377575E5322564E6F240A5E564E4F7C586D7B7C576E6377575E4F7E564E4F7B585D7B25594B4B4B0A4B0A313A300A'

In [2]: hex_challenge = challenge.decode('hex')

In [3]: %paste
def rot(text, n):
        I = 32
        F = 126
        a = []

        for i in xrange(I, F + 1):
                a.append(chr(i))

        result = ''
        for i in text:
                oi = ord(i)
                if I <= oi and oi <= F:
                        r = (oi - I + n) % len(a)
                        result += a[r]
                else:
                        result += i
        return result
## -- End pasted text --


In [4]: for i in xrange(126 - 32)
 print rot(hex_challenge, i)
 print i
 print '-' * 20
 raw_input()

...

50
--------------------

|9DTS"9LHTSHdo ~Mdws ~adfhm~555~,
L154O'1 -86@S'1~W*"/R*"3Q*"#Q+!OP+2/K+AOU+QOT,QOT-!OP+"#K+2'P
L*"'O*"3K+B~K+!OQ*"#O+1OP+B#K+2~R*"/V*"#O,1OR,AOS,!OP+2?K+2~S
L*"CU*"/V*"#O,QOR,1OP+B~K+2#X*"#O,!OS-1OP+27K+2~U*"+V*"#P-!OP
L+B3K-2;K-2CK,"#K+2~W*"#P,AOP+2?K+2#T*"3U*"#O,QOS+AOU+AOR-1OP
L+B3K+R+K,B#K+2~O*"#P,AOU+AOP+2CK+2#W*"#P-1OP+";K,2'K+2'U*"CW
2*"#P,AOP+B7K+2#R*"#O,1OX-~~~
~
dmc

51
--------------------

}:EUT#:MIUTIep! Next! begin 666 -
M265P(2!.97AT(2 X+#0S+#4R+#$R,"PQ,30L,BPV,RPU-RPU."PQ,#$L,3(Q
M+#(P+#4L,C L,"PR+#$P,2PQ,C$L,3 S+#0W+#$P-2PS-BPT-"PQ,3@L,3 T
M+#DV+#0W+#$P-RPS-2PQ,C L,3$Y+#$P-"PT.2PQ,38L,3 V+#,W+#$Q."PQ
M,C4L.3<L.3DL-#$L,3 X+#$Q-BPQ,3@L,3$U+#4V+#$P-RPT,BPV,BPS.2PQ
M,C4L,S,L-C$L,3 P+#$Q-BPV,BPQ,3DL,3$X+#$Q.2PQ,#<L-3(L,3(V+#DX
3+#$Q-BPQ,C8L,3$S+#$P-2PY.   
 
end

52
--------------------


# ipython

In [1]: byte_uud =  "\x08+4xr\x02?9:ey\x14\x05\x14\x00\x02eyg/i$,vh`/k#xwh1tj%v}ac)ltvs8k*>'}!=dt>wvwk4~bt~qib"

In [2]: r = byte_uud

In [3]: %paste
def xor(text, key):
 r = ''
 lk = len(key)
 for i in range(len(text)):
  r += chr(ord(text[i]) ^ ord(key[i % lk]))
 return r
## -- End pasted text --

In [4]: find = 'Iep! Next!'

In [5]: %paste
keys = []

for i in xrange(len(r)):
 key = xor(r[i:i+len(find)], find)
 if len(key) == len(find):
  keys.append(key)

for k in keys:
 for i in xrange(len(find)):
  nk = k[i:]+k[:i]
  result = xor(r, nk)
  if find in result:
   print '-----------------------------', nk
   print result
   raw_input()
## -- End pasted text --
----------------------------- ANDYRLZAND
Iep! Next!8ZAMRN?8)k(jh/:,u*m<6&u-8i,</'h"0/!t1kpc<oy=&r-79/u0&-,=3#
---------------------------------------------------------------------------
KeyboardInterrupt

In [6]: find = 'Iep! Ne'

In [7]: %paste
keys = []

for i in xrange(len(r)):
 key = xor(r[i:i+len(find)], find)
 if len(key) == len(find):
  keys.append(key)

for k in keys:
 for i in xrange(len(find)):
  nk = k[i:]+k[:i]
  result = xor(r, nk)
  if find in result:
   print '-----------------------------', nk
   print result
   raw_input()
## -- End pasted text --
----------------------------- ANDYRLZ
Iep! Next! FINAL! 5c3eb212c1b631c80d8981e6587a9fdf3ed68d6832f2850500

# FAQin 2k16: Escape from Matrix


# curl --user $id:$pass http://faqin.org/freeticket/crypto/index.php
...
 <br />Here is your data to escape from Matrix:<br /><br />
 <pre>
 1q2l2y2l2g2h0w2B2r2x2u0w1v1q0w2l2q0w2w2z2r0w2h2t2x2d2o0w2s2d2u2w2v0w2v2w2r2s0w1E2h2y2h
 2u2v2h0w2w2k2h0w2v2w2u2l2q2j0w2v2w2r2s0w2f2d2o2f2x2o2d2w2h0w2w2k2h0w2k2d2v2k0w2z2l2w2k
 0w1p1E1p2v0w1z1q180w1z1q1a0w1z1q1b0w1F1u1n170w202l2j2h2u0w1F2q2h2i2u2x0w1E2l2s2h1z1q0w
 232k2l2u2o2s2r2r2o0w1u2d2y2d2o0w2r2u0w2d2q2r2w2k2h2u0w2v2w2r2s0w202u2B0w2w2k2l2v0w2k2d
 2v2k0w2z2l2w2k0w2B2r2x2u0w1v1q0w2w2r0w2h2v2f2d2s2h0w2i2u2r2p0w2w2k2h0w2p2d2w2u2l2A0w2d
 2q2g0w2z2l2q0w2d0w2i2u2h2h0w2w2l2f2n2h2w0w2i2r2u0w2w2k2h0w1s1n1D2l2q0w1p2r2q2j2u2h2v2v
 </pre>
...

# cat crypto.py
n = []
n.append('1222220222201102202220222220222220222201222')
n.append('2220222022222202222022222222202220222202222')
n.append('0111201110111011101111022222012222201222110')
n.append('2222222220122220220222222202222022202222022')
n.append('2202222022220110220222222022220222022222202')
n.append('2202220202222022222202220222011122012222222')

l = []
l.append('qlylghwBrxuwvqwlqwwzrwhtxdowsduwvwvwrswEhyh')
l.append('uvhwwkhwvwulqjwvwrswfdofxodwhwwkhwkdvkwzlwk')
l.append('wpEpvwzq8wzqawzqbwFun7w0ljhuwFqhiuxwElshzqw')
l.append('3kluosrrowudydowruwdqrwkhuwvwrsw0uBwwklvwkd')
l.append('vkwzlwkwBrxuwvqwwrwhvfdshwiurpwwkhwpdwulAwd')
l.append('qgwzlqwdwiuhhwwlfnhwwiruwwkhwsnDlqwprqjuhvv')

for i in xrange(0, 6):
  s = ''
  for j in xrange(0, len(l[i])):
    if  n[i][j] == '0':
      result = chr(ord(l[i][j]) - 87)
    elif n[i][j] == '1':
      c = l[i][j]
      if c.isdigit():
        result = chr(ord(l[i][j]) - 6)
      elif c.islower():
        result = chr(ord(l[i][j]) - 45)
      else:
        result = chr(ord(l[i][j]) + 13)
    elif n[i][j] == '2':
      c = l[i][j]
      if c.isdigit():
        result = chr(ord(l[i][j]) + 36)
      elif c.islower():
        result = chr(ord(l[i][j]) - 3)
      else:
        result = chr(ord(l[i][j]) + 55)
    #print n[i][j], l[i][j], result
    s += result
  print s

# python crypto.py
Divide your ID in two equal parts stop Reve
rse the string stop calculate the hash with
 CRCs MD2 MD4 MD5 SHA1 Tiger Snefru RipeMD
Whirlpool Haval or another stop Try this ha
sh with your ID to escape from the matrix a
nd win a free ticket for the FAQin Congress

# input=`echo -n $id | cut -c 1-16 | rev`
# curl --silent --data "input=$input" http://www.nitrxgen.net/hashgen/ | grep "\"exhr\"" |  awk -F '>' '{print $3}' | awk -F '<' '{print $1}' > /tmp/hashes.txt

# cat brute.sh
#!/bin/bash

id="$1"

while read hash; do
  result="`curl --user "$id:$hash" http://faqin.org/freeticket/win 2>&1 | grep -e '401 Unauthorized'`""
  if [ "$result" == "" ]; then
   echo $hash
   exit
  fi
done < /tmp/hashes.txt

# ./brute.sh $id
md4 hash

# Wiener's attack against RSA (small values of d)


Wiener has proved that the attacker may efficiently find d when:

d < (N**0.25)/3

# cat wiener_attack.py
#!/usr/bin/python

from sympy.solvers import solve
from sympy import Symbol

def partial_quotiens(x, y):
        pq = []
        while x != 1:
                pq.append(x / y)
                a = y
                b = x % y
                x = a
                y = b
        #print pq
        return pq

def rational(pq):
        i = len(pq) - 1
        num = pq[i]
        denom = 1
        while i > 0:
                i -= 1
                a = (pq[i] * num) + denom
                b = num
                num = a
                denom = b
        #print (num, denom)
return (num, denom)

def convergents(pq):
        c = []
        for i in range(1, len(pq)):
                c.append(rational(pq[0:i]))
        #print c
        return c

def phiN(e, d, k):
        return ((e * d) - 1) / k

# e = 17993
# n = 90581
# wiener_attack(e, n) --> p =  239, q =  379

e = 0x0285f8d4fe29ce11605edf221868937c1b70ae376e34d67f9bb78c29a2d79ca46a60ea02a70fdb40e805b5d854255968b2b1f043963dcd61714ce4fc5c70ecc4d756ad1685d661db39d15a801d1c382ed97a048f0f85d909c811691d3ffe262eb70ccd1fa7dba1aa79139f21c14b3dfe95340491cff3a5a6ae9604329578db9f5bcc192e16aa62f687a8038e60c01518f8ccaa0befe569dadae8e49310a7a3c3bddcf637fc82e5340bef4105b533b6a531895650b2efa337d94c7a76447767b5129a04bcf3cd95bb60f6bfd1a12658530124ad8c6fd71652b8e0eb482fcc475043b410dfc4fe5fbc6bda08ca61244284a4ab5b311bc669df0c753526a79c1a57
n = 0x02aeb637f6152afd4fb3a2dd165aec9d5b45e70d2b82e78a353f7a1751859d196f56cb6d11700195f1069a73d9e5710950b814229ab4c5549383c2c87e0cd97f904748a1302400dc76b42591da17dabaf946aaaf1640f1327af16be45b8830603947a9c3309ca4d6cc9f1a2bcfdacf285fbc2f730e515ae1d93591ccd98f5c4674ec4a5859264700f700a4f4dcf7c3c35bbc579f6ebf80da33c6c11f68655092bbe670d5225b8e571d596fe426db59a6a05aaf77b3917448b2cfbcb3bd647b46772b13133fc68ffabcb3752372b949a3704b8596df4a44f085393ee2bf80f8f393719ed94ab348852f6a5e0c493efa32da5bf601063a033beaf73ba47d8205db

pq = partial_quotiens(e, n)
c = convergents(pq)
x = Symbol('x')
for (k, d) in c:
        if k != 0:
                y = n - phiN(e, d, k) + 1
                roots = solve(x**2 - y*x + n, x)
                if len(roots) == 2:
                        p = roots[0]
                        q = roots[1]
                        if p * q == n:
                                print 'p = ', p
                                print 'q = ', q
                                break
# ./wiener_attack.py
p =  12001304129015480165432875074437607933493850611499879464845243350215176144760883615322622081442653872645865326992384034722586201972392183010813439352778246403016897976571514715418700569567613729681273931557848857971070286176848136118602099586101089743239644367344468295964691411425416652519752140536869089101
q =  28216117316929874067495888027767527011360661622486842768414059951572932145196930641365509243766454218518793508840136548374994021850853203018205749779390383366761851772055038753940967432004901699256177783249460134792699230632136386268348434203012426963129659057781488950062703849444443906614331812260961682887

Reference

http://en.wikipedia.org/wiki/Wiener's_attack

# PicoCTF 2k13 - Broken CBC


# cat cbc_server.py
#!/usr/bin/env python
import os
from Crypto.Cipher import AES
import SocketServer
import threading
import time

#actual key and iv go here...
key = "00000000000000000000000000000000".decode("hex")
iv  = "00000000000000000000000000000000".decode("hex")

def pkcs(msg):
  print msg.encode("hex")
  padding_length = ord(msg[-1])
  padding = msg[-padding_length:]
  print padding.encode("hex")
  if (padding != (chr(padding_length)*padding_length)):
    print (chr(padding_length)*padding_length).encode("hex")
    return None
  return msg[:-padding_length]

def decrypt(cipher,enc):
  print enc,((len(enc) % 16) != 0)
  dec = ""
  if ((len(enc) % 16) != 0):
    return (False,"Error: cipher length must be a multiple of 16\n")
  dec = cipher.decrypt(enc)
  msg = pkcs(dec)
  if msg is None:
    return (False,"Error: incorrect padding\n")
  return (True,msg)

def process(cmd):
  # Message is like HERE_IS_COMMAND:cmd
  # eg "HERE_IS_COMMAND:help"
  
  cmd = cmd[16:] #ignore the COMMAND: part, it's all the same anyhow
  
  if (cmd == "help"):
    return "Commands:\n\thelp - this\n\tflag - prints out the flag\n\tnyan - prints out a nyan cat\n"
  if (cmd == "flag"):
    return "key: XXX TRY TO READ ME XXX"
  if (cmd == "nyan"):
    return """
+      o     +              o   
    +             o     +       +
o          +
    o  +           +        +
+        o     o       +        o
-_-_-_-_-_-_-_,------,      o 
_-_-_-_-_-_-_-|   /\_/\  
-_-_-_-_-_-_-~|__( ^ .^)  +     +  
_-_-_-_-_-_-_-""  ""      
+      o         o   +       o
    +         +
o        o         o      o     +
    o           +
+      +     o        o      +    
"""
  return "Invalid command. See help for a list of commands\n"

class threadedserver(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass

class incoming(SocketServer.BaseRequestHandler):
  def handle(self):
    cur_thread = threading.current_thread()
    welcome = """
Enter your encrypted command:
"""
    self.request.send(welcome)
    while True:
      m = self.request.recv(1024)
      cipher = AES.new(key, AES.MODE_CBC, iv)
      success,cmd = decrypt(cipher,m[:-1]) #discard newline
      if (success):
        self.request.send(process(cmd))
      else:
        self.request.send(cmd)

server = threadedserver(("0.0.0.0", 4567), incoming)
server.timeout = 4
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()

server_thread.join()
# cat padding_oracle.py 
#!/usr/bin/python

import socket
from Crypto.Cipher import AES

cipher = []
key = []
plain = list('HERE_IS_COMMAND:flag' + ('\x0c' * 12))
count = 0

def oracle_padding(cipher, result = False):
 s = socket.create_connection(('localhost',4567))
 s.recv(1024)
 data = ''
 for i in xrange(0,32):
  data = data + chr(cipher[i])
 #print str(data)
 s.sendall(data+"\n")
 recv = s.recv(1024)
 #print recv
 if "Error" in recv:
  return False
 else:
  if result:
   print
   print recv
  return True

def print_array(a, t, n):
 result = ''
 for i in xrange(0, n):
  result += '%02x' % a[i]
 print t + ' = ' + result

for i in range(32):
 cipher.append(0)
 key.append(0)


for i in range(16):
 for j in range(256):
  count += 1
  cipher[15 - i] = j
  result = oracle_padding(cipher)
  if result:
   key[15 - i] = (i + 1) ^ j
   print '[' + str(i) + ']'
   print_array(cipher, 'c', 16)
   print_array(key, 'k', 16)
   for z in range(i + 1):
    cipher[15 - z] = (i + 2) ^ key[15 - z]
   break

for i in range(16):
 cipher[i] = key[i] ^ ord(plain[16 + i])
print

print_array(cipher, 'solution', 32)
 
oracle_padding(cipher, True)
print 'Tries = ' + str(count)
# ./padding_oracle.py 
[0]
c = 0000000000000000000000000000003b
k = 0000000000000000000000000000003a
[1]
c = 0000000000000000000000000000ee38
k = 0000000000000000000000000000ec3a
[2]
c = 00000000000000000000000000daef39
k = 00000000000000000000000000d9ec3a
[3]
c = 000000000000000000000000fbdde83e
k = 000000000000000000000000ffd9ec3a
[4]
c = 000000000000000000000012fadce93f
k = 000000000000000000000017ffd9ec3a
[5]
c = 000000000000000000007111f9dfea3c
k = 000000000000000000007717ffd9ec3a
[6]
c = 0000000000000000005f7010f8deeb3d
k = 000000000000000000587717ffd9ec3a
[7]
c = 000000000000000071507f1ff7d1e432
k = 000000000000000079587717ffd9ec3a
[8]
c = 000000000000003470517e1ef6d0e533
k = 000000000000003d79587717ffd9ec3a
[9]
c = 000000000000283773527d1df5d3e630
k = 000000000000223d79587717ffd9ec3a
[10]
c = 0000000000be293672537c1cf4d2e731
k = 0000000000b5223d79587717ffd9ec3a
[11]
c = 000000001db92e3175547b1bf3d5e036
k = 0000000011b5223d79587717ffd9ec3a
[12]
c = 0000001d1cb82f3074557a1af2d4e137
k = 0000001011b5223d79587717ffd9ec3a
[13]
c = 0000011e1fbb2c3377567919f1d7e234
k = 00000f1011b5223d79587717ffd9ec3a
[14]
c = 0000001f1eba2d3276577818f0d6e335
k = 000f0f1011b5223d79587717ffd9ec3a
[15]
c = 041f1f0001a5322d69486707efc9fc2a
k = 140f0f1011b5223d79587717ffd9ec3a

solution = 72636e771db92e3175547b1bf3d5e03600000000000000000000000000000000

key: XXX TRY TO READ ME XXX
Tries = 1466

# hackyou 2k14: Crypto - Hashme (200 points)


# cat crypto-200.py
#!/usr/bin/python

from base64 import b64encode
from base64 import b64decode
from math import sin
from re import search as rs
from socket import AF_INET, SOCK_STREAM, socket

B = 4096

def xor(a, b):
 return ''.join(map(lambda x : chr(ord(x[0]) ^ ord(x[1])), zip(a, b * 100)))

def hashme(s, A, B, C, D, j):
 def F(X,Y,Z):
  return ((~X & Z) | (~X & Z)) & 0xFFFFFFFF
 def G(X,Y,Z):
  return ((X & Z) | (~Z & Y)) & 0xFFFFFFFF
 def H(X,Y,Z):
  return (X ^ Y ^ Y) & 0xFFFFFFFF
 def I(X,Y,Z):
  return (Y ^ (~Z | X)) & 0xFFFFFFFF
 def ROL(X,Y):
  return (X << Y | X >> (32 - Y)) & 0xFFFFFFFF

 X = [int(0xFFFFFFFF * sin(i)) & 0xFFFFFFFF for i in xrange(256)]

 for i,ch in enumerate(s):
  k, l = ord(ch), (i + j) & 0x1f
  A = (B + ROL(A + F(B,C,D) + X[k], l)) & 0xFFFFFFFF
  B = (C + ROL(B + G(C,D,A) + X[k], l)) & 0xFFFFFFFF
  C = (D + ROL(C + H(D,A,B) + X[k], l)) & 0xFFFFFFFF
  D = (A + ROL(D + I(A,B,C) + X[k], l)) & 0xFFFFFFFF

 return ''.join(map(lambda x : hex(x)[2:].strip('L').rjust(8, '0'), [B, A, D, C]))

def getcert(s):
 s.send('0\n')
 s.recv(B)
 s.send(login + '\n')
 resp = s.recv(B)
 pos = resp.find(':')
 return resp[pos+1:]

s = socket(AF_INET, SOCK_STREAM)
s.connect(('hackyou2014tasks.ctf.su', 7777))

login = 'a' * 100
for i in xrange(0,4):
 s.recv(B)
b64cert = getcert(s)
s.recv(B)
cert = b64decode(b64cert)
key = xor(cert, login).encode('hex')[12:]
search = key[0:4]
key = key[4:]
pos = key.find(search) - 12
first = key[pos:pos + 4]
last = key[pos - 4:pos]
key = key[pos:]
pos = key.find(last)
key = key[:pos + 4]

login = 'admin'
b64cert = getcert(s)
cert = xor(b64decode(b64cert), key.decode('hex'))
hash = cert[25:]
B = int(hash[0:8], 16)
A = int(hash[8:16], 16)
D = int(hash[16:24], 16)
C = int(hash[24:32], 16)

for j in xrange(0,32):
 res = s.recv(B)
 if res.find('CTF') != -1:
  print rs(r'CTF{.*}', res).group()
  break
 s.send('1\n')
 s.recv(B)
 h = hashme('&role=administrator', A, B, C, D, j)
 cert = b64encode(xor('login=' + login + '&role=anonymous&role=administrator' + h, key.decode('hex')))
 s.send(cert + '\n')
 s.recv(B)
s.close()
# ./crypto-200.py
CTF{40712b12d4be002e20f51424309a068c}

References

http://en.wikipedia.org/wiki/Length_extension_attack

# hackyou 2k14: Crypto - Easy one (100 points)


# cat encryptor.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
        if (argc != 3) {
                printf("USAGE: %s INPUT OUTPUT\n", argv[0]);
                return 0;
        }
        FILE* input  = fopen(argv[1], "rb");
        FILE* output = fopen(argv[2], "wb");
        if (!input || !output) {
                printf("Error\n");
                return 0;
        }
        char k[] = "CENSORED";
        char c, p, t = 0;
        int i = 0;
        while ((p = fgetc(input)) != EOF) {
                c = (p + (k[i % strlen(k)] ^ t) + i*i) & 0xff;
                t = p;
                i++;
                fputc(c, output);
        }
        return 0;
}
# cat crypto.py
#!/usr/bin/python

data = open('msg001.enc', 'rb').read()
enc = []
for byte in data[:-1]:
        enc.append(ord(byte))
plain = 'Hi! This is only test message'
i = t = 0
key = ''
for e in enc:
        x = ord(plain[i])
        k = ((e - x - (i * i)) ^ t) & 0xff
        t = x
        key += chr(k)
        i += 1
print key
# ./crypto.py
VeryLongKeyYouWillNeverGuessV
# cat decryptor.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv) {
        if (argc != 3) {
                printf("USAGE: %s INPUT OUTPUT\n", argv[0]);
                return 0;
        }
        FILE* input  = fopen(argv[1], "rb");
        FILE* output = fopen(argv[2], "wb");
        if (!input || !output) {
                printf("Error\n");
                return 0;
        }
        char k[] = "VeryLongKeyYouWillNeverGuess";
        char c, p, t = 0;
        int i = 0;
        while ((p = fgetc(input)) != EOF) {
                c = (p - (k[i % strlen(k)] ^ t) - i*i) & 0xff;
                t = c;
                i++;
                fputc(c, output);
        }
        return 0;
}
# gcc -o decryptor decryptor.c
# ./decryptor msg002.enc msg002
# cat msg002
The known-plaintext attack (KPA) is an attack model for cryptanalysis where the attacker has samples of both the plaintext (called a crib), and its encrypted version (ciphertext). These can be used to reveal further secret information such as secret keys and code books. The term "crib" originated at Bletchley Park, the British World War II decryption operation.
The flag is CTF{6d5eba48508efb13dc87220879306619}

# CSCamp CTF Quals 2k13: Crypto - public is enough! (400 points)


# grep -v - public.pem | tr -d '\n' | base64 -d | openssl asn1parse -inform DER -i
    0:d=0  hl=2 l= 124 cons: SEQUENCE
    2:d=1  hl=2 l=  13 cons:  SEQUENCE
    4:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
   15:d=2  hl=2 l=   0 prim:   NULL
   17:d=1  hl=2 l= 107 prim:  BIT STRING
# grep -v - public.pem | tr -d '\n' | base64 -d | openssl asn1parse -inform DER -i -strparse 17
    0:d=0  hl=2 l= 104 cons: SEQUENCE
    2:d=1  hl=2 l=  97 prim:  INTEGER           :CAD984557C97E039431A226AD727F0C6D43EF3D418469F1B375049B229843EE9F83B1F97738AC274F5F61F401F21F1913E4B64BB31B55A38D398C0DFED00B1392F0889711C44B359E7976C617FCC734F06E3E95C26476091B52F462E79413DB5
  101:d=1  hl=2 l=   3 prim:  INTEGER           :010001
# openssl rsa -pubin -inform PEM -text -noout < public.pem
Public-Key: (768 bit)
Modulus:
    00:ca:d9:84:55:7c:97:e0:39:43:1a:22:6a:d7:27:
    f0:c6:d4:3e:f3:d4:18:46:9f:1b:37:50:49:b2:29:
    84:3e:e9:f8:3b:1f:97:73:8a:c2:74:f5:f6:1f:40:
    1f:21:f1:91:3e:4b:64:bb:31:b5:5a:38:d3:98:c0:
    df:ed:00:b1:39:2f:08:89:71:1c:44:b3:59:e7:97:
    6c:61:7f:cc:73:4f:06:e3:e9:5c:26:47:60:91:b5:
    2f:46:2e:79:41:3d:b5
Exponent: 65537 (0x10001)
# # Find p and q using this URL http://www.factordb.com/index.php
n = 1230186684530117755130494958384962720772853569595334792197322452151726400507263657518745202199786469389956474942774063845925192557326303453731548268507917026122142913461670429214311602221240479274737794080665351419597459856902143413
p = 33478071698956898786044169848212690817704794983713768568912431388982883793878002287614711652531743087737814467999489
q = 36746043666799590428244633799627952632279158164343087642676032283815739666511279233373417143396810270092798736308917

# ipython
: import gmpy
: p = 33478071698956898786044169848212690817704794983713768568912431388982883793878002287614711652531743087737814467999489
: q = 36746043666799590428244633799627952632279158164343087642676032283815739666511279233373417143396810270092798736308917
: totien = (p-1) * (q-1)
: e = 65537
: d = hex(gmpy.invert(e,totien))
: d
'0x740de48760442835baad5e1990453a9d16db7976d3f8bb98bf99c0c01cbe9b9c12b808c80683d1e346c16c79ac162874f28ca610c1b97e5e1ffae95725ce0c6b031c3e188b17187a793b322cc4004c568e76c9b258542ea2a2d6ecd462fff401'

# cat rsatool.py
#!/usr/bin/python2
import base64, fractions, optparse, random
import gmpy

from pyasn1.codec.der import encoder
from pyasn1.type.univ import *

PEM_TEMPLATE = '-----BEGIN RSA PRIVATE KEY-----\n%s-----END RSA PRIVATE KEY-----\n'
DEFAULT_EXP = 65537

def factor_modulus(n, d, e):
    """
    Efficiently recover non-trivial factors of n

    See: Handbook of Applied Cryptography
    8.2.2 Security of RSA -> (i) Relation to factoring (p.287)

    http://www.cacr.math.uwaterloo.ca/hac/
    """
    t = (e * d - 1)
    s = 0

    while True:
        quotient, remainder = divmod(t, 2)

        if remainder != 0:
            break

        s += 1
        t = quotient

    found = False

    while not found:
        i = 1
        a = random.randint(1,n-1)

        while i <= s and not found:
            c1 = pow(a, pow(2, i-1, n) * t, n)
            c2 = pow(a, pow(2, i, n) * t, n)

            found = c1 != 1 and c1 != (-1 % n) and c2 == 1

            i += 1

    p = fractions.gcd(c1-1, n)
    q = (n / p)

    return p, q

class RSA:
    def __init__(self, p=None, q=None, n=None, d=None, e=DEFAULT_EXP):
        """
        Initialize RSA instance using primes (p, q)
        or modulus and private exponent (n, d)
        """

        self.e = e

        if p and q:
            assert gmpy.is_prime(p), 'p is not prime'
            assert gmpy.is_prime(q), 'q is not prime'

            self.p = p
            self.q = q
        elif n and d:   
            self.p, self.q = factor_modulus(n, d, e)
        else:
            raise ArgumentError('Either (p, q) or (n, d) must be provided')

        self._calc_values()

    def _calc_values(self):
        self.n = self.p * self.q

        phi = (self.p - 1) * (self.q - 1)
        self.d = gmpy.invert(self.e, phi)

        # CRT-RSA precomputation
        self.dP = self.d % (self.p - 1)
        self.dQ = self.d % (self.q - 1)
        self.qInv = gmpy.invert(self.q, self.p)

    def to_pem(self):
        """
        Return OpenSSL-compatible PEM encoded key
        """
        return PEM_TEMPLATE % base64.encodestring(self.to_der())

    def to_der(self):
        """
        Return parameters as OpenSSL compatible DER encoded key
        """
        seq = Sequence()

        for x in [0, self.n, self.e, self.d, self.p, self.q, self.dP, self.dQ, self.qInv]:
            seq.setComponentByPosition(len(seq), Integer(x))

        return encoder.encode(seq)

    def dump(self, verbose):
        vars = ['n', 'e', 'd', 'p', 'q']

        if verbose:
            vars += ['dP', 'dQ', 'qInv']

        for v in vars:
            self._dumpvar(v)

    def _dumpvar(self, var):
        val = getattr(self, var)

        parts = lambda s, l: '\n'.join([s[i:i+l] for i in xrange(0, len(s), l)])

        if len(str(val)) <= 40:
            print '%s = %d (%#x)\n' % (var, val, val)
        else:
            print '%s =' % var
            print parts('%x' % val, 80) + '\n'


if __name__ == '__main__':
    parser = optparse.OptionParser()

    parser.add_option('-p', dest='p', help='prime', type='int')
    parser.add_option('-q', dest='q', help='prime', type='int')
    parser.add_option('-n', dest='n', help='modulus', type='int')
    parser.add_option('-d', dest='d', help='private exponent', type='int')
    parser.add_option('-e', dest='e', help='public exponent (default: %d)' % DEFAULT_EXP, type='int', default=DEFAULT_EXP)
    parser.add_option('-o', dest='filename', help='output filname')
    parser.add_option('-f', dest='format', help='output format (DER, PEM) (default: PEM)', type='choice', choices=['DER', 'PEM'], default='PEM')
    parser.add_option('-v', dest='verbose', help='also display CRT-RSA representation', action='store_true', default=False)

    try:
        (options, args) = parser.parse_args()

        if options.p and options.q:
            print 'Using (p, q) to initialise RSA instance\n'
            rsa = RSA(p=options.p, q=options.q, e=options.e)
        elif options.n and options.d:
            print 'Using (n, d) to initialise RSA instance\n'
            rsa = RSA(n=options.n, d=options.d, e=options.e)
        else:
            parser.print_help()
            parser.error('Either (p, q) or (n, d) needs to be specified')

        rsa.dump(options.verbose)

        if options.filename:
            print 'Saving %s as %s' % (options.format, options.filename)


            if options.format == 'PEM':
                data = rsa.to_pem()
            elif options.format == 'DER':
                data = rsa.to_der()

            fp = open(options.filename, 'wb')
            fp.write(data)
            fp.close()

    except optparse.OptionValueError, e:
        parser.print_help()
        parser.error(e.msg)
# ./rsatool.py -p 33478071698956898786044169848212690817704794983713768568912431388982883793878002287614711652531743087737814467999489 -q 36746043666799590428244633799627952632279158164343087642676032283815739666511279233373417143396810270092798736308917 -n 1230186684530117755130494958384962720772853569595334792197322452151726400507263657518745202199786469389956474942774063845925192557326303453731548268507917026122142913461670429214311602221240479274737794080665351419597459856902143413 -e 65537
Using (p, q) to initialise RSA instance

n =
cad984557c97e039431a226ad727f0c6d43ef3d418469f1b375049b229843ee9f83b1f97738ac274
f5f61f401f21f1913e4b64bb31b55a38d398c0dfed00b1392f0889711c44b359e7976c617fcc734f
06e3e95c26476091b52f462e79413db5

e = 65537 (0x10001)

d =
740de48760442835baad5e1990453a9d16db7976d3f8bb98bf99c0c01cbe9b9c12b808c80683d1e3
46c16c79ac162874f28ca610c1b97e5e1ffae95725ce0c6b031c3e188b17187a793b322cc4004c56
8e76c9b258542ea2a2d6ecd462fff401

p =
d982ec7b440e2869d2535e51f91bacc3eb6eba042e106e6f875c3d17e53db65fffd6e4e9a36084ce
60f83d754dd7f701

q =
eebe6dd23ce7e99c0e2249fecc4418c34af74e418bfa714c3791828414ab18f32fd7e093062a49b0
30225cc845f99ab5

# ipython
: from Crypto.PublicKey import RSA
: keypair = RSA.generate(1024)
: keypair.n = 1230186684530117755130494958384962720772853569595334792197322452151726400507263657518745202199786469389956474942774063845925192557326303453731548268507917026122142913461670429214311602221240479274737794080665351419597459856902143413
: keypair.e = 65537
: keypair.d = 703813872109751212728960868893055483396831478279095442779477323396386489876250832944220079595968592852532432488202250497425262918616760886811596907743384527001944888359578241816763079495533278518938372814827410628647251148091159553
: keypair.p = 33478071698956898786044169848212690817704794983713768568912431388982883793878002287614711652531743087737814467999489
: keypair.q = 36746043666799590428244633799627952632279158164343087642676032283815739666511279233373417143396810270092798736308917
: private = open('private.pem','w')
: private.write(keypair.exportKey())
: private.close()
: exit
# openssl rsautl -decrypt -in message.enc -out /dev/tty -inkey private.pem
F4ct0r!zaTi0N

# cat RSAcrack.py
#!/usr/bin/python

from sys import*
from string import*

a = argv
[s,p,q] = filter(lambda x:x[:1]!= '-',a)
print "s = " + str(s)
print "p = " + str(p)
print "q = " + str(q)
d='-d' in a
print "d = " + str(d)
e, n = atol(p,16), atol(q,16)
print "e = " + str(e)
print "n = " + str(n)
l = (len(q) + 1) / 2
print "l = " + str(l)
o, inb = l-d, l-1+d
print "o = " + str(o)
print "inb = " + str(inb)
while s:
 s = stdin.read(inb)
 s and map(stdout.write, map(lambda i, b=pow(reduce(lambda x,y : (x<<8L)+y, map(ord,s)), e, n) : chr(b>>8*i&255), range(o-1, -1, -1)))
# cat message.enc | ./RSAcrack.py -d 740de48760442835baad5e1990453a9d16db7976d3f8bb98bf99c0c01cbe9b9c12b808c80683d1e346c16c79ac162874f28ca610c1b97e5e1ffae95725ce0c6b031c3e188b17187a793b322cc4004c568e76c9b258542ea2a2d6ecd462fff401 cad984557c97e039431a226ad727f0c6d43ef3d418469f1b375049b229843ee9f83b1f97738ac274f5f61f401f21f1913e4b64bb31b55a38d398c0dfed00b1392f0889711c44b359e7976c617fcc734f06e3e95c26476091b52f462e79413db5 | strings
F4ct0r!zaTi0N

# CSCamp CTF Quals 2k13: Crypto - Predictor


can you predict the next number in the sequence?

[51751041,236753494,190402293,48644501,297659248,230684862,7697029,173742959,126005793]

The code used to create those numbers is

import random
i = 295075153L
x = random.randint(0, i)
y = random.randint(0, i)
for j in range (1,10):
x = (2*x + 5) % i
y = (3*y + 7) % i
print (x^y)

The flag will be the next number in the sequence

# cat predictor.py
#!/usr/bin/python

import random 

i = 295075153

def sequence(x,y):
 for j in range (1,11):
  x = (2*x + 5) % i
  y = (3*y + 7) % i
  print (x^y)

y = 0
while True:
 y1 = (3*y + 7) % i
 x1 = y1^51751041
 x2 = (2*x1 + 5) % i
 y2 = (3*y1 + 7) % i
 if x2^y2 == 236753494:
  print "y = " + str(y)
  x = 0
  '''
  while True:
   if x1 == (2*x + 5) % i:
    print "x = " + str(x)
    sequence(x,y)
    exit()
   x += 1
  '''
  x = (i + x1 - 5) / 2
  print "x = " + str(x)
  sequence(x,y)
  exit()
 y += 1
# ./predictor.py
y = 173565935
x = 268355495
51751041
236753494
190402293
48644501
297659248
230684862
7697029
173742959
126005793
103605566