$30 off During Our Annual Pro Sale. View Details »

Antonio Bonuccelli

Antonio Bonuccelli

Using ELK to visualise security data: IPTables and Kippo SSH honeypot

Elasticsearch Inc

November 20, 2014
Tweet

More Decks by Elasticsearch Inc

Other Decks in How-to & DIY

Transcript

  1. In this presentation • Identify raw data sources of interest

    • Extract relevant information • Visualize security analytics • Demo cloud VM
  2. Raw data sources - what • Who is attempting connection

    • What services are they probing • What credentials they use
  3. Raw data sources - what • Who is attempting connection

    • What services are they probing • What credentials they use • Where are they from
  4. Raw data sources - who IPTables - Definition “iptables is

    a user-space application program that allows a system administrator to configure the tables provided by the Linux kernel firewall and the chains and rules it stores.”
  5. Raw data sources - how IPTables Logging only denied connections

    # Whitelist everything we want to allow # e.g. Don't lock yourself out -A INPUT -p tcp --dport 12345 -j ACCEPT -A INPUT -p tcp --dport ..... -j ACCEPT
  6. Raw data sources - how IPTables Logging only denied connections

    # Whitelist everything we want to allow # e.g. Don't lock yourself out -A INPUT -p tcp --dport 12345 -j ACCEPT -A INPUT -p tcp --dport ..... -j ACCEPT # Log iptables denied calls -A INPUT -j LOG --log-prefix "iptables denied:"
  7. Raw data sources - how IPTables Logging only denied connections

    # Whitelist everything we want to allow # e.g. Don't lock yourself out -A INPUT -p tcp --dport 12345 -j ACCEPT -A INPUT -p tcp --dport ..... -j ACCEPT # Log iptables denied calls -A INPUT -j LOG --log-prefix "iptables denied:" # Drop all other INPUT and FORWARD # Explicitly allowed policy earlier -A INPUT -j DROP -A FORWARD -j DROP COMMIT
  8. Raw data sources - how IPTables Logging only denied connections

    tony$ telnet host123.virtual-machines.test 1000 Trying 123.123.123.123... ^C
  9. Raw data sources - how IPTables Logging only denied connections

    tony$ telnet host123.virtual-machines.test 1000 Trying 123.123.123.123... ^C
  10. Raw data sources - how IPTables Logging only denied connections

    tony$ telnet host123.virtual-machines.test 1000 Trying 123.123.123.123... ^C Nov 18 13:45:27 li717-137 kernel: iptables denied: IN=eth0 OUT= MAC=f2:3c:91:73:6c:71:84:78:ac:5a:1a:41:08:00 SRC=77.231.116.118 DST=123.123.123.123 LEN=64 TOS=0x00 PREC=0x00 TTL=48 ID=51711 DF PROTO=TCP SPT=50196 DPT=1000 WINDOW=65535 RES=0x00 SYN URGP=0
  11. Raw data sources - how IPTables Logging only denied connections

    tony$ telnet host123.virtual-machines.test 1000 Trying 123.123.123.123... ^C Nov 18 13:45:27 li717-137 kernel: iptables denied: IN=eth0 OUT= MAC=f2:3c:91:73:6c:71:84:78:ac:5a:1a:41:08:00 SRC=77.231.116.118 DST=123.123.123.123 LEN=64 TOS=0x00 PREC=0x00 TTL=48 ID=51711 DF PROTO=TCP SPT=50196 DPT=1000 WINDOW=65535 RES=0x00 SYN URGP=0
  12. Raw data sources - who Kippo SSH HoneyPot “KippoSSH is

    a medium interaction honeypot capable of recording plenty of information about the attacker, including interactive TTY sessions recordings”
  13. Raw data sources - who Kippo SSH HoneyPot – References

    - https://github.com/desaster/kippo
  14. Raw data sources - who Kippo SSH HoneyPot – References

    - https://github.com/desaster/kippo
  15. Raw data sources - how Kippo SSH HoneyPot tony$ egrep

    '^[^#]' /opt/kippo/kippo- master/kippo.cfg [honeypot] ssh_addr = 0.0.0.0 ssh_port = 2222 hostname = miami-32 log_path = log download_path = dl download_limit_size = 10485760 contents_path = honeyfs filesystem_file = fs.pickle
  16. Raw data sources - how Kippo SSH HoneyPot data_path =

    data txtcmds_path = txtcmds public_key = public.key private_key = private.key ssh_version_string = SSH-2.0-OpenSSH_5.1p1 Debian- 5 interact_enabled = false interact_port = 5123
  17. Raw data sources - how Kippo SSH HoneyPot badguy$ ssh

    [email protected] Password: (123456) 2014-11-16 10:44:53+0000 [SSHService ssh- userauth on HoneyPotTransport,4461,77.231.116.118] login attempt [root/123456] failed
  18. Raw data sources - how Kippo SSH HoneyPot badguy$ ssh

    [email protected] Password: (123456) 2014-11-16 10:44:53+0000 [SSHService ssh- userauth on HoneyPotTransport,4461,77.231.116.118] login attempt [root/123456] failed
  19. Raw data sources - how Kippo SSH HoneyPot • Only

    root can bind to port <1024 • We don't want to run Kippo as root • iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 22 -j REDIRECT --to-port 2222
  20. Logstash • INPUT input { file { type => "iptables"

    path => "/var/log/kern.log" } file { type => "honey-kippo" path => "/var/log/kippo/kippo.log" } }
  21. Logstash • INPUT input { file { type => "iptables"

    path => "/var/log/kern.log" } file { type => "honey-kippo" path => "/var/log/kippo/kippo.log" } }
  22. Logstash • FILTER Filter { if [type] == "iptables" {

    grok { match => [ "message","%{IPTABLES_DENIED}"] } } continues..
  23. Logstash • FILTER Filter { if [type] == "iptables" {

    grok { match => [ "message","%{IPTABLES_DENIED}"] } date { match => [ "timestamp", "MMM dd HH:mm:ss"] timezone => "Europe/London" } } continues..
  24. Logstash • FILTER Filter { if [type] == "iptables" {

    grok { match => [ "message","%{IPTABLES_DENIED}"] } date { match => [ "timestamp", "MMM dd HH:mm:ss"] timezone => "Europe/London" } } continues..
  25. Logstash GROK • Parse arbitrary data and structure it •

    Build regex patterns and reuse them • Ships with 120 patterns and counting
  26. Logstash GROK • Parse arbitrary data and structure it •

    Build regex patterns and reuse them • Ships with 120 patterns and counting • Allows to define custom patterns
  27. Logstash GROK IPTABLES_DENIED % {SYSLOGTIMESTAMP:timestamp} % {HOSTNAME:_host} kernel: iptables denied:

    IN=(? <in>eth0) OUT= MAC=(?<mac_addr>\S+) SRC=% {IP:src_ip} DST=%{IP:dst_ip} LEN=\d+ TOS=0x\d+ PREC=0x\d+ TTL=\d+ ID=\d+(?:\sDF)? PROTO=(? <proto>\S+) SPT=(?<src_port>\d+) DPT=(? <dst_port>\d+)(?:\sWINDOW=\d+)?(?:\sRES=0x\d+)? (?:\s[ACKSYNFIRT]{3})+(?:\sURGP=\d)?
  28. Logstash GROK IPTABLES_DENIED % {SYSLOGTIMESTAMP:timestamp} % {HOSTNAME:_host} kernel: iptables denied:

    IN=(? <in>eth0) OUT= MAC=(?<mac_addr>\S+) SRC=% {IP:src_ip} DST=%{IP:dst_ip} LEN=\d+ TOS=0x\d+ PREC=0x\d+ TTL=\d+ ID=\d+(?:\sDF)? PROTO=(? <proto>\S+) SPT=(?<src_port>\d+) DPT=(? <dst_port>\d+)(?:\sWINDOW=\d+)?(?:\sRES=0x\d+)? (?:\s[ACKSYNFIRT]{3})+(?:\sURGP=\d)?
  29. Logstash GROK IPTABLES_DENIED % {SYSLOGTIMESTAMP:timestamp} % {HOSTNAME:_host} kernel: iptables denied:

    IN=(? <in>eth0) OUT= MAC=(?<mac_addr>\S+) SRC=% {IP:src_ip} DST=%{IP:dst_ip} LEN=\d+ TOS=0x\d+ PREC=0x\d+ TTL=\d+ ID=\d+(?:\sDF)? PROTO=(? <proto>\S+) SPT=(?<src_port>\d+) DPT=(? <dst_port>\d+)(?:\sWINDOW=\d+)?(?:\sRES=0x\d+)? (?:\s[ACKSYNFIRT]{3})+(?:\sURGP=\d)?
  30. Logstash GROK Before Nov 16 12:12:44 li717-137 kernel: iptables denied:

    IN=eth0 OUT= MAC=f2:3c:91:73:6c:71:84:78:ac:5a:1a:41:08:00 SRC=77.231.116.118 DST=123.123.123.123 LEN=60 TOS=0x00 PREC=0x00 TTL=48 ID=57130 DF PROTO=TCP SPT=49222 DPT=39000 WINDOW=29200 RES=0x00 SYN URGP=0
  31. Logstash GROK After ... "timestamp" => "Nov 16 12:12:44", "_host"

    => "host123", "in" => "eth0", "src_ip" => "77.231.116.118", "dst_ip" => "123.123.123.123", "proto" => "TCP", "src_port" => "49222", "dst_port" => "39000", ...
  32. Logstash • FILTER Filter { if [type] == "iptables" {

    grok { match => [ "message","%{IPTABLES_DENIED}"] } date { match => [ "timestamp", "MMM dd HH:mm:ss"] timezone => "Europe/London" } } continues..
  33. Logstash • FILTER Continues.. else if [type] == "honey-kippo" {

    //Do likewise for kippo //match timestamp //grok it } }//FILTER ENDS
  34. Logstash • FILTER Continues.. else if [type] == "honey-kippo" {

    //Do likewise for kippo //match timestamp //grok it } geoip { source => "src_ip" } }//FILTER ENDS
  35. Logstash GEOIP "geoip" => { "ip" => "222.186.21.48", "country_code2" =>

    "CN", "country_code3" => "CHN", "country_name" => "China", "continent_code" => "AS", "region_name" => "04", “city_name" => "Nanjing", "latitude" => 32.0617, "longitude" => 118.77780000000001, "timezone" => "Asia/Shanghai", "real_region_name" => "Jiangsu", "location" => [ [0] 118.77780000000001, [1] 32.0617 ] }
  36. Logstash GEOIP "geoip" => { "ip" => "222.186.21.48", "country_code2" =>

    "CN", "country_code3" => "CHN", "country_name" => "China", "continent_code" => "AS", "region_name" => "04", “city_name" => "Nanjing", "latitude" => 32.0617, "longitude" => 118.77780000000001, "timezone" => "Asia/Shanghai", "real_region_name" => "Jiangsu", "location" => [ [0] 118.77780000000001, [1] 32.0617 ] }
  37. Logstash • OUTPUT Output { if "_grokparsefailure" not in [tags]

    { if [type] == "iptables" { elasticsearch { protocol => "http" host => "127.0.0.1" index => "logstash-os-%{+YYYY.MM.dd}" index_type => "firewall" } } } ...
  38. Logstash • OUTPUT output { if "_grokparsefailure" not in [tags]

    { if [type] == "iptables" { elasticsearch { protocol => "http" host => "127.0.0.1" index => "logstash-os-%{+YYYY.MM.dd}" index_type => "firewall" } } } ...
  39. Logstash • OUTPUT ... if [type] == "honey-kippo" { elasticsearch

    { protocol => "http" host => "127.0.0.1" index => "logstash-honey-%{+YYYY.MM.dd}" index_type => "honey" } } ...
  40. Logstash • OUTPUT Output { if "_grokparsefailure" not in [tags]

    { if ... if ... } stdout { codec => rubydebug } }//OUTPUT ENDS
  41. Elasticsearch • Distributed JSON document store • Full-text search engine

    • Scalable • Multi-tenant • Resilient • Lucene for the masses • Schema free • Ridiculously fast • Hides complexity from user
  42. Elasticsearch • Distributed JSON document store • Full-text search engine

    • Scalable • Multi-tenant • Resilient • Lucene for the masses • Schema free • Ridicously fast • Hides complexity from user
  43. Elasticsearch • More on ES is outside the scope of

    this presentations • For our purposes we will have a 2 nodes cluster up and running with
  44. Elasticsearch $ wget https://download.elasticsearch.org/elasticsearch /elasticsearch/elasticsearch-1.4.0.tar.gz $ mkdir node1 $ mkdir

    node2 $ ./node1/elasticsearch-1.4.0/bin/elasticsearch --node.name=node1 --cluster.name=mycluster -d $ ./node2/elasticsearch-1.4.0/bin/elasticsearch --node.name=node2 --cluster.name=mycluster -d
  45. Elasticsearch $ wget https://download.elasticsearch.org/elasticsearch /elasticsearch/elasticsearch-1.4.0.tar.gz $ mkdir node1 $ mkdir

    node2 $ ./node1/elasticsearch-1.4.0/bin/elasticsearch --node.name=node1 --cluster.name=mycluster -d $ ./node2/elasticsearch-1.4.0/bin/elasticsearch --node.name=node2 --cluster.name=mycluster -d
  46. Elasticsearch $ curl -XGET localhost:9200/_cluster/health?pretty { "cluster_name" : "mycluster", "status"

    : "green", "timed_out" : false, "number_of_nodes" : 2, "number_of_data_nodes" : 2, "active_primary_shards" : 0, "active_shards" : 0, "relocating_shards" : 0, "initializing_shards" : 0, "unassigned_shards" : 0 }
  47. Elasticsearch • This is ok for test/dev (and this demo)

    • Much more that can be configured • You will need to have a good reason to change defaults settings
  48. Kibana Beta 4 – What's new • Java backend process

    • Support for aggregations • Accepts raw JSON
  49. Kibana Beta 4 – What's new • Java backend process

    • Support for aggregations • Accepts raw JSON • New amazing visualizations
  50. Kibana Beta 4 – What's new • Java backend process

    • Support for aggregations • Accepts raw JSON • New amazing visualizations • More
  51. Kibana Configuration • No need! Defaults are fine (in this

    case) • Just untar and launch (./kibana) • Stores its information into ES index .kibana
  52. Kibana Configuration • No need! Defaults are fine (in this

    case) • Stores its information into ES index .kibana