CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/net/dns/resolver/socks.rb
Views: 1904
1
# -*- coding: binary -*-
2
require 'socket'
3
require 'ipaddr'
4
5
class RawSocket # :nodoc:
6
7
@@id_arr = []
8
9
def initialize(src_addr,dest_addr)
10
11
# Define socket
12
begin
13
@socket = Socket.new PF_INET, SOCK_RAW, IPPROTO_RAW
14
rescue SystemCallError => e
15
raise SystemCallError, "You must be root to use raw sockets! #{e}"
16
end
17
18
@socket.setsockopt IPPROTO_IP, IP_HDRINCL, 1
19
20
# Checks addresses
21
@src_addr = check_addr src_addr
22
@dest_addr = check_addr dest_addr
23
24
# Source and destination port are zero
25
@src_port = 0
26
@dest_port = 0
27
28
# Set correct protocol version in the header
29
@version = @dest_addr.ipv4? ? "0100" : "0110"
30
31
# Total length: must be overridden by subclasses
32
@tot_lenght = 20
33
34
# Protocol: must be overridden by subclasses
35
@protocol = 1 # ICMP by default
36
37
# Generate a new id
38
# @id = genID
39
@id = 1234
40
41
# Generate peer sockaddr
42
@to = Socket.pack_sockaddr_in @dest_port, @dest_addr.to_s
43
end
44
45
def send(payload = '')
46
packet = make_ip_header([[ @version+'0101', 'B8' ], # version, hlen
47
[ 0, 'C' ], # tos
48
[ @tot_lenght + payload.size, 'n' ], # total len
49
[ @id, 'n' ], # id
50
[ 0, 'n' ], # flags, offset
51
[ 64, 'C' ], # ttl
52
[ @protocol, 'C' ], # protocol
53
[ 0, 'n' ], # checksum
54
[ @src_addr.to_i, 'N' ], # source
55
[ @dest_addr.to_i, 'N' ], # destination
56
])
57
packet << make_transport_header(payload.size)
58
packet << [payload].pack("a*")
59
@socket.send(packet,0,@to)
60
end
61
62
private
63
64
def check_addr addr
65
case addr
66
when String
67
IPAddr.new addr
68
when IPAddr
69
addr
70
else
71
raise ArgumentError, "Wrong address format: #{addr}"
72
end
73
end
74
75
def check_port port
76
if (1..65535).include? port and port.kind_of? Integer
77
port
78
else
79
raise ArgumentError, "Port #{port} not valid"
80
end
81
end
82
83
def genID
84
while (@@id_arr.include?(q = rand(65535)))
85
end
86
@@id_arr.push(q)
87
q
88
end
89
90
def ipchecksum(data)
91
checksum = data.unpack("n*").inject(0) { |s, x| s + x }
92
((checksum >> 16) + (checksum & 0xffff)) ^ 0xffff
93
end
94
95
def make_ip_header(parts)
96
template = ''
97
data = []
98
parts.each do |part|
99
data += part[0..-2]
100
template << part[-1]
101
end
102
data_str = data.pack(template)
103
checksum = ipchecksum(data_str)
104
data[-3] = checksum
105
data.pack(template)
106
end
107
108
def make_transport_header
109
""
110
end
111
112
end
113
114
class UdpRawSocket < RawSocket # :nodoc:
115
116
def initialize(src_addr,src_port,dest_addr,dest_port)
117
118
super(src_addr,dest_addr)
119
120
# Check ports
121
@src_port = check_port src_port
122
@dest_port = check_port dest_port
123
124
# Total length: must be overridden by subclasses
125
@tot_lenght = 20 + 8 # 8 bytes => UDP Header
126
127
# Protocol: must be overridden by subclasses
128
@protocol = 17 # UDP protocol
129
130
@to = Socket.pack_sockaddr_in @dest_port, @dest_addr.to_s
131
end
132
133
private
134
135
def make_udp_header(parts)
136
template = ''
137
data = []
138
parts.each do |part|
139
data += part[0..-2]
140
template << part[-1]
141
end
142
data.pack(template)
143
end
144
145
def make_transport_header(pay_size)
146
make_udp_header([
147
[ @src_port, 'n'], # source port
148
[ @dest_port, 'n' ], # destination port
149
[ 8 + pay_size, 'n' ], # len
150
[ 0, 'n' ] # checksum (mandatory)
151
])
152
end
153
154
end
155
156