{"id":284770,"date":"2017-04-11T11:10:23","date_gmt":"2017-04-11T07:10:23","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=284770"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=284770","title":{"rendered":"\u0410\u0443\u0434\u0438\u0442 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0431\u0435\u0437 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u0441\u043c\u0441"},"content":{"rendered":"<h2>\u0412\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435<\/h2>\n<p>  \u041a\u0430\u043a \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443, \u043a\u0442\u043e \u0445\u043e\u0442\u044c \u0440\u0430\u0437 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u0441\u044f \u043d\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u043f\u043e \u0418\u0411, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0445 \u0437\u0430 \u0434\u0435\u043d\u044c \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u043f\u043e \u0438\u0445 \u0440\u0430\u0437\u0431\u043e\u0440\u0443. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e, \u0435\u0441\u043b\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432 \u2014 \u043c\u043d\u043e\u0433\u043e, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u0442\u0430\u043c \u0437\u043e\u043e\u043f\u0430\u0440\u043a \u0438\u0437 \u041e\u0421 \u0438 \u0432\u0435\u0440\u0441\u0438\u0439.<br \/>  \u0412 \u044d\u0442\u043e\u043c \u0442\u043e\u043f\u0438\u043a\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443. \u0418 \u0434\u0430, Perl<b>*<\/b> \u0436\u0438\u0432:)<br \/>  <a name=\"habracut\"><\/a><\/p>\n<h2>\u0426\u0435\u043b\u0438 \u0438 \u0437\u0430\u0434\u0430\u0447\u0438<\/h2>\n<p>  \u041f\u0440\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043c\u044b \u0441 <a href=\"https:\/\/habrahabr.ru\/users\/mkhlystun\/\" class=\"user_link\">mkhlystun<\/a><b>**<\/b> \u0440\u0435\u0448\u0430\u043b\u0438 \u0434\u0432\u0430 \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438:  <\/p>\n<ul>\n<li>\u0421\u0431\u043e\u0440 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0432\u0435\u0440\u0441\u0438\u044f\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445<\/li>\n<li>\u0421\u0431\u043e\u0440 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044f\u0445 \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445<\/li>\n<\/ul>\n<p>  \u041e\u0431\u0435 \u044d\u0442\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0435\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u0438 \u043e\u0431\u0449\u0443\u044e \u0446\u0435\u043b\u044c: \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u044b \u043f\u0440\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f\u0445 \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u0442\u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0434\u0430\u0443\u043d\u0442\u0430\u0439\u043c, \u0447\u0435\u0433\u043e \u043c\u044b \u0438 \u0434\u043e\u0441\u0442\u0438\u0433\u043b\u0438.<\/p>\n<h2>\u0421\u0445\u0435\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u044b<\/h2>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/200\/c43\/403\/200c43403a2541a4a82c4857e1b7218b.png\"\/>  <\/p>\n<ol>\n<li>\u0420\u0430\u0437 \u0432 \u0447\u0430\u0441 \u043a\u0430\u0436\u0434\u044b\u0439 \u0445\u043e\u0441\u0442 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u043f\u0430\u043a\u0435\u0442\u0430\u0445 \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0451 \u043e\u0447\u0435\u0440\u0435\u0434\u044c<\/li>\n<li>\u0418\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0432\u044b\u0433\u0440\u0435\u0431\u0430\u044e\u0442\u0441\u044f \u0438 \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432 \u0431\u0430\u0437\u0443<\/li>\n<li>\u0420\u0430\u0437 \u0432 3 \u0447\u0430\u0441\u0430 \u0432 \u0431\u0430\u0437\u0443 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0440\u043e\u0431\u043e\u0442 \u0438 \u043f\u0440\u043e\u0433\u043e\u043d\u044f\u0435\u0442 \u043f\u0430\u043a\u0435\u0442\u044b \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0440\u0432\u0438\u0441 \u0430\u0443\u0434\u0438\u0442\u0430<\/li>\n<li>\u041f\u043e \u0438\u0442\u043e\u0433\u0430\u043c \u0437\u0430 \u0441\u0443\u0442\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u0447\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u0435\u043c \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u043d\u044b\u043c<\/li>\n<\/ol>\n<p>  <\/p>\n<h3>\u0421\u0445\u0435\u043c\u0430 \u0431\u0430\u0437\u044b<\/h3>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">pkgs.sql<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"sql\">CREATE TABLE hosts (     hostname character varying(255) NOT NULL PRIMARY KEY,     os character varying(255),     pkg_id integer[] );  CREATE INDEX hosts_pkg_id_idx ON hosts USING gin (pkg_id);  CREATE TABLE pkg (     id SERIAL NOT NULL PRIMARY KEY,     name character varying(255) NOT NULL );  CREATE UNIQUE INDEX pkg_name_idx ON pkg USING btree (name);  CREATE TABLE vulners (     id character varying(255) NOT NULL PRIMARY KEY,     cvss_score double precision DEFAULT 0.0 NOT NULL,     cvss_vector character varying(255),     description text,     cvelist text );  CREATE TABLE v2p (     pkg_id integer NOT NULL REFERENCES pkg(id),     vuln_id character varying(255) NOT NULL REFERENCES vulners(id) ); <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0412 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 <i>hosts<\/i> \u0437\u0430\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0445\u043e\u0441\u0442\u0430\u0445 ( \u043e\u0434\u0438\u043d \u0445\u043e\u0441\u0442 = \u043e\u0434\u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c ), \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u0432 <i>pkg<\/i> ( \u043e\u0434\u0438\u043d \u043f\u0430\u043a\u0435\u0442 \u2014 \u043e\u0434\u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c ), \u0432\u043e \u0438\u0437\u0431\u0435\u0436\u0430\u043d\u0438\u0435 \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438. \u041c\u0430\u0441\u0441\u0438\u0432 \u0431\u044b\u043b \u0432\u044b\u0431\u0440\u0430\u043d \u0438\u0441\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u0438, \u0436\u0438\u0442\u044c \u0441 \u043d\u0438\u043c \u0432\u043f\u043e\u043b\u043d\u0435 \u043c\u043e\u0436\u043d\u043e.<br \/>  \u041f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 <i>vulners<\/i> \u0437\u0430\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044f\u0445 \u0434\u043b\u044f \u043f\u0430\u043a\u0435\u0442\u043e\u0432, \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u0432\u044f\u0437\u0438 <i>v2p<\/i> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0443 many-to-many.<\/p>\n<h3>\u0421\u0431\u043e\u0440 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u0430\u043a\u0435\u0442\u0430\u0445<\/h3>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">grabber.pl<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"perl\">#!\/usr\/bin\/perl # (C) kreon 2016 use strict; use warnings; use JSON; # config our %grabs = (   'centos|oraclelinux|redhat|fedora' =&gt; q(rpm -aq),   'debian|ubuntu' =&gt; q(dpkg-query -W -f='${Package} ${Version} ${Architecture}\\n'),   'osx' =&gt; q(pkgutil --pkgs) );  our %unames = (   'linux' =&gt; q(lsb_release -a),   'darwin' =&gt; q(echo &quot;Distributor ID: OSX&quot;) ); # global vars our $hostname = `hostname -f`; our ($vercmd, $grabcmd, $operatingsystem, $version); # do uname my $uname = `uname`; chomp $uname;  foreach (keys %unames) {   $vercmd = $unames{$_} if $uname =~ \/$_\/i; }  die &quot;Version CMD not found&quot; unless $vercmd;  # do version check foreach (`$vercmd`) {     chomp;     \/^Distributor ID:\\s*(\\S[\\S\\s]+)$\/ and $operatingsystem  = $1;     \/^Release:\\s*(\\S[\\S\\s]+)$\/        and $version = $1; }  die &quot;Opetating System not found&quot; unless $operatingsystem;  foreach (keys %grabs) {   $grabcmd = $grabs{$_} if $operatingsystem =~ \/$_\/i; }  # grab pkgs die &quot;Opetating System not found&quot; unless $grabcmd; my @pkgs; foreach (`$grabcmd`) {     chomp;     push @pkgs, $_; } chomp $hostname;  my $result = {     hostname =&gt; $hostname,     os       =&gt; $version ? qq($operatingsystem $version) : $operatingsystem,     pkgs     =&gt; [ sort @pkgs ] }; # print JSON-&gt;new-&gt;encode($result);  # done 1; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0414\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 Perl: \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b <i>hostname -f<\/i>, <i>lsb_release -a<\/i> \u0438 <i>rpm -aq|dpkg-query -W<\/i>, \u0432\u0441\u0435 \u044d\u0442\u043e \u0443\u043f\u0430\u043a\u043e\u0432\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 JSON \u0438 \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u0434\u043b\u044f \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439.<\/p>\n<h3>\u0422\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f JSON \u0432 \u0431\u0430\u0437\u0443<\/h3>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">transform.pl<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"perl\">#!\/usr\/bin\/perl # (C) kreon 2016 use strict; use warnings; use JSON; use DBI; use constant DB =&gt; 'dbi:Pg:dbname=pkgs';  # 0. create connection my $dbh     = DBI-&gt;connect( DB, &quot;&quot;, &quot;&quot;, { RaiseError =&gt; 1, AutoCommit =&gt; 0 } );  # 1. read from stdin and parse my $data = JSON-&gt;new-&gt;decode( join( &quot;&quot;, &lt;STDIN&gt; ) );  # if data == array parse foeach if ( ref($data) eq &quot;ARRAY&quot; ) {     foreach (@$data) {         parse_host($_);     } } else {     parse_host($data); }  # Done 1;  ### SUBS ### sub parse_host {     $_ = shift;      # do parse packages     my ( $hostname, $os, @pkgs )         = ( $_-&gt;{hostname}, $_-&gt;{os}, @{ $_-&gt;{pkgs} } );     my @pkgids;     eval {         foreach (@pkgs) {             my $sth = $dbh-&gt;prepare(&quot;SELECT id FROM pkg WHERE name=?&quot;);             $sth-&gt;execute( ($_) );             if ( my ($id) = $sth-&gt;fetchrow_array ) {                 push @pkgids, int($id);             }             else {                 $dbh-&gt;do( &quot;INSERT INTO pkg (name) VALUES(?)&quot;, undef, $_ );                 push @pkgs, $_;             }         }     };     $dbh-&gt;rollback and die &quot;$@&quot; if $@;     $dbh-&gt;commit;      # do parse host     eval {         my $sth = $dbh-&gt;prepare(&quot;SELECT os FROM hosts WHERE hostname=?&quot;);         $sth-&gt;execute( ($hostname) );         if ( my ($os2) = $sth-&gt;fetchrow_array ) {             if ( lc($os2) ne lc($os) ) {                 $dbh-&gt;do( &quot;UPDATE hosts SET os=? WHERE hostname=?&quot;,                     undef, $os, $hostname );             }         }         else {             $dbh-&gt;do( &quot;INSERT INTO hosts (hostname, os) VALUES(?, ?)&quot;,                 undef, $hostname, $os );         }     };     $dbh-&gt;rollback and die &quot;$@&quot; if $@;     $dbh-&gt;commit;      # do set packages     eval {         $dbh-&gt;do( &quot;UPDATE hosts SET pkg_id=? WHERE hostname=?&quot;,             undef, [@pkgids], $hostname );     };     $dbh-&gt;rollback and die &quot;$@&quot; if $@;     $dbh-&gt;commit; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0414\u0430\u043d\u043d\u044b\u0439 \u0441\u043a\u0440\u0438\u043f\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 json, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0438\u0437 \u043e\u0447\u0435\u0440\u0435\u0434\u0438, \u0430 \u0437\u0430\u0442\u0435\u043c \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0432 \u0431\u0430\u0437\u0443 \u0432 \u0442\u0440\u0438 \u044d\u0442\u0430\u043f\u0430:<br \/>   \u2014 \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u043b\u0430\u0434\u0435\u0442 \u043f\u0430\u043a\u0435\u0442\u044b, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044f \u0438\u0445 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c<br \/>   \u2014 \u0417\u0430\u0442\u0435\u043c \u043a\u043b\u0430\u0434\u0435\u0442 \u0445\u043e\u0441\u0442\u044b, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044f \u0432\u0435\u0440\u0441\u0438\u044e \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438<br \/>   \u2014 \u0417\u0430\u0442\u0435\u043c \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442 \u0445\u043e\u0441\u0442\u044b \u0438 \u043f\u0430\u043a\u0435\u0442\u044b \u0447\u0435\u0440\u0435\u0437 \u043c\u0430\u0441\u0441\u0438\u0432<\/p>\n<h3>\u0410\u0443\u0434\u0438\u0442<\/h3>\n<p>  \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0438\u0441\u043a\u0430\u043b\u0438 \u0441\u043f\u043e\u0441\u043e\u0431 \u0430\u0443\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448\u0438 \u043f\u0430\u043a\u0435\u0442\u044b, \u043c\u044b \u0434\u043e\u043b\u0433\u043e \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u043b\u0438 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b, \u043f\u043e\u043a\u0430 \u043d\u0430 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043a\u043e\u043d\u0444\u0435 \u043d\u0430\u043c \u043d\u0430 \u0433\u043b\u0430\u0437\u0430 \u043d\u0435 \u043f\u043e\u043f\u0430\u043b\u0430\u0441\u044c \u0432\u0438\u0437\u0438\u0442\u043a\u0430 <a href=\"http:\/\/vulners.com\/\">vulners<\/a>. \u042d\u0442\u043e \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0440 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0435\u043b\u0430\u044e\u0442 <a href=\"https:\/\/habrahabr.ru\/users\/isox\/\" class=\"user_link\">isox<\/a> \u0438 <a href=\"https:\/\/habrahabr.ru\/users\/videns\/\" class=\"user_link\">videns<\/a>. \u042f \u0441\u0432\u044f\u0437\u0430\u043b\u0441\u044f \u0441 \u043d\u0438\u043c\u0438 \u0438 \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043b \u043f\u043e\u043c\u043e\u0447\u044c. \u0418\u0442\u043e\u0433\u043e\u043c \u0441\u0442\u0430\u043b\u043e <a href=\"https:\/\/vulners.com\/audit\">Audit API<\/a>.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Audit API<\/b><\/p>\n<div class=\"spoiler_text\">\u0414\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e\u0431 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044f\u0445 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0431\u043b\u043e\u0431 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0432 json \u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u043d\u0430 <i>\/api\/v3\/audit\/audit\/<\/i>.  <\/p>\n<pre><code>POST \/api\/v3\/audit\/audit\/ HTTP\/1.0 Host: vulners.com Content-Type: application\/json Content-Length: 377  { &quot;os&quot;:&quot;CentOS&quot;, &quot;version&quot;:&quot;7&quot;, &quot;package&quot;:[&quot;kernel-3.10.0-229.el7.x86_64&quot;]} <\/code><\/pre>\n<p>  \u0412 \u043e\u0442\u0432\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440 \u043e\u0442\u0434\u0430\u0441\u0442 json \u0441\u043e \u0441\u043f\u0438\u0441\u043e\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0435:  <\/p>\n<pre><code>{   &quot;result&quot;: &quot;OK&quot;,   &quot;data&quot;: {     &quot;packages&quot;: {       &quot;kernel-3.10.0-229.el7.x86_64&quot;: {         &quot;CESA-2015:2152&quot;: [           {             &quot;package&quot;: &quot;kernel-3.10.0-229.el7.x86_64&quot;,             &quot;providedVersion&quot;: &quot;0:3.10.0-229.el7&quot;,             &quot;bulletinVersion&quot;: &quot;3.10.0-327.el7&quot;,             &quot;providedPackage&quot;: &quot;kernel-3.10.0-229.el7.x86_64&quot;,             &quot;bulletinPackage&quot;: &quot;kernel-3.10.0-327.el7.x86_64.rpm&quot;,             &quot;operator&quot;: &quot;lt&quot;,             &quot;bulletinID&quot;: &quot;CESA-2015:2152&quot;           }         ],         &quot;CESA-2015:1978&quot;: [           {             &quot;package&quot;: &quot;kernel-3.10.0-229.el7.x86_64&quot;,             &quot;providedVersion&quot;: &quot;0:3.10.0-229.el7&quot;,             &quot;bulletinVersion&quot;: &quot;3.10.0-229.20.1.el7&quot;,             &quot;providedPackage&quot;: &quot;kernel-3.10.0-229.el7.x86_64&quot;,             &quot;bulletinPackage&quot;: &quot;kernel-3.10.0-229.20.1.el7.src.rpm&quot;,             &quot;operator&quot;: &quot;lt&quot;,             &quot;bulletinID&quot;: &quot;CESA-2015:1978&quot;           },           \/\/ skipped         ],         &quot;CESA-2016:0064&quot;: [           {             &quot;package&quot;: &quot;kernel-3.10.0-229.el7.x86_64&quot;,             &quot;providedVersion&quot;: &quot;0:3.10.0-229.el7&quot;,             &quot;bulletinVersion&quot;: &quot;3.10.0-327.4.5.el7&quot;,             &quot;providedPackage&quot;: &quot;kernel-3.10.0-229.el7.x86_64&quot;,             &quot;bulletinPackage&quot;: &quot;kernel-3.10.0-327.4.5.el7.src.rpm&quot;,             &quot;operator&quot;: &quot;lt&quot;,             &quot;bulletinID&quot;: &quot;CESA-2016:0064&quot;           },           \/\/ skipped         ],        \/\/ skipped     ],    \/\/ skipped     &quot;cvss&quot;: {       &quot;score&quot;: 10.0,       &quot;vector&quot;: &quot;AV:NETWORK\/AC:LOW\/Au:NONE\/C:COMPLETE\/I:COMPLETE\/A:COMPLETE\/&quot;     },     &quot;cvelist&quot;: [       &quot;CVE-2014-9644&quot;,       &quot;CVE-2016-2384&quot;,       \/\/ skipped     ],     &quot;id&quot;: &quot;F777&quot;   } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u041f\u043e\u0441\u043b\u0435 \u043e\u0431\u043a\u0430\u0442\u043a\u0438 API \u0431\u044b\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0443\u0448\u0438\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043f\u043e OS \u0438 \u0432 \u043e\u0442\u0432\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0438 \u043a\u043b\u0430\u0434\u0435\u0442 \u0438\u0445 \u0432 \u0431\u0430\u0437\u0443.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">audit.pl<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"perl\">#!\/usr\/bin\/perl # (C) kreon 2016 use strict; use warnings; use lib 'perl5'; use HTTP::Tiny; use DBI; use JSON; use constant VULNERS_AUDIT_API =&gt; 'http:\/\/vulners.com\/api\/v3\/audit\/audit\/'; use constant VULNERS_ID_API    =&gt; 'http:\/\/vulners.com\/api\/v3\/search\/id\/'; use constant DB                =&gt; 'dbi:Pg:dbname=pkgs';  our %VULNS; our $dbh; our %pkgs = (); # 0. connect to DB $dbh = DBI-&gt;connect( DB, &quot;&quot;, &quot;&quot;, { RaiseError =&gt; 1, AutoCommit =&gt; 0 } );  # get all OS variations my @os = get_os(); # for each OS get all packages and ask vulners for its vulnerabilities foreach my $os (@os) {     eval {         my ( $o, $ver ) = split( \/ \/, $os );         my $res = HTTP::Tiny-&gt;new-&gt;request(             'POST',             VULNERS_AUDIT_API,             {   headers =&gt; { 'Content-Type' =&gt; 'application\/json' },                 content =&gt; JSON-&gt;new-&gt;encode(                     {   os      =&gt; $o,                         version =&gt; $ver,                         package =&gt; [ get_packages($os) ]                     }                 )             }         );         if ( !$res-&gt;{success} ) {             die &quot;HTTP Error: $res-&gt;{content}&quot;;         }         my $data  = JSON-&gt;new-&gt;decode( $res-&gt;{content} );         my $vulns = $data-&gt;{data}-&gt;{packages};         return undef unless defined $vulns;         foreach ( keys %$vulns ) {             my $o = $vulns-&gt;{$_};             if ( defined( $pkgs{$_} ) ) {                 $VULNS{ $pkgs{$_} } = [ keys %$o ];             }         }     };     print $@ if $@; }  # Now get info on each vuln ID ( CESA, USN, etc ) ... my @result; my $res = HTTP::Tiny-&gt;new-&gt;request(     'POST',     VULNERS_ID_API,     {   headers =&gt; { 'Content-Type' =&gt; 'application\/json' },         content =&gt; JSON-&gt;new-&gt;encode( { id =&gt; [ map {@$_} values %VULNS ] } )     } );  if ( !$res-&gt;{success} ) {     die &quot;HTTP Error: $res-&gt;{content}&quot;; } my $data = JSON-&gt;new-&gt;decode( $res-&gt;{content} ); foreach ( values %{ $data-&gt;{data}-&gt;{documents} } ) {     push @result,         {         id          =&gt; $_-&gt;{id},         cvss_score  =&gt; $_-&gt;{cvss}-&gt;{score},         cvss_vector =&gt; $_-&gt;{cvss}-&gt;{vector},         description =&gt; $_-&gt;{description},         cvelist     =&gt; join( ', ', @{ $_-&gt;{cvelist} } ),         }; }  # Insert the data to DB eval {     $dbh-&gt;do( &quot;DELETE FROM v2p&quot;,     undef );     $dbh-&gt;do( &quot;DELETE FROM vulners&quot;, undef );     # insert prepared data to vulners table     foreach (@result) {         $dbh-&gt;do(             &quot;INSERT INTO vulners (id, cvss_score, cvss_vector, description, cvelist) VALUES (?,?,?,?,?)&quot;,             undef,             $_-&gt;{id},             $_-&gt;{cvss_score},             $_-&gt;{cvss_vector},             $_-&gt;{description},             $_-&gt;{cvelist}         );     }     # and link pkg and vuls into v2p     foreach my $pkg_id ( keys %VULNS ) {         foreach my $vuln_id ( @{ $VULNS{$pkg_id} } ) {             $dbh-&gt;do( &quot;INSERT INTO v2p(pkg_id,vuln_id) VALUES(?,?)&quot;,                 undef, $pkg_id, $vuln_id );         }     } }; $dbh-&gt;rollback and die &quot;Error $@&quot; if $@; $dbh-&gt;commit; # All done 1;  ### SUBS #### sub get_os {     my @os;     my $sth = $dbh-&gt;prepare(&quot;SELECT DISTINCT os FROM hosts&quot;);     $sth-&gt;execute();     while ( my ($os) = $sth-&gt;fetchrow_array ) {         push @os, $os;     }     return @os; }  sub get_packages {     my $os = shift;     my $sth         = $dbh-&gt;prepare(         &quot;select DISTINCT p.id,p.name FROM pkg p RIGHT JOIN hosts h ON (p.id=ANY(h.pkg_id)) WHERE h.os=?&quot;         );     $sth-&gt;execute( ($os) );     my @pkgs;     while ( my ( $id, $name ) = $sth-&gt;fetchrow_array ) {         $pkgs{$name} = $id;         push @pkgs, $name;     }     return @pkgs; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0410\u043b\u0433\u043e\u0440\u0438\u043c:<br \/>   \u2014 \u0411\u0435\u0440\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a OS \u0438\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u044b hosts<br \/>   \u2014 \u041f\u043e \u043a\u0430\u0436\u0434\u043e\u0439 OS \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0430\u043a\u0435\u0442\u043e\u0432<br \/>   \u2014 \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0430\u043a\u0435\u0442\u044b \u0432 Audit API, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a (id) \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0435\u0439<br \/>   \u2014 \u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 ID Api, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435<br \/>   \u2014 \u041f\u0438\u0448\u0435\u043c \u0432 \u0431\u0430\u0437\u0443 \u043c\u0435\u0442\u0430\u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 vulners<br \/>   \u2014 \u041f\u0438\u0448\u0435\u043c \u0432 \u0431\u0430\u0437\u0443 \u0441\u0432\u044f\u0437\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0438 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 v2p<\/p>\n<h3>\u041e\u0442\u0447\u0435\u0442\u044b<\/h3>\n<p>  \u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043d\u0430\u0448\u0435\u0439 \u0446\u0435\u043b\u044c\u044e \u0431\u044b\u043b\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0445\u043e\u0441\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043d\u043e\u0433\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f, \u043f\u0435\u0440\u0432\u044b\u0439 \u043e\u0442\u0447\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0441\u0434\u0435\u043b\u0430\u043b, \u0431\u044b\u043b &#8216;top10 hosts to update&#8217;, \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u043f\u043e \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e\u043c\u0443 CVSS Score<b>***<\/b>.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">report.pl<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"perl\">#!\/usr\/bin\/perl # (C) kreon 2016 use strict; use warnings; use lib 'perl5'; use HTTP::Tiny; use DBI; use JSON; use constant DB                =&gt; 'dbi:Pg:dbname=pkgs';  our $dbh; our @hosts; # 0. connect to DB $dbh = DBI-&gt;connect( DB, &quot;&quot;, &quot;&quot;, { RaiseError =&gt; 1, AutoCommit =&gt; 0 } ); # get top10 hosts my $sth = $dbh-&gt;prepare(&quot;SELECT h.hostname,SUM(v.cvss_score) as sum FROM hosts h INNER JOIN pkg p ON(p.id=ANY(h.pkg_id)) INNER JOIN v2p vp ON(vp.pkg_id=p.id) INNER JOIN vulners v ON (v.id=vp.vuln_id) GROUP BY h.hostname ORDER BY sum DESC LIMIT 10&quot;); $sth-&gt;execute(); while (my ($host, $sum) = $sth-&gt;fetchrow_array) {   push @hosts, { hostname =&gt; $host, score =&gt; $sum, pkgs =&gt; [] }; } foreach (@hosts) {   $sth = $dbh-&gt;prepare(&quot;SELECT p.name,SUM(v.cvss_score) AS score FROM pkg p RIGHT JOIN hosts h ON (p.id=ANY(h.pkg_id)) INNER JOIN v2p ON (v2p.pkg_id=p.id) INNER JOIN vulners v ON (v.id=v2p.vuln_id) WHERE h.hostname=? GROUP BY p.name ORDER BY score DESC LIMIT 10&quot;);   $sth-&gt;execute(($_-&gt;{hostname}));   while(my ($pkg,$sum) = $sth-&gt;fetchrow_array) {     push @{$_-&gt;{pkgs}}, { package =&gt; $pkg, score =&gt; $sum };   } }  print &lt;&lt;EOF          TOP 10 SERVERS TO UPDATE EOF ; foreach (@hosts) {   print &lt;&lt;EOF --------------------------------------------------   Hostname:   $_-&gt;{hostname}   Score   :   $_-&gt;{score}   Packages: EOF   ;   foreach (@{$_-&gt;{pkgs}}) {       print &lt;&lt;EOF       Name : $_-&gt;{package}       Score: $_-&gt;{score} EOF   } } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  \u0414\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0435\u0440\u0435\u0442 \u0442\u043e\u043f10 \u0445\u043e\u0441\u0442\u043e\u0432 \u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445 \u0431\u0435\u0440\u0435\u0442 \u0442\u043e\u043f 10 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0441 \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u044b\u043c \u0441\u043a\u043e\u0440\u043e\u043c. \u0414\u0430\u043b\u044c\u0448\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \ud83d\ude42<\/p>\n<h2>\u0418\u0442\u043e\u0433\u0438 \u0433\u043e\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f<\/h2>\n<p>  \u0423\u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0433\u043e\u0434\u0430 \u043c\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0440\u0435\u0431\u044f\u0442\u0430\u043c \u0438\u0437 Vulners. \u041d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u043d\u0438 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0430\u0443\u0434\u0438\u0440\u0443\u044e\u0442 \u0431\u043e\u043b\u0435\u0435 30 000 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432. \u0427\u0442\u043e \u043f\u0440\u0438\u044f\u0442\u043d\u043e, \u0432\u0441\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0435 \u0431\u0430\u0433\u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u044f\u043b\u0438\u0441\u044c, \u0430 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u0442\u044b\u0441\u044f\u0447\u0438 \u0432\u044b\u0440\u043e\u0441\u043b\u0430 \u0441 30 \u0441\u0435\u043a\u0443\u043d\u0434 \u0434\u043e 400 \u043c\u0438\u043b\u0438\u0441\u0435\u043a\u0443\u043d\u0434. \u0418\u043c\u0435\u043d\u043d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0438\u043c \u044d\u0442\u043e\u0442 \u0442\u043e\u043f\u0438\u043a \u043d\u0430\u0437\u0432\u0430\u043d &quot;\u2026 \u0431\u0435\u0437 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u0441\u043c\u0441&quot; \ud83d\ude42<\/p>\n<p>  \u0427\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u043c\u043e \u0431\u0438\u0437\u043d\u0435\u0441-\u0446\u0435\u043b\u0435\u0439, \u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u0435\u043c \u0434\u0430\u043d\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u0443 \u043d\u0430\u0441 \u043d\u0430\u0447\u0430\u043b \u043f\u043e\u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u044b\u0445 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0439. \u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u2014 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430 \u0434\u043b\u044f \u0434\u0435\u0436\u0443\u0440\u043d\u043e\u0433\u043e \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0430, \u0430 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0435 10 \u2014 \u0432\u043f\u043e\u043b\u043d\u0435 \u043f\u043e\u0441\u0438\u043b\u044c\u043d\u0430\u044f. \u0417\u0430 \u0433\u043e\u0434 \u043c\u044b \u0443\u0440\u043e\u043d\u0438\u043b\u0438 \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u044b\u0439 cvss score \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u0432\u0434\u0432\u043e\u0435, \u0447\u0435\u0433\u043e \u0438 \u0432\u0430\u043c \u0436\u0435\u043b\u0430\u0435\u043c<b>****<\/b> \ud83d\ude42<\/p>\n<h4>\u0421\u043d\u043e\u0441\u043a\u0438 \u0438 \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u044f<\/h4>\n<p>  <b>*<\/b> \u2014 \u0422\u0430\u043a \u0441\u043b\u043e\u0436\u0438\u043b\u043e\u0441\u044c \u0438\u0441\u0442\u043e\u0440\u0438\u0447\u0435\u0441\u043a\u0438, \u044f \u043d\u0430\u0447\u0430\u043b \u043f\u0438\u0441\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u044e \u043d\u0430 Perl \u0438 \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u0443\u0441\u043f\u0435\u043b \u043c\u0435\u043d\u044f \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c.<br \/>  <b>**<\/b> \u2014 \u041c\u0438\u0448\u0430 \u043d\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0445\u0430\u0431\u0440\u0430, \u043d\u043e \u043a\u0430\u043a \u0438\u043d\u0436\u0435\u043d\u0435\u0440 \u043e\u043d \u043d\u0435\u0437\u0430\u043c\u0435\u043d\u0438\u043c \ud83d\ude42<br \/>  <b>***<\/b> \u2014 \u0426\u0438\u0444\u0440\u043e\u0432\u0430\u044f \u043c\u0435\u0442\u0440\u0438\u043a\u0430 \u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0438, \u043e\u0442 1.0 ( \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0431\u0438\u0442\u044c ) \u0434\u043e 10.0 ( \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u0430\u044f \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u044c )<br \/>  <b>****<\/b> \u2014 \u0412\u0435\u0441\u044c \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0442\u0443\u0442: <a href=\"https:\/\/github.com\/kreon\/freeaudit\/\">github.com\/kreon\/freeaudit<\/a><\/p>\n<p>  P.S. \u0418 \u0442\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 \u2014 Perl \u0436\u0438\u0432!<br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habrahabr.ru\/post\/326084\/\"> https:\/\/habrahabr.ru\/post\/326084\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<h2>\u0412\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u0435<\/h2>\n<p>  \u041a\u0430\u043a \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443, \u043a\u0442\u043e \u0445\u043e\u0442\u044c \u0440\u0430\u0437 \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u0441\u044f \u043d\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u043f\u043e \u0418\u0411, \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0445 \u0437\u0430 \u0434\u0435\u043d\u044c \u0443\u044f\u0437\u0432\u0438\u043c\u043e\u0441\u0442\u0435\u0439 \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0435\u0432\u044b\u0448\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430 \u043f\u043e \u0438\u0445 \u0440\u0430\u0437\u0431\u043e\u0440\u0443. \u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e, \u0435\u0441\u043b\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u0432 \u2014 \u043c\u043d\u043e\u0433\u043e, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0435\u0441\u043b\u0438 \u0442\u0430\u043c \u0437\u043e\u043e\u043f\u0430\u0440\u043a \u0438\u0437 \u041e\u0421 \u0438 \u0432\u0435\u0440\u0441\u0438\u0439.<br \/>  \u0412 \u044d\u0442\u043e\u043c \u0442\u043e\u043f\u0438\u043a\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443. \u0418 \u0434\u0430, Perl<b>*<\/b> \u0436\u0438\u0432:)  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-284770","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/284770","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=284770"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/284770\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=284770"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=284770"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=284770"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}