Telegram DNS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Telegram public RSA key: