elasticpot 2.0.1.dev0__tar.gz → 2.0.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/CHANGELOG.md +49 -4
  2. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/MANIFEST.in +3 -4
  3. {elasticpot-2.0.1.dev0/elasticpot.egg-info → elasticpot-2.0.3}/PKG-INFO +6 -1
  4. elasticpot-2.0.3/core/httpclient.py +71 -0
  5. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/core/tools.py +5 -6
  6. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/cli.py +43 -6
  7. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/Dockerfile +1 -0
  8. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/INSTALL.md +2 -2
  9. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/INSTALLWIN.md +3 -3
  10. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/mysql/mysql.sql +10 -5
  11. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/postgres/postgres.sql +10 -0
  12. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/sqlite3/sqlite3.sql +10 -5
  13. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/etc/honeypot.cfg.base +44 -31
  14. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3/elasticpot}/honeypot.py +1 -1
  15. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3/elasticpot.egg-info}/PKG-INFO +6 -1
  16. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot.egg-info/SOURCES.txt +1 -1
  17. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot.egg-info/requires.txt +5 -0
  18. {elasticpot-2.0.1.dev0/elasticpot → elasticpot-2.0.3}/honeypot.py +1 -1
  19. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/couch.py +5 -1
  20. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/datadog.py +4 -8
  21. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/discord.py +4 -9
  22. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/elastic.py +2 -0
  23. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/mysql.py +95 -42
  24. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/nlcvapi.py +4 -10
  25. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/postgres.py +21 -21
  26. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/sqlite.py +10 -20
  27. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/telegram.py +8 -12
  28. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/xmpp.py +1 -1
  29. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/setup.cfg +0 -3
  30. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/setup.py +9 -2
  31. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/LICENSE +0 -0
  32. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/README.md +0 -0
  33. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/core/__init__.py +0 -0
  34. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/core/config.py +0 -0
  35. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/core/logfile.py +0 -0
  36. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/core/output.py +0 -0
  37. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/core/paths.py +0 -0
  38. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/core/protocol.py +0 -0
  39. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/__init__.py +0 -0
  40. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/PLUGINS.md +0 -0
  41. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/TODO.md +0 -0
  42. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/datadog/README.md +0 -0
  43. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/discord/README.md +0 -0
  44. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/geoipupdtask.ps1 +0 -0
  45. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/mysql/README.md +0 -0
  46. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/mysql/READMEWIN.md +0 -0
  47. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/postgres/README.md +0 -0
  48. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/postgres/READMEWIN.md +0 -0
  49. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/slack/README.md +0 -0
  50. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/sqlite3/README.md +0 -0
  51. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/sqlite3/READMEWIN.md +0 -0
  52. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/docs/telegram/README.md +0 -0
  53. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/aliases.json +0 -0
  54. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/banner.json +0 -0
  55. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/cluster.json +0 -0
  56. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/clusterstore.json +0 -0
  57. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/error.json +0 -0
  58. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/index1long.json +0 -0
  59. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/index1short.json +0 -0
  60. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/index2long.json +0 -0
  61. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/index2short.json +0 -0
  62. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/indices.txt +0 -0
  63. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/mapping.json +0 -0
  64. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/nodes.json +0 -0
  65. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/nodes2.json +0 -0
  66. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/nodes2.txt +0 -0
  67. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/pluginhead.html +0 -0
  68. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/search.json +0 -0
  69. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/search2.json +0 -0
  70. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/settings.json +0 -0
  71. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/stats1.json +0 -0
  72. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/stats2.json +0 -0
  73. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/responses/store.json +0 -0
  74. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/test/.gitignore +0 -0
  75. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/test/README.md +0 -0
  76. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/test/baseline +0 -0
  77. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/test/test.py +0 -0
  78. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot/data/test/testurls.txt +0 -0
  79. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot.egg-info/dependency_links.txt +0 -0
  80. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot.egg-info/entry_points.txt +0 -0
  81. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/elasticpot.egg-info/top_level.txt +0 -0
  82. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/README.md +0 -0
  83. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/__init__.py +0 -0
  84. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/hpfeed.py +0 -0
  85. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/influx2.py +0 -0
  86. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/jsonlog.py +0 -0
  87. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/kafka.py +0 -0
  88. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/localsyslog.py +0 -0
  89. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/mongodb.py +0 -0
  90. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/redisdb.py +0 -0
  91. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/rethinkdblog.py +0 -0
  92. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/slack.py +0 -0
  93. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/socketlog.py +0 -0
  94. {elasticpot-2.0.1.dev0 → elasticpot-2.0.3}/output_plugins/textlog.py +0 -0
@@ -5,15 +5,60 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [2.0.1]
8
+ ## [2.0.3]
9
9
 
10
- ### Added in version 2.0.1
10
+ ### Added in version 2.0.3
11
11
 
12
- * Nothing so far
12
+ * Nothing
13
13
 
14
- ### Changed in version 2.0.1
14
+ ### Changed in version 2.0.3
15
15
 
16
16
  * Increased the version number
17
+ * The `restart` command wasn't working correctly on Windows due to a race
18
+ condition. Fixed.
19
+ * Fixed a problem in the MySQL plugin that made it unresponsive under high
20
+ traffic
21
+ * **Warning!** The MySQL, PostgreSQL, and SQLite3 schemas have changed.
22
+ Specifically, in the `urls` table, the key `path` is now `UNIQUE` and so are
23
+ the keys `user_agent` in `user_agents`, `content_type` in `content_types`,
24
+ `accept_language` in `accept_language`, and `message` in `message`. If you are
25
+ already using the corresponding output plugins and have gathered some data
26
+ into these tables, you *must* remove any duplicated rows in these tables
27
+ (leave only the one with the smallest `id`) and to modify these keys and they
28
+ indices to be unique or the plugins will cause errors. For instance, something
29
+ like
30
+
31
+ ```MySQL
32
+ DELETE t1 FROM `urls` t1
33
+ INNER JOIN `urls` t2
34
+ WHERE t1.`path` = t2.`path` AND t1.`id` > t2.`id`;
35
+ ALTER TABLE `path` DROP INDEX `path`;
36
+ ALTER TABLE `path` ADD UNIQUE (`path`);
37
+ ...
38
+ ```
39
+
40
+ ## [2.0.2]
41
+
42
+ ### Added in version 2.0.2
43
+
44
+ * Nothing
45
+
46
+ ### Changed in version 2.0.2
47
+
48
+ * Increased the version number
49
+ * The `datadog`, `discord`, `nlcvapi`, and `telegram` plugins now use a secure
50
+ connection (HTTPS) by default
51
+ * The `elastic` plugin now warns if the `ssl` is set while certificate
52
+ verification (`verify_certs`) is off
53
+ * The `couch` plugin now uses authentication mechanism that does not pass the
54
+ username and password in the URL
55
+
56
+ ## [2.0.1]
57
+
58
+ ### Changed in version 2.0.1
59
+
60
+ * The honeypot was released with an incorrect version - "2.0.1-dev0" instead of
61
+ "2.0.0". Fixed by changing it and releasing version 2.0.1
17
62
 
18
63
  ## [2.0.0]
19
64
 
@@ -1,9 +1,8 @@
1
- include honeypot.py
2
- include setup.cfg
1
+ include CHANGELOG.md
3
2
  include LICENSE
4
3
  include README.md
5
- include CHANGELOG.md
6
- graft elasticpot
4
+ include honeypot.py
7
5
  graft core
6
+ graft elasticpot
8
7
  graft output_plugins
9
8
  prune elasticpot/data/test/develop
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: elasticpot
3
- Version: 2.0.1.dev0
3
+ Version: 2.0.3
4
4
  Summary: An ElasticSearch Honeypot
5
5
  Home-page: https://gitlab.com/bontchev/elasticpot
6
6
  Author: Vesselin Bontchev
@@ -43,11 +43,13 @@ Requires-Dist: twisted>=21; python_version >= "3"
43
43
  Provides-Extra: couchdb
44
44
  Requires-Dist: couchdb; extra == "couchdb"
45
45
  Provides-Extra: datadog
46
+ Requires-Dist: certifi; extra == "datadog"
46
47
  Requires-Dist: cryptography<=2.8; python_version < "3" and extra == "datadog"
47
48
  Requires-Dist: pyOpenSSL<=18.0.0; python_version < "3" and extra == "datadog"
48
49
  Requires-Dist: cryptography; python_version >= "3" and extra == "datadog"
49
50
  Requires-Dist: pyOpenSSL; python_version >= "3" and extra == "datadog"
50
51
  Provides-Extra: discord
52
+ Requires-Dist: certifi; extra == "discord"
51
53
  Provides-Extra: elastic
52
54
  Requires-Dist: elasticsearch<=7.13; python_version < "3" and extra == "elastic"
53
55
  Requires-Dist: numpy<=1.16.6; python_version < "3" and extra == "elastic"
@@ -71,6 +73,7 @@ Provides-Extra: mysql
71
73
  Requires-Dist: PyMySQL; python_version < "3" and extra == "mysql"
72
74
  Requires-Dist: mysqlclient>=1.3.12; python_version >= "3" and extra == "mysql"
73
75
  Provides-Extra: nlcvapi
76
+ Requires-Dist: certifi; extra == "nlcvapi"
74
77
  Requires-Dist: pyOpenSSL<=18.0.0; python_version < "3" and extra == "nlcvapi"
75
78
  Requires-Dist: pyOpenSSL; python_version >= "3" and extra == "nlcvapi"
76
79
  Provides-Extra: postgres
@@ -87,12 +90,14 @@ Requires-Dist: slack-sdk; python_version >= "3" and extra == "slack"
87
90
  Provides-Extra: socketlog
88
91
  Provides-Extra: sqlite
89
92
  Provides-Extra: telegram
93
+ Requires-Dist: certifi; extra == "telegram"
90
94
  Provides-Extra: textlog
91
95
  Provides-Extra: xmpp
92
96
  Requires-Dist: xmpppy>=0.7.3; extra == "xmpp"
93
97
  Provides-Extra: all
94
98
  Requires-Dist: Automat<20; python_version < "3" and extra == "all"
95
99
  Requires-Dist: PyMySQL; python_version < "3" and extra == "all"
100
+ Requires-Dist: certifi; extra == "all"
96
101
  Requires-Dist: confluent-kafka; python_version >= "3" and extra == "all"
97
102
  Requires-Dist: confluent-kafka<1.0; python_version < "3" and extra == "all"
98
103
  Requires-Dist: couchdb; extra == "all"
@@ -0,0 +1,71 @@
1
+ from __future__ import absolute_import
2
+
3
+ from io import open
4
+
5
+ from twisted.internet.ssl import Certificate, trustRootFromCertificates
6
+ from twisted.python.log import msg
7
+ from twisted.web.client import Agent, BrowserLikePolicyForHTTPS
8
+
9
+
10
+ class _LegacyWebClientContextFactory(object):
11
+ @staticmethod
12
+ def build():
13
+ from twisted.internet.ssl import ClientContextFactory
14
+
15
+ class WebClientContextFactory(ClientContextFactory):
16
+ def getContext(self, hostname, port):
17
+ return ClientContextFactory.getContext(self)
18
+
19
+ return WebClientContextFactory()
20
+
21
+
22
+ def _load_trust_root_from_pem_bundle(pem_path):
23
+ with open(pem_path, 'r', encoding='utf-8') as fh:
24
+ content = fh.read()
25
+ certs = []
26
+ end_marker = '-----END CERTIFICATE-----'
27
+ for chunk in content.split(end_marker):
28
+ chunk = chunk.strip()
29
+ if not chunk:
30
+ continue
31
+ pem = chunk + '\n' + end_marker + '\n'
32
+ certs.append(Certificate.loadPEM(pem))
33
+ if not certs:
34
+ return None
35
+ return trustRootFromCertificates(certs)
36
+
37
+
38
+ def _trust_root(ca_certs):
39
+ if ca_certs:
40
+ try:
41
+ return _load_trust_root_from_pem_bundle(ca_certs)
42
+ except Exception as e:
43
+ msg('Failed to load CA bundle {}: {}'.format(ca_certs, e))
44
+ return None
45
+
46
+ try:
47
+ import certifi
48
+ return _load_trust_root_from_pem_bundle(certifi.where())
49
+ except Exception:
50
+ return None
51
+
52
+
53
+ def create_http_agent(reactor, pool, plugin_name, verify_tls=True, ca_certs=None):
54
+ """
55
+ Build a Twisted Agent with sane HTTPS defaults.
56
+ verify_tls=True uses BrowserLikePolicyForHTTPS for cert + hostname checks.
57
+ verify_tls=False falls back to a legacy context factory for compatibility.
58
+ """
59
+ if verify_tls:
60
+ return Agent(
61
+ reactor,
62
+ contextFactory=BrowserLikePolicyForHTTPS(trustRoot=_trust_root(ca_certs)),
63
+ pool=pool
64
+ )
65
+
66
+ msg('{}: TLS certificate verification is disabled.'.format(plugin_name))
67
+ return Agent(
68
+ reactor,
69
+ contextFactory=_LegacyWebClientContextFactory.build(),
70
+ pool=pool
71
+ )
@@ -15,13 +15,15 @@ try:
15
15
  from urllib.request import urlopen
16
16
  from urllib.parse import urlsplit, urlunsplit
17
17
  except ImportError:
18
- from urllib import urlopen
18
+ from urllib2 import urlopen # type: ignore
19
19
  from urlparse import urlsplit, urlunsplit # type: ignore
20
20
 
21
21
 
22
22
  if version_info[0] >= 3:
23
23
  def decode(x):
24
- return x.decode('utf-8')
24
+ if isinstance(x, bytes):
25
+ return x.decode('utf-8')
26
+ return x
25
27
  def encode(x):
26
28
  return x.encode()
27
29
  def unicode(x):
@@ -42,10 +44,7 @@ def get_utc_time(unix_time):
42
44
 
43
45
  def get_public_ip(ip_reporter):
44
46
  try:
45
- if version_info[0] < 3:
46
- return urlopen(ip_reporter).read().decode('latin1', errors='replace').encode('utf-8')
47
- else:
48
- return urlopen(ip_reporter).read()
47
+ return decode(urlopen(ip_reporter, timeout=10).read())
49
48
  except:
50
49
  return '127.0.0.1'
51
50
 
@@ -48,6 +48,7 @@ from os.path import (
48
48
  from re import search, IGNORECASE
49
49
  from shutil import copy2
50
50
  import sys
51
+ from time import sleep
51
52
 
52
53
  from core.paths import bundled, get_workdir, workdir_path
53
54
 
@@ -62,8 +63,27 @@ def _ensure_dir(p):
62
63
 
63
64
 
64
65
  def _file_differs(a, b):
65
- with open(a, 'r') as fa, open(b, 'r') as fb:
66
- return fa.read() != fb.read()
66
+ """Return True if files differ. Ignores line-ending differences for text files."""
67
+ # Try text mode first (normalizes \r\n, \r, \n)
68
+ try:
69
+ with open(a, 'r') as fa, open(b, 'r') as fb:
70
+ while True:
71
+ line_a = fa.readline()
72
+ line_b = fb.readline()
73
+ if line_a != line_b:
74
+ return True
75
+ if not line_a: # EOF on both
76
+ return False
77
+ except UnicodeDecodeError:
78
+ # Binary fallback: compare in chunks without loading whole file
79
+ with open(a, 'rb') as fa, open(b, 'rb') as fb:
80
+ while True:
81
+ chunk_a = fa.read(8192)
82
+ chunk_b = fb.read(8192)
83
+ if chunk_a != chunk_b:
84
+ return True
85
+ if not chunk_a:
86
+ return False
67
87
 
68
88
 
69
89
  def _copy_if_missing(src, dst, label=None):
@@ -363,6 +383,7 @@ def cmd_stop(args):
363
383
  return
364
384
 
365
385
  print('Stopping the honeypot (PID {})... '.format(pid), end='')
386
+ sys.stdout.flush()
366
387
 
367
388
  if name == 'nt':
368
389
  _stop_windows(pid, pidfile)
@@ -372,7 +393,6 @@ def cmd_stop(args):
372
393
 
373
394
  def _stop_posix(pid, pidfile):
374
395
  from signal import SIGKILL, SIGTERM
375
- from time import sleep
376
396
  kill(pid, SIGTERM)
377
397
  for _ in range(60):
378
398
  sleep(1)
@@ -406,11 +426,28 @@ def _stop_windows(pid, pidfile):
406
426
  finally:
407
427
  _devnull.close()
408
428
 
409
- if ret == 0 or not _pid_running(pid):
410
- print('Stopped.')
429
+ if ret != 0 and _pid_running(pid):
430
+ print()
431
+ print(
432
+ 'Warning: taskkill returned {}, process may still be running.'.format(ret)
433
+ )
434
+ remove(pidfile)
435
+ return
436
+
437
+ # taskkill /F calls TerminateProcess() which is asynchronous: the call
438
+ # returns before the kernel has finished tearing down the process and
439
+ # releasing its resources (sockets, handles, etc.). Poll until the
440
+ # process is truly gone so that a subsequent 'start' does not race with
441
+ # the old process still holding port 3389.
442
+ for _ in range(30):
443
+ if not _pid_running(pid):
444
+ break
445
+ sleep(0.5)
411
446
  else:
412
447
  print()
413
- print('Warning: taskkill returned {}, process may still be running.'.format(ret))
448
+ print('Warning: process {} did not exit within 15 s.'.format(pid))
449
+
450
+ print('Stopped.')
414
451
  remove(pidfile)
415
452
 
416
453
 
@@ -51,6 +51,7 @@ USER elasticpot
51
51
  # docker run \
52
52
  # -v /path/to/honeypot.cfg:/elasticpot/etc/honeypot.cfg \
53
53
  # -v /path/to/data:/elasticpot/data \
54
+ # -v /path/to/log:/elasticpot/log \
54
55
  # -p 9200:9200 elasticpot
55
56
  #
56
57
  CMD ["elasticpot", "run"]
@@ -168,7 +168,7 @@ working) and `Dockerfile` into the working directory.
168
168
  The configuration for the honeypot is stored in `etc/honeypot.cfg.base` and
169
169
  `etc/honeypot.cfg`. Both files are read on startup but entries from
170
170
  `etc/honeypot.cfg` take precedence. The `.base` file contains the default
171
- settings and should not be edited it may be overwritten by upgrades. All
171
+ settings and should not be edited - it may be overwritten by upgrades. All
172
172
  your customisations should go into `etc/honeypot.cfg`.
173
173
 
174
174
  To run with a standard configuration there is no need to change anything.
@@ -418,7 +418,7 @@ $ source ~/elasticpot-env/bin/activate
418
418
 
419
419
  where `[plugin_list]` is as explained above.
420
420
 
421
- Note that `elasticpot init` is safe to re-run it never overwrites files that
421
+ Note that `elasticpot init` is safe to re-run - it never overwrites files that
422
422
  you have already edited or created (such as `etc/honeypot.cfg`). It only
423
423
  copies files that are missing, so any new defaults added by an upgrade are
424
424
  picked up automatically.
@@ -33,7 +33,7 @@ programs (if they are not already present):
33
33
 
34
34
  - **Database server** (optional). If you want the honeypot to send the data
35
35
  it collects to a local database server (e.g., MySQL), make sure to install
36
- it again, for all users and not just for the current one.
36
+ it - again, for all users and not just for the current one.
37
37
 
38
38
  - The latest version of the **VS C++ redistributable** (required by some of
39
39
  the database output plugins, e.g., for MySQL). Version 14 or higher should
@@ -188,7 +188,7 @@ working directory.
188
188
  The configuration for the honeypot is stored in `etc\honeypot.cfg.base` and
189
189
  `etc\honeypot.cfg`. Both the `*.cfg.base` and the `*.cfg` files are read on
190
190
  startup but entries from the `*.cfg` files take precedence. The `*.base` files
191
- contain the default settings and should not be edited they may be overwritten
191
+ contain the default settings and should not be edited - they may be overwritten
192
192
  by future updates. All your customisations should go into the `*.cfg` files.
193
193
 
194
194
  To run with a standard configuration there is no need to change anything.
@@ -429,7 +429,7 @@ PS C:\elasticpot-workdir> C:\elasticpot-env\Scripts\activate.ps1
429
429
 
430
430
  where `[plugin_list]` is as explained above.
431
431
 
432
- Note that `elasticpot init` is safe to re-run it never overwrites files that
432
+ Note that `elasticpot init` is safe to re-run - it never overwrites files that
433
433
  you have already edited or created (such as `etc\honeypot.cfg`). It only
434
434
  copies files that are missing, so any new defaults added by an upgrade are
435
435
  picked up automatically.
@@ -22,7 +22,8 @@ CREATE TABLE IF NOT EXISTS `connections` (
22
22
  CREATE TABLE IF NOT EXISTS `urls` (
23
23
  `id` int NOT NULL AUTO_INCREMENT,
24
24
  `path` varchar(255) DEFAULT NULL,
25
- PRIMARY KEY (`id`)
25
+ PRIMARY KEY (`id`),
26
+ UNIQUE (`path`)
26
27
  );
27
28
 
28
29
  CREATE TABLE IF NOT EXISTS `payloads` (
@@ -36,25 +37,29 @@ CREATE TABLE IF NOT EXISTS `payloads` (
36
37
  CREATE TABLE IF NOT EXISTS `user_agents` (
37
38
  `id` int NOT NULL AUTO_INCREMENT,
38
39
  `user_agent` varchar(255) DEFAULT NULL,
39
- PRIMARY KEY (`id`)
40
+ PRIMARY KEY (`id`),
41
+ UNIQUE (`user_agent`)
40
42
  );
41
43
 
42
44
  CREATE TABLE IF NOT EXISTS `content_types` (
43
45
  `id` int NOT NULL AUTO_INCREMENT,
44
46
  `content_type` varchar(255) DEFAULT NULL,
45
- PRIMARY KEY (`id`)
47
+ PRIMARY KEY (`id`),
48
+ UNIQUE (`content_type`)
46
49
  );
47
50
 
48
51
  CREATE TABLE IF NOT EXISTS `accept_languages` (
49
52
  `id` int NOT NULL AUTO_INCREMENT,
50
53
  `accept_language` varchar(255) DEFAULT NULL,
51
- PRIMARY KEY (`id`)
54
+ PRIMARY KEY (`id`),
55
+ UNIQUE (`accept_language`)
52
56
  );
53
57
 
54
58
  CREATE TABLE IF NOT EXISTS `messages` (
55
59
  `id` int NOT NULL AUTO_INCREMENT,
56
60
  `message` varchar(10) DEFAULT NULL,
57
- PRIMARY KEY (`id`)
61
+ PRIMARY KEY (`id`),
62
+ UNIQUE (`message`)
58
63
  );
59
64
 
60
65
  CREATE TABLE IF NOT EXISTS `sensors` (
@@ -24,6 +24,8 @@ CREATE TABLE IF NOT EXISTS urls (
24
24
  path varchar(255) DEFAULT NULL
25
25
  );
26
26
 
27
+ CREATE UNIQUE INDEX path_idx ON urls (path);
28
+
27
29
  CREATE TABLE IF NOT EXISTS payloads (
28
30
  id SERIAL PRIMARY KEY,
29
31
  input varchar(3000) NOT NULL,
@@ -37,21 +39,29 @@ CREATE TABLE IF NOT EXISTS user_agents (
37
39
  user_agent varchar(255) DEFAULT NULL
38
40
  );
39
41
 
42
+ CREATE UNIQUE INDEX user_agent_idx ON user_agents (user_agent);
43
+
40
44
  CREATE TABLE IF NOT EXISTS content_types (
41
45
  id SERIAL PRIMARY KEY,
42
46
  content_type varchar(255) DEFAULT NULL
43
47
  );
44
48
 
49
+ CREATE UNIQUE INDEX content_type_idx ON content_types (content_type);
50
+
45
51
  CREATE TABLE IF NOT EXISTS accept_languages (
46
52
  id SERIAL PRIMARY KEY,
47
53
  accept_language varchar(255) DEFAULT NULL
48
54
  );
49
55
 
56
+ CREATE UNIQUE INDEX accept_language_idx ON accept_languages (accept_language);
57
+
50
58
  CREATE TABLE IF NOT EXISTS messages (
51
59
  id SERIAL PRIMARY KEY,
52
60
  message varchar(10) DEFAULT NULL
53
61
  );
54
62
 
63
+ CREATE UNIQUE INDEX message_idx ON messages (message);
64
+
55
65
  CREATE TABLE IF NOT EXISTS sensors (
56
66
  id SERIAL PRIMARY KEY,
57
67
  name varchar(255) DEFAULT NULL
@@ -21,7 +21,8 @@ CREATE INDEX IF NOT EXISTS `ip2_idx` ON `connections` (`timestamp`, `ip`);
21
21
 
22
22
  CREATE TABLE IF NOT EXISTS `urls` (
23
23
  `id` INTEGER PRIMARY KEY,
24
- `path` VARCHAR(255) DEFAULT NULL
24
+ `path` VARCHAR(255) DEFAULT NULL,
25
+ UNIQUE (`path`)
25
26
  );
26
27
 
27
28
  CREATE TABLE IF NOT EXISTS `payloads` (
@@ -33,22 +34,26 @@ CREATE TABLE IF NOT EXISTS `payloads` (
33
34
 
34
35
  CREATE TABLE IF NOT EXISTS `user_agents` (
35
36
  `id` INTEGER PRIMARY KEY,
36
- `user_agent` VARCHAR(255) DEFAULT NULL
37
+ `user_agent` VARCHAR(255) DEFAULT NULL,
38
+ UNIQUE (`user_agent`)
37
39
  );
38
40
 
39
41
  CREATE TABLE IF NOT EXISTS `content_types` (
40
42
  `id` INTEGER PRIMARY KEY,
41
- `content_type` VARCHAR(255) DEFAULT NULL
43
+ `content_type` VARCHAR(255) DEFAULT NULL,
44
+ UNIQUE (`content_type`)
42
45
  );
43
46
 
44
47
  CREATE TABLE IF NOT EXISTS `accept_languages` (
45
48
  `id` INTEGER PRIMARY KEY,
46
- `accept_language` VARCHAR(255) DEFAULT NULL
49
+ `accept_language` VARCHAR(255) DEFAULT NULL,
50
+ UNIQUE (`accept_language`)
47
51
  );
48
52
 
49
53
  CREATE TABLE IF NOT EXISTS `messages` (
50
54
  `id` INTEGER PRIMARY KEY,
51
- `message` VARCHAR(10) DEFAULT NULL
55
+ `message` VARCHAR(10) DEFAULT NULL,
56
+ UNIQUE (`message`)
52
57
  );
53
58
 
54
59
  CREATE TABLE IF NOT EXISTS `sensors` (