dpyproxy 2.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dpyproxy/__init__.py +1 -0
- dpyproxy/__main__.py +4 -0
- dpyproxy-2.2.0.dist-info/METADATA +296 -0
- dpyproxy-2.2.0.dist-info/RECORD +59 -0
- dpyproxy-2.2.0.dist-info/WHEEL +4 -0
- dpyproxy-2.2.0.dist-info/entry_points.txt +2 -0
- dpyproxy-2.2.0.dist-info/licenses/LICENSE +201 -0
- enumerators/DnsProxyMode.py +39 -0
- enumerators/DnsResolvers.py +141 -0
- enumerators/HttpMethod.py +17 -0
- enumerators/Modules.py +38 -0
- enumerators/Port.py +11 -0
- enumerators/TcpProxyMode.py +17 -0
- enumerators/TlsVersion.py +21 -0
- enumerators/__init__.py +0 -0
- exception/DnsException.py +7 -0
- exception/ParserException.py +7 -0
- exception/__init__.py +0 -0
- main.py +94 -0
- modules/Module.py +45 -0
- modules/__init__.py +0 -0
- modules/dns/DnsModeDeterminator.py +358 -0
- modules/dns/DnsModule.py +113 -0
- modules/dns/DnsProxy.py +277 -0
- modules/dns/DnsResolver.py +18 -0
- modules/dns/__init__.py +0 -0
- modules/http/HttpModule.py +69 -0
- modules/http/HttpStrategies.py +849 -0
- modules/http/HttpUtils.py +94 -0
- modules/http/__init__.py +0 -0
- modules/tls/TcpProxy.py +106 -0
- modules/tls/TlsModule.py +173 -0
- modules/tls/__init__.py +0 -0
- network/DomainResolver.py +472 -0
- network/NetworkAddress.py +10 -0
- network/WrappedSocket.py +97 -0
- network/__init__.py +0 -0
- network/protocols/Dns.py +62 -0
- network/protocols/Http.py +109 -0
- network/protocols/Socksv4.py +70 -0
- network/protocols/Socksv5.py +106 -0
- network/protocols/Tls.py +113 -0
- network/protocols/__init__.py +0 -0
- network/tcp/Forwarder.py +203 -0
- network/tcp/TcpConnectionHandler.py +264 -0
- network/tcp/WrappedTcpSocket.py +30 -0
- network/tcp/__init__.py +0 -0
- network/udp/__init__.py +0 -0
- test/Sink.py +23 -0
- test/__init__.py +0 -0
- test/test_dns.py +98 -0
- test/test_http.py +57 -0
- test/test_tls.py +63 -0
- util/DnsAutoModeRuntimeMeasurement.py +62 -0
- util/DnsReachabilityCollector.py +160 -0
- util/DnsResolversDomainResolver.py +36 -0
- util/Util.py +62 -0
- util/__init__.py +0 -0
- util/constants.py +8 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Determines and outputs the reachability of all DNS servers and circumvention methods's
|
|
2
|
+
# specified in DnsModeDeterminator.py
|
|
3
|
+
import logging
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
# hack to add parent to pythonpath
|
|
7
|
+
import sys
|
|
8
|
+
import time
|
|
9
|
+
|
|
10
|
+
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
|
|
11
|
+
|
|
12
|
+
from modules.dns.DnsModeDeterminator import DnsModeDeterminator
|
|
13
|
+
|
|
14
|
+
TIMEOUT = 5
|
|
15
|
+
CENSORED_DOMAIN = "www.google.dj"
|
|
16
|
+
MIN_RETRIES = 3
|
|
17
|
+
MAX_RETRIES = 20
|
|
18
|
+
ADD_SNI = True
|
|
19
|
+
RESTRICT_ADVERTISED = True
|
|
20
|
+
BLOCK_PAGE_IPS = False
|
|
21
|
+
|
|
22
|
+
# wikipedia ranges https://wikitech.wikimedia.org/wiki/IP_and_AS_allocations
|
|
23
|
+
WIKIMEDIA_RANGES = [
|
|
24
|
+
"185.15.56.0/22",
|
|
25
|
+
"91.198.174.0/24",
|
|
26
|
+
"195.200.68.0/24",
|
|
27
|
+
"193.46.90.0/24",
|
|
28
|
+
"198.35.26.0/23",
|
|
29
|
+
"208.80.152.0/22",
|
|
30
|
+
"103.102.166.0/24",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
# https://www.gstatic.com/ipranges/goog.json
|
|
34
|
+
GOOGLE_RANGES = [
|
|
35
|
+
"8.8.4.0/24",
|
|
36
|
+
"8.8.8.0/24",
|
|
37
|
+
"8.34.208.0/20",
|
|
38
|
+
"8.35.192.0/20",
|
|
39
|
+
"23.236.48.0/20",
|
|
40
|
+
"23.251.128.0/19",
|
|
41
|
+
"34.0.0.0/15",
|
|
42
|
+
"34.2.0.0/16",
|
|
43
|
+
"34.3.0.0/23",
|
|
44
|
+
"34.3.3.0/24",
|
|
45
|
+
"34.3.4.0/24",
|
|
46
|
+
"34.3.8.0/21",
|
|
47
|
+
"34.3.16.0/20",
|
|
48
|
+
"34.3.32.0/19",
|
|
49
|
+
"34.3.64.0/18",
|
|
50
|
+
"34.4.0.0/14",
|
|
51
|
+
"34.8.0.0/13",
|
|
52
|
+
"34.16.0.0/12",
|
|
53
|
+
"34.32.0.0/11",
|
|
54
|
+
"34.64.0.0/10",
|
|
55
|
+
"34.128.0.0/10",
|
|
56
|
+
"35.184.0.0/13",
|
|
57
|
+
"35.192.0.0/14",
|
|
58
|
+
"35.196.0.0/15",
|
|
59
|
+
"35.198.0.0/16",
|
|
60
|
+
"35.199.0.0/17",
|
|
61
|
+
"35.199.128.0/18",
|
|
62
|
+
"35.200.0.0/13",
|
|
63
|
+
"35.208.0.0/12",
|
|
64
|
+
"35.224.0.0/12",
|
|
65
|
+
"35.240.0.0/13",
|
|
66
|
+
"57.140.192.0/18",
|
|
67
|
+
"64.15.112.0/20",
|
|
68
|
+
"64.233.160.0/19",
|
|
69
|
+
"66.22.228.0/23",
|
|
70
|
+
"66.102.0.0/20",
|
|
71
|
+
"66.249.64.0/19",
|
|
72
|
+
"70.32.128.0/19",
|
|
73
|
+
"72.14.192.0/18",
|
|
74
|
+
"74.114.24.0/21",
|
|
75
|
+
"74.125.0.0/16",
|
|
76
|
+
"104.154.0.0/15",
|
|
77
|
+
"104.196.0.0/14",
|
|
78
|
+
"104.237.160.0/19",
|
|
79
|
+
"107.167.160.0/19",
|
|
80
|
+
"107.178.192.0/18",
|
|
81
|
+
"108.59.80.0/20",
|
|
82
|
+
"108.170.192.0/18",
|
|
83
|
+
"108.177.0.0/17",
|
|
84
|
+
"130.211.0.0/16",
|
|
85
|
+
"136.22.160.0/20",
|
|
86
|
+
"136.22.176.0/21",
|
|
87
|
+
"136.22.184.0/23",
|
|
88
|
+
"136.22.186.0/24",
|
|
89
|
+
"136.124.0.0/15",
|
|
90
|
+
"142.250.0.0/15",
|
|
91
|
+
"146.148.0.0/17",
|
|
92
|
+
"152.65.208.0/22",
|
|
93
|
+
"152.65.214.0/23",
|
|
94
|
+
"152.65.218.0/23",
|
|
95
|
+
"152.65.222.0/23",
|
|
96
|
+
"152.65.224.0/19",
|
|
97
|
+
"162.120.128.0/17",
|
|
98
|
+
"162.216.148.0/22",
|
|
99
|
+
"162.222.176.0/21",
|
|
100
|
+
"172.110.32.0/21",
|
|
101
|
+
"172.217.0.0/16",
|
|
102
|
+
"172.253.0.0/16",
|
|
103
|
+
"173.194.0.0/16",
|
|
104
|
+
"173.255.112.0/20",
|
|
105
|
+
"192.104.160.0/23",
|
|
106
|
+
"192.158.28.0/22",
|
|
107
|
+
"192.178.0.0/15",
|
|
108
|
+
"193.186.4.0/24",
|
|
109
|
+
"199.36.154.0/23",
|
|
110
|
+
"199.36.156.0/24",
|
|
111
|
+
"199.192.112.0/22",
|
|
112
|
+
"199.223.232.0/21",
|
|
113
|
+
"207.223.160.0/20",
|
|
114
|
+
"208.65.152.0/22",
|
|
115
|
+
"208.68.108.0/22",
|
|
116
|
+
"208.81.188.0/22",
|
|
117
|
+
"208.117.224.0/19",
|
|
118
|
+
"209.85.128.0/17",
|
|
119
|
+
"216.58.192.0/19",
|
|
120
|
+
"216.73.80.0/20",
|
|
121
|
+
"216.239.32.0/19",
|
|
122
|
+
"216.252.220.0/22",
|
|
123
|
+
]
|
|
124
|
+
|
|
125
|
+
IRAN_BLOCK_PAGES = ["10.10.34.34", "10.10.34.35", "10.10.34.36"]
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def main():
|
|
129
|
+
print(",".join(GOOGLE_RANGES))
|
|
130
|
+
return
|
|
131
|
+
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
|
|
132
|
+
|
|
133
|
+
_det = DnsModeDeterminator(
|
|
134
|
+
timeout=TIMEOUT,
|
|
135
|
+
censored_domain=CENSORED_DOMAIN,
|
|
136
|
+
compare_ip_ranges=GOOGLE_RANGES,
|
|
137
|
+
block_page_ips=BLOCK_PAGE_IPS,
|
|
138
|
+
restrict_advertised=RESTRICT_ADVERTISED,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
print("Generating working resolvers... might take a while!")
|
|
142
|
+
_time = time.time()
|
|
143
|
+
|
|
144
|
+
for resolver in [
|
|
145
|
+
x for x in _det.generate_working_resolver(min_retries=MIN_RETRIES, max_retries=MAX_RETRIES, add_sni=ADD_SNI)
|
|
146
|
+
]:
|
|
147
|
+
print(resolver)
|
|
148
|
+
|
|
149
|
+
print(f"Time taken: {format_time(time.time() - _time)}")
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
def format_time(unix_timestamp: float) -> str:
|
|
153
|
+
"""
|
|
154
|
+
Formats unix timestamp to hh:mm:ss format
|
|
155
|
+
"""
|
|
156
|
+
return time.strftime("%H:%M:%S", time.gmtime(unix_timestamp))
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
if __name__ == "__main__":
|
|
160
|
+
main()
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
# hack to add parent to pythonpath
|
|
4
|
+
import sys
|
|
5
|
+
|
|
6
|
+
from dns.message import make_query
|
|
7
|
+
|
|
8
|
+
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
|
|
9
|
+
|
|
10
|
+
from enumerators.DnsProxyMode import DnsProxyMode
|
|
11
|
+
from enumerators.DnsResolvers import DnsResolvers
|
|
12
|
+
from network.DomainResolver import DomainResolver
|
|
13
|
+
from network.NetworkAddress import NetworkAddress
|
|
14
|
+
from util.Util import parse_all_ips
|
|
15
|
+
|
|
16
|
+
TIMEOUT = 5
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def main():
|
|
20
|
+
local_address = NetworkAddress("127.0.0.53", 53)
|
|
21
|
+
local_resolver = DomainResolver(DnsProxyMode.UDP, local_address, TIMEOUT, "")
|
|
22
|
+
for resolver in DnsResolvers:
|
|
23
|
+
if resolver.hostname == "":
|
|
24
|
+
continue # No need to test Gcore
|
|
25
|
+
|
|
26
|
+
message = make_query(resolver.hostname, "A")
|
|
27
|
+
try:
|
|
28
|
+
answer = local_resolver.resolve_udp_static(message, resolver=local_address, timeout=TIMEOUT)
|
|
29
|
+
resolved_ips = parse_all_ips(answer)
|
|
30
|
+
if resolver.value not in resolved_ips:
|
|
31
|
+
print(f"Ip mismatch between {resolver} and {resolved_ips}")
|
|
32
|
+
except Exception as e:
|
|
33
|
+
print(f"Could not determine IP of {resolver} due to {e}")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
main()
|
util/Util.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import socket
|
|
3
|
+
|
|
4
|
+
import dns
|
|
5
|
+
from dns.rdatatype import RdataType
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def is_valid_ipv4_address(ip_address: str) -> bool:
|
|
9
|
+
"""
|
|
10
|
+
Returns whether the given string is a valid ipv4 address.
|
|
11
|
+
:param ip_address: String to check for ipv4 validity
|
|
12
|
+
:return: Whether the given string is a valid ip address
|
|
13
|
+
"""
|
|
14
|
+
try:
|
|
15
|
+
socket.inet_aton(ip_address)
|
|
16
|
+
return True
|
|
17
|
+
except socket.error:
|
|
18
|
+
return False
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def parse_all_ips(answer: dns.message.Message) -> list[str]:
|
|
22
|
+
resolved_ips = []
|
|
23
|
+
_name = ""
|
|
24
|
+
_rdclass = ""
|
|
25
|
+
_rdtype = ""
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
_name = answer.question[0].name
|
|
29
|
+
_rdclass = answer.question[0].rdclass
|
|
30
|
+
_rdtype = answer.question[0].rdtype
|
|
31
|
+
|
|
32
|
+
for record in answer.find_rrset(answer.answer, _name, _rdclass, _rdtype):
|
|
33
|
+
try:
|
|
34
|
+
ip = record.address
|
|
35
|
+
resolved_ips += [ip]
|
|
36
|
+
except Exception as e:
|
|
37
|
+
logging.error(f"Could not extract IP from DNS response with exception {e}:\n{record}")
|
|
38
|
+
continue
|
|
39
|
+
except Exception as e:
|
|
40
|
+
if answer is not None:
|
|
41
|
+
try:
|
|
42
|
+
# Try CNAME backup
|
|
43
|
+
cname = answer.find_rrset(answer.answer, _name, _rdclass, RdataType.CNAME)
|
|
44
|
+
_name = str(cname[0])
|
|
45
|
+
|
|
46
|
+
for record in answer.find_rrset(answer.answer, _name, _rdclass, _rdtype):
|
|
47
|
+
try:
|
|
48
|
+
ip = record.address
|
|
49
|
+
resolved_ips += [ip]
|
|
50
|
+
except Exception as e:
|
|
51
|
+
logging.error(f"Could not extract IP from DNS response with exception {e}:\n{record}")
|
|
52
|
+
continue
|
|
53
|
+
except Exception as e:
|
|
54
|
+
logging.error(
|
|
55
|
+
f"Could not extract IP from DNS response with exception {e}:\n{_name}, {_rdclass}, {_rdtype}; "
|
|
56
|
+
f"{answer.answer}"
|
|
57
|
+
)
|
|
58
|
+
else:
|
|
59
|
+
logging.error(
|
|
60
|
+
f"Could not extract IP from DNS response with exception {e}:\n{_name}, {_rdclass}, {_rdtype}; None"
|
|
61
|
+
)
|
|
62
|
+
return resolved_ips
|
util/__init__.py
ADDED
|
File without changes
|