Skip to content

Instantly share code, notes, and snippets.

@jefmathiot
Created April 17, 2018 13:40
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jefmathiot/7beb198555c53278757ab93e8a2d0290 to your computer and use it in GitHub Desktop.
Save jefmathiot/7beb198555c53278757ab93e8a2d0290 to your computer and use it in GitHub Desktop.
Telegram DNS
#!/usr/bin/env ruby
require 'base64'
require 'openssl'
require 'net/http'
require 'ipaddr'
require 'json'
def handle_response(body)
raw = Base64.decode64(body)
rsa_key = OpenSSL::PKey::RSA.new(File.read('public_key.pem'))
rsa_plaintext = rsa_key.public_decrypt(raw, OpenSSL::PKey::RSA::NO_PADDING)
aes_ciphertext = rsa_plaintext[32, 224]
cipher = OpenSSL::Cipher.new('aes-256-cbc')
cipher.key = rsa_plaintext[0, 32]
cipher.iv = rsa_plaintext[16, 16]
cipher.padding = 0
raw_config = cipher.update(aes_ciphertext)
raw_config << cipher.final
# Check SHA-2 hash
match = Digest::SHA256.digest(raw_config[0, 208])[0, 16] == raw_config[208, 16]
unless match
puts 'SHA-2 mismatch'
return
end
puts 'SHA-2 digest is correct'
data = raw_config.unpack('V*')
# => Search for the vector of IP & ports
# 'd997c3c5' => 'help.configSimple',
# '1cb5c415' => 'vector'
position = data.find_index { |value| value.to_s(16) == '1cb5c415' }
length = data[position + 1]
puts "Found a vector of #{length} IP addresses"
tuples = data[position + 2, length * 2]
(0..(tuples.length - 1)).step(2).each do |index|
puts " * #{IPAddr.new(tuples[index], Socket::AF_INET)}:#{tuples[index + 1]}"
end
end
def download(uri, host)
req = Net::HTTP::Get.new(uri)
req['Host'] = host
req['User-Agent'] = 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A5297c Safari/602.1'
Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(req)
end
end
puts '****** Google DNS ******'
uri = URI("https://google.com/resolve?name=ap.stel.com&type=16")
json = JSON.parse(download(uri, 'dns.google.com').body)
answers = json['Answer'].map{ |a| a['data'] }.sort_by(&:size).reverse
handle_response(answers.join(''))
puts '****** Appspot ******'
uri = URI('https://dns-telegram.appspot.com')
handle_response(download(uri, 'dns-telegram.appspot.com').body)
# 403 Forbidden: implemented in TDLib but not on the server side ?
# puts '****** Microsoft ******'
# uri = URI('https://software-download.microsoft.com/prod/config.txt')
# puts download(uri, 'tcdnb.azureedge.net').body
# handle_response(download(uri, 'tcdnb.azureedge.net').body)
@jefmathiot
Copy link
Author

Telegram public RSA key:

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAyr+18Rex2ohtVy8sroGP
BwXD3DOoKCSpjDqYoXgCqB7ioln4eDCFfOBUlfXUEvM/fnKCpF46VkAftlb4VuPD
eQSS/ZxZYEGqHaywlroVnXHIjgqoxiAd192xRGreuXIaUKmkwlM9JID9WS2jUsTp
zQ91L8MEPLJ/4zrBwZua8W5fECwCCh2c9G5IzzBm+otMS/YKwmR1olzRCyEkyAEj
XWqBI9Ftv5eG8m0VkBzOG655WIYdyV0HfDK/NWcvGqa0w/nriMD6mDjKOryamw0O
P9QuYgMN0C9xMW9y8SmP4h92OAWodTYgY1hZCxdv6cs5UnW9+PWvS+WIbkh+GaWY
xwIDAQAB
-----END RSA PUBLIC KEY-----

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment