Suspicious Reverse Shell Command Line

Detects suspicious shell commands or program code that may be exected or used in command line to establish a reverse shell

Rule Content

- title: Suspicious Reverse Shell Command Line
  id: 738d9bcf-6999-4fdb-b4ac-3033037db8ab
  status: experimental
  description: Detects suspicious shell commands or program code that may be exected
    or used in command line to establish a reverse shell
  references:
  - https://alamot.github.io/reverse_shells/
  author: Florian Roth
  date: 2019/04/02
  logsource:
    product: linux
    service: null
    category: null
  detection:
    keywords:
    - BEGIN {s = "/inet/tcp/0/
    - bash -i >& /dev/tcp/
    - bash -i >& /dev/udp/
    - sh -i >$ /dev/udp/
    - sh -i >$ /dev/tcp/
    - '&& while read line 0<&5; do'
    - /bin/bash -c exec 5<>/dev/tcp/
    - /bin/bash -c exec 5<>/dev/udp/
    - 'nc -e /bin/sh '
    - /bin/sh | nc
    - 'rm -f backpipe; mknod /tmp/backpipe p && nc '
    - ;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i))))
    - ;STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;
    - /bin/sh -i <&3 >&3 2>&3
    - uname -a; w; id; /bin/bash -i
    - $sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2); $stream.Write($sendbyte,0,$sendbyte.Length);
      $stream.Flush()};
    - ;os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);os.putenv('HISTFILE','/dev/null');
    - .to_i;exec sprintf("/bin/sh -i <&%d >&%d 2>&%d",f,f,f)
    - ;while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print
    - 'socat exec:''bash -li'',pty,stderr,setsid,sigint,sane tcp:'
    - rm -f /tmp/p; mknod /tmp/p p &&
    - ' | /bin/bash | telnet '
    - ',echo=0,raw tcp-listen:'
    - 'nc -lvvp '
    - xterm -display 1
    condition: keywords
  falsepositives:
  - Unknown
  level: high

Querying Elasticsearch

Import Libraries


In [ ]:
from elasticsearch import Elasticsearch
from elasticsearch_dsl import Search
import pandas as pd

Initialize Elasticsearch client


In [ ]:
es = Elasticsearch(['http://helk-elasticsearch:9200'])
searchContext = Search(using=es, index='logs-*', doc_type='doc')

Run Elasticsearch Query


In [ ]:
s = searchContext.query('query_string', query='\*.keyword:(*BEGIN\ \{s\ \=\ \"\/inet\/tcp\/0\/* OR *bash\ \-i\ &\ \/dev\/tcp\/* OR *bash\ \-i\ &\ \/dev\/udp\/* OR *sh\ \-i\ $\ \/dev\/udp\/* OR *sh\ \-i\ $\ \/dev\/tcp\/* OR *\&&\ while\ read\ line\ 0&5;\ do* OR *\/bin\/bash\ \-c\ exec\ 5\/dev\/tcp\/* OR *\/bin\/bash\ \-c\ exec\ 5\/dev\/udp\/* OR *nc\ \-e\ \/bin\/sh\ * OR *\/bin\/sh\ |\ nc* OR *rm\ \-f\ backpipe;\ mknod\ \/tmp\/backpipe\ p\ \&&\ nc\ * OR *;socket\(S,PF_INET,SOCK_STREAM,getprotobyname\(\"tcp\"\)\);if\(connect\(S,sockaddr_in\($p,inet_aton\($i\)\)\)\)* OR *;STDIN\-fdopen\($c,r\);$\~\-fdopen\($c,w\);system$_\ while;* OR *\/bin\/sh\ \-i\ &3\ &3\ 2&3* OR *uname\ \-a;\ w;\ id;\ \/bin\/bash\ \-i* OR *$sendbyte\ \=\ \(\[text.encoding\]\:\:ASCII\).GetBytes\($sendback2\);\ $stream.Write\($sendbyte,0,$sendbyte.Length\);\ $stream.Flush\(\)\};* OR *;os.dup2\(s.fileno\(\),0\);os.dup2\(s.fileno\(\),1\);os.dup2\(s.fileno\(\),2\);os.putenv\('HISTFILE','\/dev\/null'\);* OR *.to_i;exec\ sprintf\(\"\/bin\/sh\ \-i\ &%d\ &%d\ 2&%d\",f,f,f\)* OR *;while\(cmd\=c.gets\);IO.popen\(cmd,\"r\"\)\{|io|c.print* OR *socat\ exec\:'bash\ \-li',pty,stderr,setsid,sigint,sane\ tcp\:* OR *rm\ \-f\ \/tmp\/p;\ mknod\ \/tmp\/p\ p\ \&&* OR *\ |\ \/bin\/bash\ |\ telnet\ * OR *,echo\=0,raw\ tcp\-listen\:* OR *nc\ \-lvvp\ * OR *xterm\ \-display\ 1*)')
response = s.execute()
if response.success():
    df = pd.DataFrame((d.to_dict() for d in s.scan()))

Show Results


In [ ]:
df.head()