Content-Length: 898237 | pFad | http://github.com/tilfin/detect-http-attack/commit/78ed9e293f494d3b7cb73ba044d0ce6f800c7410

1E Added explanations. · tilfin/detect-http-attack@78ed9e2 · GitHub
Skip to content

Commit 78ed9e2

Browse files
committed
Added explanations.
1 parent d57e680 commit 78ed9e2

File tree

3 files changed

+152
-34
lines changed

3 files changed

+152
-34
lines changed

README.md

+46-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,47 @@
11
detect-http-attack
2-
==================
2+
==================
3+
4+
It is a detecting attack tool for HTTP server such as Apache and Nginx.
5+
Analyzing access logs, output formated text as results.
6+
7+
To use shell pipelines easily, all I/O targets are STDIN, STDOUT and STDERR.
8+
9+
### Analyze access log:
10+
11+
./detect-http-attack.rb < /var/log/nginx/access.log
12+
13+
Targets eight or more consecutive senquential access:
14+
15+
./detect-http-attack.rb -s 8 < /var/log/apache/access_log
16+
17+
Regarded as senquential access within 3 seconds:
18+
19+
./detect-http-attack.rb -i 3 < /var/log/apache/access_log
20+
21+
### Notify attack while tailing access log:
22+
23+
Notifying attacks whenever detecting them to STDERR, all results are output to a file.
24+
25+
tail -f /var/log/nginx/access.log | ./detect-http-attack.rb -n > attack.log
26+
27+
### LTSV Format adapted:
28+
29+
Uses Labeled Tab-separated Values (LTSV) format (http://ltsv.org/)
30+
31+
./detect-http-attack.rb -ltsv < /var/log/apache/access_ltsv_log
32+
33+
### Settings and Customize:
34+
35+
edits detect-http-attack.conf
36+
37+
### Usage:
38+
39+
./detect-http-attack.rb --help
40+
41+
Usage: detect_http_attack [options]
42+
-ltsv Log type is LTSV
43+
-n notify when detecting attack
44+
-s COUNT Specify minimum sequential count
45+
-i SECONDS Specify maximum interval seconds
46+
-f CONFFILE Specify configuration file
47+

detect_http_attack.conf

+75-19
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
#
2-
# Detection HTTP Attack
2+
# Detect HTTP Attack
33
#
44
# Configuration file
55
#
66
#=========================
77

88

9+
#=========================
10+
# Exclueded access targets
11+
#==========================
12+
#
913
# Excluded hosts (comma-separated)
1014
exc_hosts=127.0.0.1
1115

@@ -20,39 +24,91 @@ exc_path_match=\.(js|css|jpg|gif|png|ico)$
2024
# Output Template
2125
#==================
2226
#
23-
# Terminal View Format for "tail -f access_log | "
27+
# Template consists of three lines 'head', 'body' and 'foot'.
28+
# Attack log treats sequential accesses from each host as BLOCK.
29+
# 'head' is a first line of BLOCK.
30+
# 'body' is a line for each access.
31+
# 'foot' is a last line of BLOCK.
32+
#
33+
# If '-n' flag is specified,
34+
# attack access is printed as 'serr' line to STDERR
35+
# whenever they are detected.
36+
#
37+
# Each line is specified escape sequences and fields.
38+
# Field name begins with '$'.
39+
#
40+
#
41+
# == Field List ==
42+
#
43+
# = Apache, Nginx Combined Log Format =
2444
#
25-
# head is host, count, ua.
26-
# host that is IP address or Hostname is cyan bold.
27-
# count that is the number of sequential access is magenta.
28-
# ua that is User-Agent is green.
45+
# > $host $ident $user [$time] "$req" $status $size $referer "$ua"
46+
# > 66.249.XX.XX - - [10/Feb/2013:10:27:45 +0900] "GET / HTTP/1.1" 200 1500 "-" "Searchbot/2.1"
47+
#
48+
# host = 66.249.XX.XX
49+
# ident = -
50+
# user = -
51+
# time = 10/Feb/2013:10:27:45 +0900
52+
# req = GET / HTTP/1.1
53+
# status = 200
54+
# size = 1500
55+
# referer = -
56+
# ua = Searchbot/2.1
57+
#
58+
# And futhermore, req is broken down into method, path and version.
59+
#
60+
# method = GET
61+
# path = /
62+
# version = HTTP/1.1
2963
#
30-
# body is date, status, path, size.
31-
# date is access date time by Ruby standard output.
32-
# status is HTTP status code.
33-
# path is the request path of URL.
34-
# referer is HTTP Referer.
35-
#
36-
# Other fields
37-
# $size response size without headers.
38-
#
3964
#
40-
# foot is empty line.
65+
# = LTSV Format =
4166
#
67+
# Field name is applied to each label.
68+
# And futhermore, req is broken down into method, path and version.
69+
#
70+
71+
#
72+
# == Formats ==
73+
#
74+
# = Terminal View Format for "tail -f access_log | " =
75+
#
76+
# head is host, count, ua.
77+
# host that is IP address or Hostname is cyan bold.
78+
# count that is the number of sequential access is magenta.
79+
# ua that is User-Agent is green.
80+
#
81+
# body is date, status, path, size.
82+
# date is access date time by Ruby standard output.
83+
# status is HTTP status code.
84+
# path is the request path of URL.
85+
# referer is HTTP Referer.
86+
#
87+
# foot is empty line.
88+
#
89+
# serr is red host, count, ua, date, status, path and referer at two lines.
90+
#
4291
head=\e[36m\e[1m$host\e[0m\t\e[35m$count\e[0m\t\e[32m$ua\e[0m\n
4392
body=$date\t$status\t$path\t$referer\n
4493
foot=\n
94+
serr=\e[31m\e[1m$host\e[0m\t\e[33m\e[1m$count\e[0m\t$ua\n$date\t$status\t$path\t$referer\n\n
95+
96+
#
97+
# = Terminal View Format without color sequences =
98+
#
4599
#head=$host\t$count\t$ua\n
46100
#body=$date\t$status\t$path\t$referer\n
47101
#foot=\n
102+
#serr=$host\t$count\t$ua\n$date\t$status\t$path\t$referer\n\n
48103

49104
#
50-
# LTSV format
105+
# = LTSV format =
51106
#
52-
# head and foot isn't output.
53-
# body is time, host and req.
107+
# head and foot aren't output.
108+
# body is time, host and req.
54109
#
55110
##head=
56111
#body=time:[$time]\thost:$host\treq:$req\n
57112
##foot=
113+
#serr=time:[$time]\thost:$host\treq:$req\n
58114

detect_http_attack.rb

+31-14
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,10 @@ def parse(line)
9999
values[name.to_sym] = value
100100
}
101101

102-
method, path = values[:req].split(' ')
102+
method, path, version = values[:req].split(' ')
103103
values[:method] = method
104104
values[:path] = path
105+
values[:version] = version
105106
values[:date] = parse_datetime(values[:time])
106107

107108
values
@@ -144,16 +145,18 @@ def get(field)
144145

145146
class Template
146147

147-
def initialize(head, body, foot)
148+
def initialize(head, body, foot, serr)
148149
@re_field = Regexp.new("\\$[a-z]+")
149150

150151
h = head || "$host\\t$count\\t$ua"
151152
b = body || "$date\\t$path\\t$referer"
152153
f = foot || ""
154+
s = serr || "$host\\t$count\\t$ua\\n$date\\t$path\\t$referer"
153155

154156
@head = parse_value(h)
155157
@body = parse_value(b)
156158
@foot = parse_value(f)
159+
@serr = parse_value(s)
157160
end
158161

159162
def parse_value(value)
@@ -182,22 +185,26 @@ def parse_value(value)
182185
vals
183186
end
184187

185-
def print_head(ops, count, row)
188+
def print_head(count, row)
186189
if @head
187-
print_row(@head, ops, count, row)
190+
print_row(@head, STDOUT, count, row)
188191
end
189192
end
190193

191-
def print_body(ops, row)
192-
print_row(@body, ops, "", row)
194+
def print_body(row)
195+
print_row(@body, STDOUT, "", row)
193196
end
194197

195-
def print_foot(ops, count, row)
198+
def print_foot(count, row)
196199
if @foot
197-
print_row(@foot, ops, count, row)
200+
print_row(@foot, STDOUT, count, row)
198201
end
199202
end
200203

204+
def print_serr(count, row)
205+
print_row(@serr, STDERR, count, row)
206+
end
207+
201208
def print_row(templ, ops, count, row)
202209
templ.each do |val|
203210
if val.instance_of?(String)
@@ -221,6 +228,7 @@ class DetectionProcessor
221228

222229
attr :interval_threshold, true
223230
attr :sequence_threshold, true
231+
attr :notify, true
224232
attr :exc_hosts, true
225233
attr :exc_ua, true
226234
attr :exc_path, true
@@ -235,6 +243,8 @@ def initialize(template)
235243
@exc_ua = nil
236244
@exc_path = nil
237245

246+
@realtime_notify = false
247+
238248
@pre_access_map = Hash.new
239249
@ops = STDOUT
240250
end
@@ -254,6 +264,10 @@ def proc(row)
254264
if (date_ts - ts) <= @interval_threshold
255265
al.push(row)
256266
@pre_access_map.store(host, [date_ts, al])
267+
268+
if @notify and al.count >= @sequence_threshold
269+
@template.print_serr(al.count, row)
270+
end
257271
else
258272
if al.count >= @sequence_threshold
259273
print_access(host, al)
@@ -277,13 +291,13 @@ def finalize
277291
def print_access(host, al)
278292
fl = al[0]
279293

280-
@template.print_head(@ops, al.count, fl)
294+
@template.print_head(al.count, fl)
281295

282296
al.each do |row|
283-
@template.print_body(@ops, row)
297+
@template.print_body(row)
284298
end
285299

286-
@template.print_foot(@ops, al.count, fl)
300+
@template.print_foot(al.count, fl)
287301
end
288302
end
289303

@@ -292,12 +306,14 @@ def print_access(host, al)
292306
def get_opts
293307
# Settting from Arguments
294308

295-
opts = { :parser => 'combined', :max_interval => 3, :min_seq => 8 }
309+
opts = { :parser => 'combined', :max_interval => 3, :min_seq => 8, :notify => false }
296310

297311
opt = OptionParser.new
298312

299313
opt.on('-ltsv', 'Log type is LTSV') { |v| opts[:parser] = "ltsv" }
300314

315+
opt.on('-n', 'notify when detecting attack') { |v| opts[:notify] = true }
316+
301317
opt.on('-s COUNT', 'Specify minimum sequential count') do |count|
302318
opts[:min_seq] = count.to_i
303319
end
@@ -327,11 +343,12 @@ def main
327343

328344
conf = Configuration.new(opts[:conf_file])
329345

330-
template = Template.new(conf.get(:head), conf.get(:body), conf.get(:foot))
346+
template = Template.new(conf.get(:head), conf.get(:body), conf.get(:foot), conf.get(:serr))
331347

332348
processor = DetectionProcessor.new(template)
333349
processor.interval_threshold = opts[:max_interval]
334350
processor.sequence_threshold = opts[:min_seq]
351+
processor.notify = opts[:notify]
335352

336353
exc_hosts = conf.get(:exc_hosts)
337354
if exc_hosts
@@ -340,7 +357,7 @@ def main
340357

341358
exc_ua = conf.get(:exc_ua_match)
342359
if exc_ua
343-
processor.exc_ua = Regexp.new(exc_ua, "i")
360+
processor.exc_ua = Regexp.new(exc_ua, Regexp::IGNORECASE)
344361
end
345362

346363
exc_path = conf.get(:exc_path_match)

0 commit comments

Comments
 (0)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/tilfin/detect-http-attack/commit/78ed9e293f494d3b7cb73ba044d0ce6f800c7410

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy