tcell_agent 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (84) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +4 -0
  3. data/README.md +43 -0
  4. data/Rakefile +7 -0
  5. data/bin/tcell_agent +171 -0
  6. data/config/initializers/authlogic_auth.rb +51 -0
  7. data/config/initializers/devise_auth.rb +167 -0
  8. data/config/initializers/init.rb +8 -0
  9. data/lib/tcell_agent.rb +33 -0
  10. data/lib/tcell_agent/agent.rb +79 -0
  11. data/lib/tcell_agent/agent/event_processor.rb +133 -0
  12. data/lib/tcell_agent/agent/policy_manager.rb +138 -0
  13. data/lib/tcell_agent/agent/policy_types.rb +42 -0
  14. data/lib/tcell_agent/agent/static_agent.rb +22 -0
  15. data/lib/tcell_agent/api.rb +101 -0
  16. data/lib/tcell_agent/appsensor.rb +42 -0
  17. data/lib/tcell_agent/appsensor/cmdi.rb +32 -0
  18. data/lib/tcell_agent/appsensor/path_traversal.rb +33 -0
  19. data/lib/tcell_agent/appsensor/sqli.rb +55 -0
  20. data/lib/tcell_agent/appsensor/xss.rb +40 -0
  21. data/lib/tcell_agent/authlogic.rb +26 -0
  22. data/lib/tcell_agent/configuration.rb +148 -0
  23. data/lib/tcell_agent/dataloss.rb +0 -0
  24. data/lib/tcell_agent/devise.rb +83 -0
  25. data/lib/tcell_agent/instrumentation.rb +44 -0
  26. data/lib/tcell_agent/logger.rb +46 -0
  27. data/lib/tcell_agent/policies/add_script_tag_policy.rb +47 -0
  28. data/lib/tcell_agent/policies/appsensor_policy.rb +76 -0
  29. data/lib/tcell_agent/policies/clickjacking_policy.rb +113 -0
  30. data/lib/tcell_agent/policies/content_security_policy.rb +119 -0
  31. data/lib/tcell_agent/policies/dataloss_policy.rb +175 -0
  32. data/lib/tcell_agent/policies/honeytokens_policy.rb +67 -0
  33. data/lib/tcell_agent/policies/http_redirect_policy.rb +84 -0
  34. data/lib/tcell_agent/policies/http_tx_policy.rb +60 -0
  35. data/lib/tcell_agent/policies/login_fraud_policy.rb +42 -0
  36. data/lib/tcell_agent/policies/secure_headers_policy.rb +64 -0
  37. data/lib/tcell_agent/rails.rb +146 -0
  38. data/lib/tcell_agent/rails/devise.rb +0 -0
  39. data/lib/tcell_agent/rails/dlp.rb +204 -0
  40. data/lib/tcell_agent/rails/middleware/body_filter_middleware.rb +69 -0
  41. data/lib/tcell_agent/rails/middleware/context_middleware.rb +50 -0
  42. data/lib/tcell_agent/rails/middleware/global_middleware.rb +53 -0
  43. data/lib/tcell_agent/rails/middleware/headers_middleware.rb +176 -0
  44. data/lib/tcell_agent/rails/routes.rb +130 -0
  45. data/lib/tcell_agent/rails/settings_reporter.rb +40 -0
  46. data/lib/tcell_agent/sensor_events/app_config.rb +16 -0
  47. data/lib/tcell_agent/sensor_events/app_sensor.rb +240 -0
  48. data/lib/tcell_agent/sensor_events/dlp.rb +58 -0
  49. data/lib/tcell_agent/sensor_events/honeytokens.rb +16 -0
  50. data/lib/tcell_agent/sensor_events/login_fraud.rb +43 -0
  51. data/lib/tcell_agent/sensor_events/metrics.rb +24 -0
  52. data/lib/tcell_agent/sensor_events/sensor.rb +85 -0
  53. data/lib/tcell_agent/sensor_events/server_agent.rb +101 -0
  54. data/lib/tcell_agent/sensor_events/util/redirect_utils.rb +22 -0
  55. data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +153 -0
  56. data/lib/tcell_agent/sensor_events/util/utils.rb +21 -0
  57. data/lib/tcell_agent/sinatra.rb +41 -0
  58. data/lib/tcell_agent/start_background_thread.rb +63 -0
  59. data/lib/tcell_agent/userinfo.rb +8 -0
  60. data/lib/tcell_agent/utils/queue_with_timeout.rb +60 -0
  61. data/lib/tcell_agent/version.rb +5 -0
  62. data/spec/controllers/application_controller.rb +12 -0
  63. data/spec/lib/tcell_agent/api/api_spec.rb +36 -0
  64. data/spec/lib/tcell_agent/appsensor_spec.rb +66 -0
  65. data/spec/lib/tcell_agent/policies/add_script_tag_policy_spec.rb +37 -0
  66. data/spec/lib/tcell_agent/policies/appsensor_policy_spec.rb +40 -0
  67. data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +71 -0
  68. data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +71 -0
  69. data/spec/lib/tcell_agent/policies/dataloss_policy_spec.rb +88 -0
  70. data/spec/lib/tcell_agent/policies/honeytokens_policy_spec.rb +22 -0
  71. data/spec/lib/tcell_agent/policies/http_redirect_policy_spec.rb +62 -0
  72. data/spec/lib/tcell_agent/policies/http_tx_policy_spec.rb +22 -0
  73. data/spec/lib/tcell_agent/policies/login_policy_spec.rb +42 -0
  74. data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +67 -0
  75. data/spec/lib/tcell_agent/rails/middleware/global_middleware_spec.rb +187 -0
  76. data/spec/lib/tcell_agent/rails_spec.rb +57 -0
  77. data/spec/lib/tcell_agent/sensor_events/dlp_spec.rb +14 -0
  78. data/spec/lib/tcell_agent/sensor_events/util/redirect_utils_spec.rb +25 -0
  79. data/spec/lib/tcell_agent/sensor_events/util/sanitizer_utilities_spec.rb +57 -0
  80. data/spec/lib/tcell_agent_spec.rb +22 -0
  81. data/spec/resources/normal_config.json +13 -0
  82. data/spec/spec_helper.rb +4 -0
  83. data/tcell_agent.gemspec +29 -0
  84. metadata +249 -0
@@ -0,0 +1,101 @@
1
+ # encoding: utf-8
2
+ # See the file "LICENSE" for the full license governing this code.
3
+ require 'rest-client'
4
+ require 'tcell_agent/logger'
5
+ require 'tcell_agent/configuration'
6
+ require 'tcell_agent/version'
7
+ require 'date'
8
+
9
+ module TCellAgent
10
+ class TCellApi
11
+
12
+ def initialize
13
+ end
14
+
15
+ def pollAPI(last_timestamp=nil)
16
+ if !TCellAgent.configuration || !TCellAgent.configuration.tcell_api_url || !TCellAgent.configuration.app_id
17
+ raise "Config Information Not Found, can't poll tCell service"
18
+ end
19
+ full_url = TCellAgent.configuration.tcell_api_url + "/app/" + TCellAgent.configuration.app_id + "/update"
20
+ if (last_timestamp && last_timestamp != "")
21
+ full_url = full_url + "?last_timestamp=" + last_timestamp.to_s
22
+ end
23
+ TCellAgent.logger.debug "tCell.io API Request: " + full_url
24
+ request_headers = {
25
+ :Authorization => 'Bearer ' + TCellAgent.configuration.api_key
26
+ }
27
+ begin
28
+ request_headers[:TCellAgent] = "RubyAgent " + TCellAgent::VERSION
29
+ rescue Exception => e
30
+ TCellAgent.logger.debug("tCell.io Could not add agent string: " + e.message)
31
+ end
32
+ response = RestClient.get full_url,request_headers
33
+ new_timestamp = last_timestamp
34
+ TCellAgent.logger.debug "tCell.io API Response: " + response
35
+ response_json = JSON.parse(response)
36
+ if (response_json && response_json.has_key?("result"))
37
+ return response_json["result"]
38
+ end
39
+ # else result was null and no new information exists...
40
+ return nil
41
+ end
42
+
43
+ def pollOldAPI(last_timestamp=nil)
44
+ if !TCellAgent.configuration || !TCellAgent.configuration.tcell_api_url || !TCellAgent.configuration.app_id
45
+ raise "Config Information Not Found, can't poll tCell service"
46
+ end
47
+ full_url = TCellAgent.configuration.tcell_api_url + "/api/" + TCellAgent.configuration.app_id + "/csp/poll"
48
+ TCellAgent.logger.debug "tCell.io API Request: " + full_url
49
+ full_url = full_url + "/" + TCellAgent.configuration.api_key
50
+ if (last_timestamp && last_timestamp != "")
51
+ full_url = full_url + "?last_timestamp=" + last_timestamp.to_s
52
+ end
53
+ TCellAgent.logger.debug("tCell.io Old API Request: " + full_url)
54
+ response = RestClient.get full_url
55
+ TCellAgent.logger.debug "tCell.io API Response: " + response
56
+ response_json = JSON.parse(response)
57
+ if (response_json && response_json.has_key?("result"))
58
+ return response_json["result"]
59
+ end
60
+ # else result was null and no new information exists...
61
+ return nil
62
+ end
63
+
64
+ def sendEventSet(events)
65
+ if !TCellAgent.configuration || !TCellAgent.configuration.tcell_input_url || !TCellAgent.configuration.app_id
66
+ raise "Config Information Not Found, can't send events"
67
+ end
68
+ current_time = DateTime.now.to_time.to_i
69
+ if (events)
70
+ events.each { |event| event.calculateOffset(current_time) }
71
+ else
72
+ events = []
73
+ end
74
+ eventset = { "uuid"=>TCellAgent.configuration.uuid,
75
+ "hostname"=>TCellAgent.configuration.host_identifier,
76
+ "events"=>events }
77
+ TCellAgent.logger.debug("Sending #{eventset.to_json}")
78
+ full_url = TCellAgent.configuration.tcell_input_url + "/app/" + TCellAgent.configuration.app_id + "/server_agent"
79
+
80
+ TCellAgent.logger.debug("tCell.io SendEvents API Request: " + full_url)
81
+ request_headers = {
82
+ :Authorization => 'Bearer ' + TCellAgent.configuration.api_key,
83
+ :content_type => :json,
84
+ :accept => :json,
85
+ }
86
+ begin
87
+ request_headers[:TCellAgent] = "RubyAgent " + TCellAgent::VERSION
88
+ rescue Exception => e
89
+ TCellAgent.logger.debug("tCell.io Could not add agent string: " + e.message)
90
+ end
91
+ response = RestClient.post full_url, eventset.to_json, request_headers
92
+ TCellAgent.logger.debug("tCell.io SendEvents API Response: " + response.code.to_s)
93
+ return response.code == 200
94
+ end
95
+
96
+ def valid_header?(str)
97
+ return true if (/^[\p{L}\w\d\-_ :\/,;.'\"%?@#=$]*$/).match(str)
98
+ return false
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ # See the file "LICENSE" for the full license governing this code.
3
+
4
+ require 'tcell_agent/appsensor/xss'
5
+ require 'tcell_agent/appsensor/sqli'
6
+ require 'tcell_agent/appsensor/cmdi'
7
+ require 'tcell_agent/appsensor/path_traversal'
8
+
9
+ module TCellAgent
10
+ class AppSensor
11
+
12
+ GENERALLY_SAFE_REGEX = /^[a-zA-Z0-9_\s\r\n\t]*$/
13
+ NULL_CHARS_REGEX=/\0/
14
+ RETURN_CHARS_REGEX=/(\n|\r)/
15
+
16
+ def self.generallySafe(value)
17
+ if !value.instance_of? String
18
+ return false
19
+ end
20
+ return (value.match(AppSensor::GENERALLY_SAFE_REGEX)!=nil)
21
+ end
22
+ def self.containsNull(value)
23
+ if !value.instance_of? String
24
+ return false
25
+ end
26
+ if value.match(AppSensor::NULL_CHARS_REGEX)
27
+ return true
28
+ end
29
+ return false
30
+ end
31
+ def self.containsReturnChars(value)
32
+ if !value.instance_of? String
33
+ return false
34
+ end
35
+ if value.match(AppSensor::RETURN_CHARS_REGEX)
36
+ return true
37
+ end
38
+ return false
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ # See the file "LICENSE" for the full license governing this code.
3
+
4
+ require 'tcell_agent/sensor_events/util/sanitizer_utilities'
5
+
6
+
7
+ # Some Rules Originate from ModSecurity
8
+ # ModSecurity for Apache 2.x, http://www.modsecurity.org/
9
+ # Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
10
+
11
+ module TCellAgent
12
+ class AppSensor
13
+ CMDI_PATTERNS = [
14
+ /(?i:(?:[\;\|\`]\W*?\bcc|\b(wget|curl))\b|\/cc(?:[\'\"\|\;\`\-\s]|$))/,
15
+ /(?:\b(?:(?:n(?:et(?:\b\W+?\blocalgroup|\.exe)|(?:map|c)\.exe)|t(?:racer(?:oute|t)|elnet\.exe|clsh8?|ftp)|(?:w(?:guest|sh)|rcmd|ftp)\.exe|echo\b\W*?\by+)\b|c(?:md(?:(?:\.exe|32)\b|\b\W*?\\\/c)|d(?:\b\W*?[\\\/]|\W*?\.\.)|hmod.{0,40}?\+.{0,3}x))|[\;\|\`]\W*?\b(?:(?:c(?:h(?:grp|mod|own|sh)|md|pp)|p(?:asswd|ython|erl|ing|s)|n(?:asm|map|c)|f(?:inger|tp)|(?:kil|mai)l|(?:xte)?rm|ls(?:of)?|telnet|uname|echo|id)\b|g(?:\+\+|cc\b)))/
16
+ ]
17
+ def self.isCmdi(value)
18
+ if !value.instance_of? String
19
+ return false
20
+ end
21
+ if generallySafe(value)
22
+ return false
23
+ end
24
+ CMDI_PATTERNS.each do |cmdi_pattern|
25
+ if value.match(cmdi_pattern)
26
+ return true
27
+ end
28
+ end
29
+ false
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ # See the file "LICENSE" for the full license governing this code.
3
+
4
+ require 'tcell_agent/sensor_events/util/sanitizer_utilities'
5
+
6
+
7
+ # Some Rules Originate from ModSecurity
8
+ # ModSecurity for Apache 2.x, http://www.modsecurity.org/
9
+ # Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
10
+
11
+ module TCellAgent
12
+ class AppSensor
13
+ PATH_TRAVERSAL_REGEXES = [
14
+ Regexp.new("(?:(?:\\\/|\\\\)?\\.+(\\\/|\\\\)(?:\\.+)?)|(?:\\w+\\.exe\\??\\s)|(?:;\\s*\\w+\\s*\\\/[\\w*-]+\\\/)|(?:\\d\\.\\dx\\|)|(?:%(?:c0\\.|af\\.|5c\\.))|(?:\\\/(?:%2e){2})"),
15
+ Regexp.new("(?:%c0%ae\\\/)|(?:(?:\\\/|\\\\)(home|conf|usr|etc|proc|opt|s?bin|local|dev|tmp|kern|[br]oot|sys|system|windows|winnt|program|%[a-z_-]{3,}%)(?:\\\/|\\\\))|(?:(?:\\\/|\\\\)inetpub|localstart\\.asp|boot\\.ini)"),
16
+ Regexp.new("(?:etc\\\/\\W*passwd)")
17
+ ]
18
+ def self.isPathTraversal(value)
19
+ if !value.instance_of? String
20
+ return false
21
+ end
22
+ if generallySafe(value)
23
+ return false
24
+ end
25
+ PATH_TRAVERSAL_REGEXES.each do |pattern|
26
+ if value.match(pattern)
27
+ return true
28
+ end
29
+ end
30
+ false
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+ # See the file "LICENSE" for the full license governing this code.
3
+
4
+ require 'tcell_agent/sensor_events/util/sanitizer_utilities'
5
+
6
+
7
+ # Some Rules Originate from ModSecurity
8
+ # ModSecurity for Apache 2.x, http://www.modsecurity.org/
9
+ # Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
10
+
11
+ module TCellAgent
12
+ class AppSensor
13
+ SQLI_PATTERNS = [
14
+ /(?i:(?i:\d[\"'`´’‘]\s+[\"'`´’‘]\s+\d)|(?:^admin\s*?[\"'`´’‘]|(\/\*)+[\"'`´’‘]+\s?(?:--|#|\/\*|{)?)|(?:[\"'`´’‘]\s*?\b(x?or|div|like|between|and)\b\s*?[+<>=(),-]\s*?[\d\"'`´’‘])|(?:[\"'`´’‘]\s*?[^\w\s]?=\s*?[\"'`´’‘])|(?:[\"'`´’‘]\W*?[+=]+\W*?[\"'`´’‘])|(?:[\"'`´’‘]\s*?[!=|][\d\s!=+-]+.*?[\"'`´’‘(].*?$)|(?:[\"'`´’‘]\s*?[!=|][\d\s!=]+.*?\d+$)|(?:[\"'`´’‘]\s*?like\W+[\w\"'`´’‘(])|(?:\sis\s*?0\W)|(?:where\s[\s\w\.,-]+\s=)|(?:[\"'`´’‘][<>~]+[\"'`´’‘]))/,
15
+ #Hex Evasion (ModSecurity)
16
+ #/(?i:(?:\A|[^\d])0x[a-f\d]{3,}[a-f\d]*)+/,
17
+ #Order By (ModSecurity)
18
+ /\b(?i:having)\b\s+(\d{1,10}|'[^=]{1,10}')\s*?[=<>]|(?i:\bexecute(\s{1,5}[\w\.$]{1,5}\s{0,3})?\()|\bhaving\b ?(?:\d{1,10}|[\'\"][^=]{1,10}[\'\"]) ?[=<>]+|(?i:\bcreate\s+?table.{0,20}?\()|(?i:\blike\W*?char\W*?\()|(?i:(?:(select(.*?)case|from(.*?)limit|order\sby)))|exists\s(\sselect|select\Sif(null)?\s\(|select\Stop|select\Sconcat|system\s\(|\b(?i:having)\b\s+(\d{1,10})|'[^=]{1,10}')/,
19
+ # (ModSecurity)
20
+ #/(?i:([\s'\"`´’‘\(\)]*?)\b([\d\w]++)([\s'\"`´’‘\(\)]*?)(?:(?:=|<=>|r?like|sounds\s+like|regexp)([\s'\"`´’‘\(\)]*?)\2\b|(?:!=|<=|>=|<>|<|>|\^|is\s+not|not\s+like|not\s+regexp)([\s'\"`´’‘\(\)]*?)(?!\2)([\d\w]+)\b))/,
21
+ # Tautaulogy (ModSecurity)
22
+ /([';]--|--[\s\r\n\v\f]|(?:--[^-]*?-)|([^\-&])#.*?[\s\r\n\v\f]|;?\\x00)/,
23
+ /(?i:(?:@.+=\s*?\(\s*?select)|(?:\d+\s*?(x?or|div|like|between|and)\s*?\d+\s*?[\-+])|(?:\/\w+;?\s+(?:having|and|x?or|div|like|between|and|select)\W)|(?:\d\s+group\s+by.+\()|(?:(?:;|#|--)\s*?(?:drop|alter))|(?:(?:;|#|--)\s*?(?:update|insert)\s*?\w{2,})|(?:[^\w]SET\s*?@\w+)|(?:(?:n?and|x?x?or|div|like|between|and|not |\|\||\&\&)[\s(]+\w+[\s)]*?[!=+]+[\s\d]*?[\"'`´’‘=()]))/,
24
+ /(?i:(?:in\s*?\(+\s*?select)|(?:(?:n?and|x?x?or|div|like|between|and|not |\|\||\&\&)\s+[\s\w+]+(?:regexp\s*?\(|sounds\s+like\s*?[\"'`´’‘]|[=\d]+x))|([\"'`´’‘]\s*?\d\s*?(?:--|#))|(?:[\"'`´’‘][\%&<>^=]+\d\s*?(=|x?or|div|like|between|and))|(?:[\"'`´’‘]\W+[\w+-]+\s*?=\s*?\d\W+[\"'`´’‘])|(?:[\"'`´’‘]\s*?is\s*?\d.+[\"'`´’‘]?\w)|(?:[\"'`´’‘]\|?[\w-]{3,}[^\w\s.,]+[\"'`´’‘])|(?:[\"'`´’‘]\s*?is\s*?[\d.]+\s*?\W.*?[\"'`´’‘]))/,
25
+ /(?i:(?:[\"'`´’‘]\s*?\*.+(?:x?or|div|like|between|and|id)\W*?[\"'`´’‘]\d)|(?:\^[\"'`´’‘])|(?:^[\w\s\"'`´’‘-]+(?<=and\s)(?<=or|xor|div|like|between|and\s)(?<=xor\s)(?<=nand\s)(?<=not\s)(?<=\|\|)(?<=\&\&)\w+\()|(?:[\"'`´’‘][\s\d]*?[^\w\s]+\W*?\d\W*?.*?[\"'`´’‘\d])|(?:[\"'`´’‘]\s*?[^\w\s?]+\s*?[^\w\s]+\s*?[\"'`´’‘])|(?:[\"'`´’‘]\s*?[^\w\s]+\s*?[\W\d].*?(?:#|--))|(?:[\"'`´’‘].*?\*\s*?\d)|(?:[\"'`´’‘]\s*?(x?or|div|like|between|and)\s[^\d]+[\w-]+.*?\d)|(?:[()\*<>%+-][\w-]+[^\w\s]+[\"'`´’‘][^,]))/,
26
+ #Probing (ModSecurity)
27
+ #/(^[\"'`´’‘;]+|[\"'`´’‘;]+$)/,
28
+ #SQL Ops (ModSecurity)
29
+ #/(?i:(\!\=|\&\&|\|\||>>|<<|>=|<=|<>|<=>|xor|rlike|regexp|isnull)|(?:not\s+between\s+0\s+and)|(?:is\s+null)|(like\s+null)|(?:(?:^|\W)in[+\s]*\([\s\d\"]+[^()]*\))|(?:xor|<>|rlike(?:\s+binary)?)|(?:regexp\s+binary))/,
30
+ #Database strings (ModSecurity)
31
+ #/(?i:(?:m(?:s(?:ysaccessobjects|ysaces|ysobjects|ysqueries|ysrelationships|ysaccessstorage|ysaccessxml|ysmodules|ysmodules2|db)|aster\.\.sysdatabases|ysql\.db)|s(?:ys(?:\.database_name|aux)|chema(?:\W*\(|_name)|qlite(_temp)?_master)|d(?:atabas|b_nam)e\W*\(|information_schema|pg_(catalog|toast)|northwind|tempdb))/,
32
+ #Blind (ModSecurity)
33
+ #/(?i:(?:\b(?:(?:s(?:ys\.(?:user_(?:(?:t(?:ab(?:_column|le)|rigger)|object|view)s|c(?:onstraints|atalog))|all_tables|tab)|elect\b.{0,40}\b(?:substring|users?|ascii))|m(?:sys(?:(?:queri|ac)e|relationship|column|object)s|ysql\.(db|user))|c(?:onstraint_type|harindex)|waitfor\b\W*?\bdelay|attnotnull)\b|(?:locate|instr)\W+\()|\@\@spid\b)|\b(?:(?:s(?:ys(?:(?:(?:process|tabl)e|filegroup|object)s|c(?:o(?:nstraint|lumn)s|at)|dba|ibm)|ubstr(?:ing)?)|user_(?:(?:(?:constrain|objec)t|tab(?:_column|le)|ind_column|user)s|password|group)|a(?:tt(?:rel|typ)id|ll_objects)|object_(?:(?:nam|typ)e|id)|pg_(?:attribute|class)|column_(?:name|id)|xtype\W+\bchar|mb_users|rownum)\b|t(?:able_name\b|extpos\W+\()))/,
34
+ # (ModSecurity)
35
+ /(?i:(?i:\d[\"'`´’‘]\s+[\"'`´’‘]\s+\d)|(?:^admin\s*?[\"'`´’‘]|(\/\*)+[\"'`´’‘]+\s?(?:--|#|\/\*|{)?)|(?:[\"'`´’‘]\s*?\b(x?or|div|like|between|and)\b\s*?[+<>=(),-]\s*?[\d\"'`´’‘])|(?:[\"'`´’‘]\s*?[^\w\s]?=\s*?[\"'`´’‘])|(?:[\"'`´’‘]\W*?[+=]+\W*?[\"'`´’‘])|(?:[\"'`´’‘]\s*?[!=|][\d\s!=+-]+.*?[\"'`´’‘(].*?$)|(?:[\"'`´’‘]\s*?[!=|][\d\s!=]+.*?\d+$)|(?:[\"'`´’‘]\s*?like\W+[\w\"'`´’‘(])|(?:\sis\s*?0\W)|(?:where\s[\s\w\.,-]+\s=)|(?:[\"'`´’‘][<>~]+[\"'`´’‘]))/
36
+ # (ModSecurity)
37
+ #/(?i:(?:\sexec\s+xp_cmdshell)|(?:[\"'`´’‘]\s*?!\s*?[\"'`´’‘\w])|(?:from\W+information_schema\W)|(?:(?:(?:current_)?user|database|schema|connection_id)\s*?\([^\)]*?)|(?:[\"'`´’‘];?\s*?(?:select|union|having)\s*?[^\s])|(?:\wiif\s*?\()|(?:exec\s+master\.)|(?:union select @)|(?:union[\w(\s]*?select)|(?:select.*?\w?user\()|(?:into[\s+]+(?:dump|out)file\s*?[\"'`´’‘]))/
38
+ ]
39
+ def self.isSqli(value)
40
+ if !value.instance_of? String
41
+ return false
42
+ end
43
+ if generallySafe(value)
44
+ return false
45
+ end
46
+ SQLI_PATTERNS.each do |sqli_pattern|
47
+ if value.match(sqli_pattern)
48
+ return true
49
+ end
50
+ end
51
+ false
52
+ end
53
+ end
54
+ end
55
+
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+ # See the file "LICENSE" for the full license governing this code.
3
+
4
+ require 'tcell_agent/sensor_events/util/sanitizer_utilities'
5
+
6
+
7
+ # Some Rules Originate from ModSecurity
8
+ # ModSecurity for Apache 2.x, http://www.modsecurity.org/
9
+ # Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
10
+
11
+ module TCellAgent
12
+ class AppSensor
13
+ XSS_PATTERNS = [
14
+ Regexp.new("<(script|iframe|embed|frame|frameset|object|img|applet|body|html|style|layer|link|ilayer|meta|bgsound)"),
15
+ Regexp.new("(alert|on\\w+|function\\s+\\w+)\\s*\\(\\s*(['+\\d\\w](,?\\s*['+\\d\\w]*)*)*\\s*\\)"),
16
+ Regexp.new("(?:\"[^\"]*[^-]?>)|(?:[^\\w\\s]\\s*\\/>)|(?:>\")"),
17
+ Regexp.new("(?:\"+.*[<=]\\s*\"[^\"]+\")|(?:\"\\s*\\w+\\s*=)|(?:>\\w=\\/)|(?:#.+\\)[\"\\s]*>)|(?:\"\\s*(?:src|style|on\\w+)\\s*=\\s*\")|(?:[^\"]?\"[,;\\s]+\\w*[\\[\\(])"),
18
+ Regexp.new("(?:^>[\\w\\s]*<\\/?\\w{2,}>)"),
19
+ Regexp.new("(?:with\\s*\\(\\s*.+\\s*\\)\\s*\\w+\\s*\\()|(?:(?:do|while|for)\\s*\\([^)]*\\)\\s*\\{)|(?:\\/[\\w\\s]*\\[\\W*\\w)"),
20
+ Regexp.new("(?:[=(].+\\?.+:)|(?:with\\([^)]*\\)\\))|(?:\\.\\s*source\\W)"),
21
+ Regexp.new("(?:[\".]script\\s*\\()|(?:\\$\\$?\\s*\\(\\s*[\\w\"])|(?:\\/[\\w\\s]+\\/\\.)|(?:=\\s*\\/\\w+\\/\\s*\\.)|(?:(?:this|window|top|parent|frames|self|content)\\[\\s*[(,\"]*\\s*[\\w\\$])|(?:,\\s*new\\s+\\w+\\s*[,;)])"),
22
+ Regexp.new("(?:=\\s*\\w+\\s*\\+\\s*\")|(?:\\+=\\s*\\(\\s\")|(?:!+\\s*[\\d.,]+\\w?\\d*\\s*\\?)|(?:=\\s*\\[s*\\])|(?:\"\\s*\\+\\s*\")|(?:[^\\s]\\[\\s*\\d+\\s*\\]\\s*[;+])|(?:\"\\s*[&|]+\\s*\")|(?:\\/\\s*\\?\\s*\")|(?:\\/\\s*\\)\\s*\\[)|(?:\\d\\?.+:\\d)|(?:\\]\\s*\\[\\W*\\w)|(?:[^\\s]\\s*=\\s*\\/)"),
23
+ Regexp.new("<iframe.*")
24
+ ]
25
+ def self.isXss(value)
26
+ if !value.instance_of? String
27
+ return false
28
+ end
29
+ if generallySafe(value)
30
+ return false
31
+ end
32
+ XSS_PATTERNS.each do |xss_pattern|
33
+ if value.match(xss_pattern)
34
+ return true
35
+ end
36
+ end
37
+ false
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,26 @@
1
+ # See the file "LICENSE" for the full license governing this code.
2
+
3
+ require 'tcell_agent/userinfo'
4
+ require 'tcell_agent/logger'
5
+ require 'tcell_agent/sensor_events/honeytokens'
6
+
7
+ module TCellAgent
8
+ if defined?(Authlogic)
9
+ TCellAgent::UserInformation.class_eval do
10
+ class << self
11
+ alias_method :original_getUserFromRequest, :getUserFromRequest
12
+ def getUserFromRequest(request)
13
+ orig_user_id = original_getUserFromRequest(request)
14
+ begin
15
+ if request.session and request.session.has_key?("user_credentials_id")
16
+ return request.session["user_credentials_id"].to_s
17
+ end
18
+ rescue Exception => e
19
+ return orig_user_id
20
+ end
21
+ return orig_user_id
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,148 @@
1
+ # See the file "LICENSE" for the full license governing this code.
2
+ require 'fileutils'
3
+ require 'json'
4
+ require 'socket'
5
+ require 'securerandom'
6
+
7
+ module TCellAgent
8
+ class << self
9
+ attr_accessor :configuration
10
+ end
11
+
12
+ def self.configure
13
+ self.configuration ||= Configuration.new
14
+ yield(configuration)
15
+ end
16
+
17
+ class Configuration
18
+ attr_accessor :version, :app_id, :api_key, :hmac_key,
19
+ :tcell_api_url, :tcell_input_url,
20
+ :enabled, :logging_options,
21
+ :fetch_policies_from_tcell, :instrument_for_events,
22
+ :preload_policy_filename,
23
+ :proxy_host, :proxy_port, :proxy_username, :proxy_password,
24
+ :use_websockets, :host_identifier, :session_cookie_names,
25
+ :uuid,
26
+ :company,
27
+ :event_batch_size_limit, :event_time_limit_seconds,
28
+ :default_log_filename,
29
+ :base_dir,
30
+ :cache_filename,
31
+ :js_agent_api_base_url,
32
+ :js_agent_url
33
+
34
+ attr_accessor :exp_config_settings
35
+
36
+
37
+ def initialize(filename="config/tcell_agent.config", useapp=nil)
38
+ @version = 0
39
+ @exp_config_settings = true
40
+
41
+
42
+ @fetch_policies_from_tcell = true
43
+ @instrument_for_events = true
44
+ @enabled = true
45
+ @cache_filename = "tcell/tcell_agent.cache"
46
+ @default_log_filename = "tcell/tcell_agent.log"
47
+ read_config_using_env
48
+ read_config_from_file(filename)
49
+
50
+ @tcell_api_url ||= "https://api.tcell.io/api/v1"
51
+ @tcell_input_url ||= "https://input.tcell.io/api/v1"
52
+ @js_agent_api_base_url ||= nil
53
+ @js_agent_url ||= "https://api.tcell.io/tcellagent.min.js"
54
+ @event_batch_size_limit = 25
55
+ @event_time_limit_seconds = 30
56
+
57
+ begin
58
+ @host_identifier = (Socket.gethostname() || "localhost")
59
+ rescue Exception => e
60
+ @host_identifier = "host_identifier_not_found"
61
+ end
62
+ @uuid = SecureRandom.uuid
63
+
64
+ FileUtils::mkdir_p File.dirname(@cache_filename)
65
+ if @logging_options and @logging_options["filename"]
66
+ FileUtils::mkdir_p File.dirname(@logging_options["filename"])
67
+ else
68
+ FileUtils::mkdir_p File.dirname(@default_log_filename)
69
+ end
70
+ end
71
+ def read_config_using_env
72
+ @app_id = ENV["TCELL_APP_ID"]
73
+ @api_key = ENV["TCELL_API_KEY"]
74
+ @hmac_key = ENV["TCELL_HMAC_KEY"]
75
+ @tcell_api_url = ENV["TCELL_API_URL"]
76
+ @tcell_input_url = ENV["TCELL_INPUT_URL"]
77
+ end
78
+ def read_config_from_file(filename)
79
+ if File.file?(filename)
80
+ #puts "tCell.io: Loading from file"
81
+ begin
82
+ config_text = open(filename).read
83
+ config = JSON.parse(config_text)
84
+ if (config["version"] == 1)
85
+ # Required
86
+ app_data = config["applications"][0] #Default
87
+ @version = 1
88
+ @app_id ||= app_data["app_id"]
89
+ @app_id ||= app_data["name"]
90
+ @api_key ||= app_data["api_key"]
91
+
92
+ # Optional
93
+ @enabled = app_data.fetch("enabled", true)
94
+ @preload_policy_filename = app_data.fetch("preload_policy_filename", nil)
95
+ @fetch_policies_from_tcell = app_data.fetch("fetch_policies_from_tcell", @fetch_policies_from_tcell)
96
+ @instrument_for_events = app_data.fetch("instrument_for_events", @instrument_for_events)
97
+
98
+ @logging_options = app_data.fetch("logging_options", {})
99
+
100
+ @tcell_api_url = app_data.fetch("tcell_api_url", @tcell_api_url)
101
+ @tcell_input_url = app_data.fetch("tcell_input_url", @tcell_input_url)
102
+
103
+ @proxy_host = app_data["proxy_host"]
104
+ @proxy_port = app_data["proxy_port"]
105
+ @proxy_username = app_data["proxy_username"]
106
+ @proxy_password = app_data["proxy_password"]
107
+
108
+ @use_websockets = app_data["use_websockets"]
109
+ @host_identifier = app_data["host_identifier"]
110
+ if (@host_identifier == nil)
111
+ @host_identifier = (Socket.gethostname() || "localhost")
112
+ end
113
+ @hmac_key ||= app_data["hmac_key"] # if not already set
114
+ @session_cookie_names = app_data["session_cookie_names"]
115
+ @uuid = SecureRandom.uuid
116
+ if (@uuid == nil)
117
+ @uuid = "secure-random-failed"
118
+ end
119
+
120
+ if app_data.key?("js_agent_api_base_url")
121
+ @js_agent_api_base_url = app_data["js_agent_api_base_url"]
122
+ end
123
+ if app_data.key?("js_agent_url")
124
+ @js_agent_url = app_data["js_agent_url"]
125
+ end
126
+
127
+ # Causes old event url to be used
128
+ @company = app_data["company"]
129
+
130
+
131
+ else
132
+ puts " ********* ********* ********* *********"
133
+ puts "* tCell.io *"
134
+ puts "* Unsupported config file version *"
135
+ puts " ********* ********* ********* *********"
136
+ end
137
+ rescue Exception => e
138
+ puts " ********* ********* ********* *********"
139
+ puts "* tCell.io *"
140
+ puts "* Could not load config file *"
141
+ puts " ********* ********* ********* *********"
142
+ puts e
143
+ end #begin
144
+ end # filename exist
145
+ end #def read
146
+ end # class
147
+ TCellAgent.configuration ||= TCellAgent::Configuration.new
148
+ end