BreizhCTF 2k17 - Write-ups

Information#

Version#

By Version Comment
noraj 1.0 Creation

CTF#

  • Name : BreizhCTF 2k17
  • Website : breizhctf.com
  • Type : On-site
  • Format : Jeopardy

100 - A-H-K-4-7 - Programming#

This old compiler have been found, but we're not able to recover what it trying to hide to us ! Can you help us! It's crucial for us.

P.S. : flag format = bzhctf{theSecretMessageYouFound}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
$ cat breiz

<JEAN_LA_TRIQUE_COMPILO: v1.3.3.8>

#8c15e88a775a924dd0e8bb8c92d015447792b7774492fd7f29e8

───────────────▄▄▄▄▄▄▄───────────
β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–„β–ˆβ–’β–’β–’β–ˆβ–’β–’β–’β–ˆβ–„β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–Œβ”€β”€β”€β”€β”€β”€β”€β”€
β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ”€β”€β”€β”€β”€β”€β”€β”€
β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–Œβ”€β”€β”€β”€β”€β”€β”€β”€
β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ”€β”€β”€β”€β”€β”€β”€β”€β”€
β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€
β”€β”€β”€β”€β”€β”€β”€β”€β”€β–ˆβ–’β–ˆβ–ˆβ–ˆβ–ˆβ–’β–ˆβ–ˆβ–ˆβ–ˆβ–’β–’β–ˆβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”€β”€β”€β”€β”€β”€β”€β”€β”€β–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”€β”€β”€β”€β”€β”€β”€β”€β”€β–ˆβ–’β”€β”€β”€β”€β–’β–’β”€β”€β”€β”€β–’β–ˆβ–Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€
β”€β”€β”€β”€β”€β”€β”€β”€β”€β–ˆβ–’β–ˆβ–ˆβ”€β”€β–’β–’β–ˆβ–ˆβ”€β”€β–’β–’β–ˆβ”€β”€β”€β”€β”€β”€β”€β”€β”€
β”€β”€β”€β”€β”€β”€β”€β”€β”€β–ˆβ–’β”€β”€β”€β”€β–’β–’β”€β”€β”€β”€β–’β–’β–ˆβ”€β”€β”€β”€β”€β”€β”€β”€β”€
β”€β”€β”€β”€β”€β”€β”€β”€β–„β–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ”€β”€β”€β”€β”€β”€β”€β”€
β”€β”€β”€β”€β”€β”€β”€β–ˆβ–ˆβ–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–’β–’β–’β–’β–ˆβ–ˆβ”€β”€β”€β”€β”€β”€β”€
β”€β”€β”€β”€β”€β–ˆβ–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ”€β”€β”€β”€β”€
β”€β”€β”€β–ˆβ–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ”€β”€β”€
β”€β–ˆβ–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–“β–ˆβ–ˆβ”€
β–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆ
β–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–“β–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆ
β–ˆβ–“β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–“β–ˆβ–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆ
β–€β–ˆβ–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–“β–ˆβ–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–€
β”€β”€β–ˆβ–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–’β–’β–’β–’β–’β–’β–’β–’β–’β–’β–ˆβ–ˆβ”€β”€
β”€β”€β”€β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–Œβ–Œβ–Œβ–Œβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ”€β”€β”€

8====D::^a::#HotLikeBreizh::16
8====D::^b::#HotLikeBreizh::4d
8====D::^c::#HotLikeBreizh::8c
8====D::^d::#HotLikeBreizh::01
8====D::^e::#HotLikeBreizh::4d
8====D::^f::#HotLikeBreizh::07
8====D::^g::#HotLikeBreizh::cd
8====D::^h::#HotLikeBreizh::b7
8====D::^i::#HotLikeBreizh::bb
8====D::^j::#HotLikeBreizh::32
8====D::^k::#HotLikeBreizh::fd
8====D::^l::#HotLikeBreizh::a3
8====D::^m::#HotLikeBreizh::5a
8====D::^n::#HotLikeBreizh::30
8====D::^o::#HotLikeBreizh::71
8====D::^p::#HotLikeBreizh::4c
8====D::^q::#HotLikeBreizh::ec
8====D::^r::#HotLikeBreizh::20
8====D::^s::#HotLikeBreizh::e8
8====D::^t::#HotLikeBreizh::8a
8====D::^u::#HotLikeBreizh::15
8====D::^v::#HotLikeBreizh::bb
8====D::^w::#HotLikeBreizh::13
8====D::^x::#HotLikeBreizh::ed
8====D::^y::#HotLikeBreizh::29
8====D::^z::#HotLikeBreizh::c0
8====D::^0::#HotLikeBreizh::77
8====D::^1::#HotLikeBreizh::a7
8====D::^2::#HotLikeBreizh::a8
8====D::^3::#HotLikeBreizh::7f
8====D::^4::#HotLikeBreizh::d0
8====D::^5::#HotLikeBreizh::61
8====D::^6::#HotLikeBreizh::46
8====D::^7::#HotLikeBreizh::44
8====D::^8::#HotLikeBreizh::72
8====D::^9::#HotLikeBreizh::07
8====D::^_::#HotLikeBreizh::92

Ok so we have a string (with hex chars) and a mapping table between ASCII chars and hex values.

So I made a script to reverse the mapping.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
File.open('breiz', 'r') do |f|
mapping = Hash.new
answer = ''

data = f.read()
encoded_data = data.match(/^#([0-9a-f]*)$/).captures[0]
data.scan(/8====D::\^(.{1})::#HotLikeBreizh::([0-9a-f]{2})/).each do |char, hex|
mapping.store(hex, char)
end
encoded_data = encoded_data.scan(/.{1,2}/)
encoded_data.each do |chunck|
if mapping.include?(chunck)
puts "#{chunck} #{mapping[chunck]}"
answer += mapping[chunck]
end
end
puts answer
end

That give me cust0m_e4svc_4u70_h07_k3ys, but bzhctf{cust0m_e4svc_4u70_h07_k3ys} is not the flag :(

What's wrong? Maybe I should take ^a and not a for chars?

Let's change the regex /8====D::\^(.{1})::#HotLikeBreizh::([0-9a-f]{2})/ into /8====D::(.{2})::#HotLikeBreizh::([0-9a-f]{2})/

bzhctf{^c^u^s^t^0^m^_^e^4^s^v^c^_^4^u^7^0^_^h^0^7^_^k^3^y^s} is not the flag either.

And then I saw that 4d could be b or e, it seems there is multiple chars possible for a single hex value.

Let's modify the ruby script to show the possibilities:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
File.open('breiz', 'r') do |f|
mapping = Hash.new
answer = ''

data = f.read()
encoded_data = data.match(/^#([0-9a-f]*)$/).captures[0]
data.scan(/8====D::\^(.{1})::#HotLikeBreizh::([0-9a-f]{2})/).each do |char, hex|
if mapping.include?(hex)
mapping.store(hex, "[#{mapping[hex]}|#{char}]")
else
mapping.store(hex, char)
end
end
encoded_data = encoded_data.scan(/.{1,2}/)
encoded_data.each do |chunck|
if mapping.include?(chunck)
puts "#{chunck} #{mapping[chunck]}"
answer += mapping[chunck]
end
end
puts answer
end

The output of my script is now cust0m_[b|e]4s[i|v]c_4u70_h07_k3ys, that let us 4 possibilities:

  • cust0m_b4sic_4u70_h07_k3ys
  • cust0m_e4sic_4u70_h07_k3ys
  • cust0m_b4svc_4u70_h07_k3ys
  • cust0m_e4svc_4u70_h07_k3ys

The flag is bzhctf{cust0m_b4sic_4u70_h07_k3ys}.

50 - The Bounty Challenge - Web#

SaxX wins some $$$ with this super method in some bug bounties ! Will you find this superdupper technique?

Link : http://10.119.227.42:21000

Just try it:

1
2
$ curl -X TRACE http://10.119.227.42:21000/
too l33t for me, take the flag : BZHCTF{d4t_vulnzzz_0mfg}

100 - Shufflunatorz - Web#

URL : https://10.119.227.42:25000/shufflunatorz.php

We need to bruteforce the authentication. User is admin, (one of) shuffled password is bicpemo and there is a random token that seems associated to the password.

So we neeed to parse the result and submit the password and the token until we get the flag. Each request use the previous result (password and token).

Here is my ruby script:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
require 'net/https'
require 'cgi'

uri = URI('https://10.119.227.42:25000/shufflunatorz.php?action=login')

req = Net::HTTP::Post.new(uri)
req['Cookie'] = CGI::Cookie.new("PHPSESSID", "aji6p0idn7p3entn0c82cjl1n2").to_s

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

def parse(uri, http, req, password='password', token='token')
req.set_form_data('password' => password, 'username' => 'admin', 'token' => token)
res = http.request(req)
if /token/.match?(res.body) # avoid nil parse error when void
password = res.body.match(/Shuffled admin password: ([mcoebip]{7})/).captures[0]
token = res.body.match(/name="token" value="(.*)"/).captures[0]
end
if /Login failed/.match?(res.body)
parse(uri, http, req, password, token)
else
puts res.body
end
end

puts parse(uri, http, req)

Flag is: BZHCTF{3v3rY_d4y_1_m_Shuff71n6}.

250 - Cryptopat - Crypto#

READ the README.

Flag is in two steps.

WARNING : This is a write-up fort the fist part only!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
$ cat README
Nous avons rΓ©ussi Γ  intercepter une conversation entre Alice et Bob sur un cannal non sΓ©curisΓ©. Malheureusement, le message contenant les informations sensibles dont nous souhaitons rΓ©cupΓ©rer a Γ©tΓ© chiffrΓ© par le biais du chiffrement asymΓ©trique RSA.

C'est pour cela que nous engageons les meilleurs cryptanaliste qui seront rΓ©compensΓ©s par des points s'ils parviennent Γ  nous retrouver partiellement ou l'intΓ©gralitΓ© des donnΓ©es dont nous recherchons !


Pour vous faciliter la tΓ’che nous vous avons extrait chacun de ces messages et les avons classΓ©s par ordre chronologique. (message1, puis message2 ...). Nous avons Γ©galement interceptΓ©s deux clΓ©s publique en provenance d'Alice. (d'abord pubkey, ensuite pubkey2). Esperons que cela suffise pour que vous puissiez nous aider !

$ cat message1 | base64 -d
De : Alice
A : Bob
Bonjour Bob, peux tu m'envoyer le flag du chall Crypto ? je ne le retrouve plus !

$ cat message2 | base64 -d
De : Bob
A : Alice
Biensur, envois moi ta clé publique pour que je puisse te l'envoyer de façon sécurisée

$ cat message3 | base64 -d
De : Bob
A : Alice
Attention je pense que ta clΓ© publique est vulnΓ©rable Γ  Wiener, je te conseille fortement de la changer ! bzhctf{B3g1N_0f_Fl4g

$ cat message4 | base64 -d
De : Alice
A : Bob
VoilΓ , j'ai ajoutΓ© 15 bits de poids fort Γ  ma nouvelle clΓ© privΓ©e, maintenant je ne suis plus vulnΓ©rable Γ  Wiener ;)
Tu peux m'envoyer le flag sans soucis ;)

$ openssl rsa -pubin -inform PEM -text -noout < alice_pubkey.pem
Public-Key: (2048 bit)
Modulus:
00:9b:ce:c3:0e:d1:8f:da:b0:8e:55:9b:e4:29:dc:
40:8a:cc:a7:27:a0:bd:b2:2e:dd:ae:29:7e:0f:b4:
19:11:f0:a9:24:bf:4b:11:1c:ef:13:5a:77:66:32:
56:39:ed:7b:1d:e1:3a:25:93:8b:86:a5:b0:2e:5b:
38:2d:25:8d:42:bb:c6:eb:50:78:ed:4a:5a:84:f7:
7e:35:de:1f:51:d4:43:e8:78:70:44:77:70:58:9f:
9e:5d:6f:99:84:6b:bb:d1:8a:43:4d:29:54:f4:f3:
62:50:c2:4b:ca:fa:c2:1f:63:a1:83:dd:de:7d:f3:
d9:a8:a7:15:f7:90:e9:65:e0:f2:5e:c0:05:2d:c1:
6f:31:64:a4:75:4b:68:6f:88:2a:48:f4:40:0f:6e:
5d:99:69:34:4b:3a:62:63:9d:c0:0c:26:93:28:85:
84:24:8e:c7:5b:c7:ca:78:ee:80:cb:71:5c:9b:fc:
1a:6b:cf:3d:d8:76:fe:a6:23:87:d1:7b:3c:b2:99:
fc:d8:5d:36:b4:76:d0:ce:38:6c:a9:69:6a:e6:f8:
cf:ba:2e:9d:10:80:77:5b:ca:26:f9:6c:7b:e9:17:
b6:dd:55:cf:94:fa:2b:a8:06:fd:7e:b8:f8:f6:40:
25:de:13:5c:e9:11:8a:75:73:57:40:12:8c:fa:0c:
81:81
Exponent:
7f:46:eb:fb:41:c8:6b:90:5b:76:98:10:a7:e8:17:
f6:15:20:de:40:c3:63:62:fc:8e:94:37:67:ca:0b:
9b:d0:54:f2:9d:44:58:9e:da:a8:aa:aa:e5:05:ed:
86:d5:aa:ee:22:58:dc:49:f6:aa:89:4a:34:80:b5:
af:0c:3e:e0:cc:e6:bd:49:74:ca:74:6c:a0:5e:22:
16:b6:92:32:d0:19:c1:c3:a7:bb:44:22:0b:47:1e:
cb:18:74:ca:44:25:74:50:5b:a2:a6:4d:15:a0:db:
11:f4:39:ff:49:49:15:b9:d1:11:0a:f5:27:05:73:
9f:45:4a:8f:d5:87:a8:15:5c:d8:ea:ba:c3:55:1a:
4e:1d:12:23:70:e5:e3:c5:09:eb:5a:3c:19:53:08:
ed:57:20:1b:1f:e5:07:63:37:a4:f1:55:fe:f8:8c:
82:a1:30:95:23:ab:73:25:32:81:69:b6:90:f1:20:
d8:c3:bd:c8:64:a9:52:96:80:69:61:a1:d4:9b:2f:
5c:0b:eb:ca:97:62:9d:5f:fc:85:f2:56:40:45:e7:
71:d7:f1:b4:7c:01:a2:11:4e:1c:e8:45:d4:98:da:
0d:ad:ae:e1:cf:ee:4c:e6:ef:b1:13:0c:ca:81:93:
1e:41:2e:39:ee:c0:5b:39:66:19:de:f7:5f:be:81:
8d

$ openssl rsa -in alice_pubkey.pem -pubin -modulus -noout
Modulus=9BCEC30ED18FDAB08E559BE429DC408ACCA727A0BDB22EDDAE297E0FB41911F0A924BF4B111CEF135A7766325639ED7B1DE13A25938B86A5B02E5B382D258D42BBC6EB5078ED4A5A84F77E35DE1F51D443E87870447770589F9E5D6F99846BBBD18A434D2954F4F36250C24BCAFAC21F63A183DDDE7DF3D9A8A715F790E965E0F25EC0052DC16F3164A4754B686F882A48F4400F6E5D9969344B3A62639DC00C2693288584248EC75BC7CA78EE80CB715C9BFC1A6BCF3DD876FEA62387D17B3CB299FCD85D36B476D0CE386CA9696AE6F8CFBA2E9D1080775BCA26F96C7BE917B6DD55CF94FA2BA806FD7EB8F8F64025DE135CE9118A75735740128CFA0C8181

To get the exponent in hex value, just save it in a tmp file and:

1
2
$ cat tmp | tr -d '\n :'
7f46ebfb41c86b905b769810a7e817f61520de40c36362fc8e943767ca0b9bd054f29d44589edaa8aaaae505ed86d5aaee2258dc49f6aa894a3480b5af0c3ee0cce6bd4974ca746ca05e2216b69232d019c1c3a7bb44220b471ecb1874ca442574505ba2a64d15a0db11f439ff494915b9d1110af52705739f454a8fd587a8155cd8eabac3551a4e1d122370e5e3c509eb5a3c195308ed57201b1fe5076337a4f155fef88c82a1309523ab7325328169b690f120d8c3bdc864a95296806961a1d49b2f5c0bebca97629d5ffc85f2564045e771d7f1b47c01a2114e1ce845d498da0dadaee1cfee4ce6efb1130cca81931e412e39eec05b396619def75fbe818d

Thanks to http://hacktracking.blogspot.fr/2014/10/wieners-attack-against-rsa-small-values.html we can use the following Wiener attack script (python):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/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 = 0x7f46ebfb41c86b905b769810a7e817f61520de40c36362fc8e943767ca0b9bd054f29d44589edaa8aaaae505ed86d5aaee2258dc49f6aa894a3480b5af0c3ee0cce6bd4974ca746ca05e2216b69232d019c1c3a7bb44220b471ecb1874ca442574505ba2a64d15a0db11f439ff494915b9d1110af52705739f454a8fd587a8155cd8eabac3551a4e1d122370e5e3c509eb5a3c195308ed57201b1fe5076337a4f155fef88c82a1309523ab7325328169b690f120d8c3bdc864a95296806961a1d49b2f5c0bebca97629d5ffc85f2564045e771d7f1b47c01a2114e1ce845d498da0dadaee1cfee4ce6efb1130cca81931e412e39eec05b396619def75fbe818d
n = 0x9BCEC30ED18FDAB08E559BE429DC408ACCA727A0BDB22EDDAE297E0FB41911F0A924BF4B111CEF135A7766325639ED7B1DE13A25938B86A5B02E5B382D258D42BBC6EB5078ED4A5A84F77E35DE1F51D443E87870447770589F9E5D6F99846BBBD18A434D2954F4F36250C24BCAFAC21F63A183DDDE7DF3D9A8A715F790E965E0F25EC0052DC16F3164A4754B686F882A48F4400F6E5D9969344B3A62639DC00C2693288584248EC75BC7CA78EE80CB715C9BFC1A6BCF3DD876FEA62387D17B3CB299FCD85D36B476D0CE386CA9696AE6F8CFBA2E9D1080775BCA26F96C7BE917B6DD55CF94FA2BA806FD7EB8F8F64025DE135CE9118A75735740128CFA0C8181

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
1
2
3
$ python2 wiener.py
p = 114127149061357518627202132148209789945562612498171703248844728647183939205938400942088872182451798474402023118266246164952671542551602493983267902191445132286997707695929380412166491987698597139874971335692611445465113906908277696311843072283279564769241732213534852153586415575904428530982417501447741168433
q = 172341949716171339980378913772457904178742410614994375111157032750032422968724167844252874762188062144611147923283489705813391034056983943831521141317610640390137786177422229331666759756497246847667967198831406618086722957960048848045394212884717806630358540400300795625429172362504491641913435853590659323729

Now we have p and q let's use RSAtool to generate a PEM file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$ python2 /home/noraj/CTF/tools/rsatool/rsatool.py -f PEM -o key.pem -p 114127149061357518627202132148209789945562612498171703248844728647183939205938400942088872182451798474402023118266246164952671542551602493983267902191445132286997707695929380412166491987698597139874971335692611445465113906908277696311843072283279564769241732213534852153586415575904428530982417501447741168433 -q 172341949716171339980378913772457904178742410614994375111157032750032422968724167844252874762188062144611147923283489705813391034056983943831521141317610640390137786177422229331666759756497246847667967198831406618086722957960048848045394212884717806630358540400300795625429172362504491641913435853590659323729
Using (p, q) to initialise RSA instance

n =
9bcec30ed18fdab08e559be429dc408acca727a0bdb22eddae297e0fb41911f0a924bf4b111cef13
5a7766325639ed7b1de13a25938b86a5b02e5b382d258d42bbc6eb5078ed4a5a84f77e35de1f51d4
43e87870447770589f9e5d6f99846bbbd18a434d2954f4f36250c24bcafac21f63a183ddde7df3d9
a8a715f790e965e0f25ec0052dc16f3164a4754b686f882a48f4400f6e5d9969344b3a62639dc00c
2693288584248ec75bc7ca78ee80cb715c9bfc1a6bcf3dd876fea62387d17b3cb299fcd85d36b476
d0ce386ca9696ae6f8cfba2e9d1080775bca26f96c7be917b6dd55cf94fa2ba806fd7eb8f8f64025
de135ce9118a75735740128cfa0c8181

e = 65537 (0x10001)

d =
5f4ceab667ac0be1ae4de2da7e58400a25ffa0178bb02f465cbef8627690570ed306ad132756814d
5f2a651228f7a9b082a83ebeb92ec09f1bd25eed4f80069568f1d50115d65e825b8e5e5e688cd3aa
7816fb83fffce674eebd18fda7f2fd4a9672719402d1fa39dc4af56d12acaa8c348e986fdf253f40
450e5e3b5d21c5b40645316d794110ee3b1f22df3575db9c68f61f1d3b31bcbb7cf6c7b345289ecd
e7cdcc4d367ccdcf4105e150dfc2350dcbf6230027687956f0bc2715a08dee68e64a79a65c141b9b
4bcb42ec6ee99b25d863faabd912393938253fe95ed8b6af552f271976c456e6b1c837adacf03c92
0366d528fe70bcca78244277ce624a01

p =
a285bf9c3912df02b18291b52ea511306fbc353ee38008bb5a02119c4aa9eb1fe4236b3b6f69ade9
6e309a3297b19f5cf530736d14218d307048b25819bed321cf50951e8a3bb1ca6f4f6f385e890a28
d9a284aa10d75f17635053325e6abbc9b22cb0a43c8d2c335487e2086222f49b16aa71707baa6550
ec2ea3fdfaaadb31

q =
f56c4f29447e79324350165aff52fbcbbfaee72bac2b8abead11bc27e42d5237d7f0e1c2e431b997
4a66c0c0be8734ddffcf44bcf5f0622c3f3f6fe4e00b89444e015b0cd8edf57baed79a02fdd50fa0
b5a6a8065181e180c301cda7d23d6fd2e79750c06d664819756014bd550c1f8d4854985934b41792
b8a18da58297d751

Saving PEM as key.pem

But this not the good private key:

1
2
3
4
$ openssl rsautl -decrypt -in message5.enc -out plaintext -inkey key.pem; cat plaintext
RSA operation error
139928048981656:error:0407109F:rsa routines:RSA_padding_check_PKCS1_type_2:pkcs decoding error:rsa_pk1.c:273:
139928048981656:error:04065072:rsa routines:RSA_EAY_PRIVATE_DECRYPT:padding check failed:rsa_eay.c:602:

End of the first part, now we need to generate the second private key by bruteforcing the first 15 MSB bits.

Here is the second public key (we didn't manage to generate the second private key):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
$ openssl rsa -pubin -inform PEM -text -noout < alice_pubkey_2.pem
Public-Key: (2048 bit)
Modulus:
00:a9:41:56:1e:e5:f5:27:da:d4:7e:8f:82:b5:44:
6a:fd:82:5a:c3:04:a5:04:db:1c:f9:97:9a:63:c6:
a8:bd:ee:f5:6b:e3:fa:cd:a9:52:67:6c:c8:26:9e:
ae:0b:76:d6:13:24:85:ee:e9:ae:37:b9:68:f1:2a:
4d:6a:3e:d1:1f:0d:7d:b6:8e:b8:9e:37:34:0b:5d:
45:8b:cc:58:16:9c:7b:b1:45:dc:32:04:0c:97:6c:
ba:88:43:86:c9:8c:b4:4f:07:88:97:a3:17:fe:83:
cc:f2:b4:8d:d3:97:b0:59:c4:65:ed:5a:3c:64:a5:
30:86:5f:70:95:53:2e:6e:cd:8d:f9:79:4f:e2:4c:
07:80:68:48:91:2f:02:6d:e1:50:c0:08:ac:ce:9a:
fa:e7:15:f2:e1:29:27:35:6a:7e:4d:11:84:93:6f:
0e:03:bc:c9:b7:eb:55:7e:91:f4:6c:9f:8e:b8:11:
25:e3:8d:75:52:e1:34:5c:09:b6:39:a6:9d:65:36:
c2:9d:43:ef:66:c2:3e:9f:85:a0:ef:ef:47:84:90:
9b:62:d2:a4:4a:f8:49:a4:6c:87:7e:71:18:ab:26:
22:bf:7c:60:7b:5f:41:a0:28:53:c5:18:61:96:d8:
86:18:c6:0a:2e:28:0a:d3:87:e8:f7:29:ed:06:f8:
87:fd
Exponent:
6c:c7:ff:b9:2a:9f:4a:6c:82:76:08:24:34:f7:0e:
fd:4e:44:87:c2:05:40:eb:cd:92:c5:7a:33:b0:20:
46:70:72:14:63:f0:67:e5:81:9f:b8:d3:87:88:7a:
ea:e7:a6:12:50:55:14:3f:e1:05:df:be:eb:29:59:
8a:8f:27:f0:e1:fb:87:b2:9e:58:30:32:a1:29:35:
11:00:19:15:f7:0a:6a:59:46:0f:49:da:ef:5d:94:
3a:c3:c7:f4:a0:7f:69:36:69:b5:e1:3a:73:b3:f2:
37:71:f7:23:21:57:3f:c8:0b:c7:c5:9e:6f:91:3c:
a3:cc:d8:36:87:92:0e:62:1c:65:2e:a2:83:39:b4:
3e:ed:4b:39:38:d8:12:4a:f3:40:7e:64:96:2b:ea:
01:c3:21:20:71:ab:9b:6c:2a:44:27:16:52:c9:d8:
22:d4:7a:a3:f1:c4:5c:7a:03:83:c8:71:6d:8b:b0:
60:7c:e6:66:21:82:f2:35:08:3e:8d:36:5d:a1:5d:
6b:fa:11:9d:ed:e2:37:56:de:bb:48:c9:79:ed:e3:
70:b9:15:bc:a5:43:0a:e0:2b:36:7d:e8:0d:42:46:
b6:ff:f4:c5:ec:75:bd:e9:20:9b:02:2e:a4:5b:d1:
4f:ba:30:a7:2c:7b:0f:1c:2e:9d:d7:07:ea:4c:5c:
ad

$ openssl rsa -in alice_pubkey_2.pem -pubin -modulus -noout
Modulus=A941561EE5F527DAD47E8F82B5446AFD825AC304A504DB1CF9979A63C6A8BDEEF56BE3FACDA952676CC8269EAE0B76D6132485EEE9AE37B968F12A4D6A3ED11F0D7DB68EB89E37340B5D458BCC58169C7BB145DC32040C976CBA884386C98CB44F078897A317FE83CCF2B48DD397B059C465ED5A3C64A530865F7095532E6ECD8DF9794FE24C07806848912F026DE150C008ACCE9AFAE715F2E12927356A7E4D1184936F0E03BCC9B7EB557E91F46C9F8EB81125E38D7552E1345C09B639A69D6536C29D43EF66C23E9F85A0EFEF4784909B62D2A44AF849A46C877E7118AB2622BF7C607B5F41A02853C5186196D88618C60A2E280AD387E8F729ED06F887FD

$ cat tmp | tr -d '\n :'
6cc7ffb92a9f4a6c8276082434f70efd4e4487c20540ebcd92c57a33b0204670721463f067e5819fb8d387887aeae7a6125055143fe105dfbeeb29598a8f27f0e1fb87b29e583032a1293511001915f70a6a59460f49daef5d943ac3c7f4a07f693669b5e13a73b3f23771f72321573fc80bc7c59e6f913ca3ccd83687920e621c652ea28339b43eed4b3938d8124af3407e64962bea01c3212071ab9b6c2a44271652c9d822d47aa3f1c45c7a0383c8716d8bb0607ce6662182f235083e8d365da15d6bfa119dede23756debb48c979ede370b915bca5430ae02b367de80d4246b6fff4c5ec75bde9209b022ea45bd14fba30a72c7b0f1c2e9dd707ea4c5cad
Share