
パラメータを記録したいので、connect
ルールを追加しましたauditctl
。
audit.log に次の行が表示されます。
タイプ=SOCKADDR msg=audit(1385638181.866:89758729):saddr=16進文字列
それでは、16進文字列の宛先アドレスをどのように解釈する必要がありますか(16進文字列に何が格納されているのかわかりません)。
答え1
私はこのPerlスクリプトを見つけました。監査log.plの解析、次のように文字列を解析できる関数を示します。
sub parse_saddr
{
my $sockfd = $_[0];
my $saddr = $_[1];
# 0 - sys_bind(), 1 - sys_connect(), 2 - sys_accept()
my $action = $_[2];
($f1, $f2, $p1, $p2, @addr) = unpack("A2A2A2A2A2A2A2A2", $saddr);
$family = hex2dec($f1) + 256 * hex2dec($f2);
$port = 256 * hex2dec($p1) + hex2dec($p2);
$ip1 = hex2dec($addr[0]);
$ip2 = hex2dec($addr[1]);
$ip3 = hex2dec($addr[2]);
$ip4 = hex2dec($addr[3]);
#print "$saddr\n";
if ($family eq 2) { #&& $ip1 ne 0) {
my $dst_addr = "$ip1.$ip2.$ip3.$ip4:$port";
# print "family=$family $dst_addr\n\n";
# todo: avoid code duplication
if ($action eq 0) {
$sockfd_hash{ $sockfd } = $dst_addr;
} elsif ($action eq 1) {
my $src_addr;
if (exists $sockfd_hash{ $sockfd }) {
$src_addr = $sockfd_hash{ $sockfd };
} else {
$src_addr = "x.x.x.x:x";
}
print "$src_addr -> $dst_addr\n";
} elsif ($action eq 2) {
my $src_addr;
if (exists $sockfd_hash{ $sockfd }) {
$src_addr = $sockfd_hash{ $sockfd };
} else {
$src_addr = "x.x.x.x:x";
}
print "$dst_addr <- $src_addr\n";
} else {
print "unknown action\n";
}
} elsif ($family eq 1) {
$tmp1 = 0;
($tmp1, $tmp2) = unpack("A4A*", $saddr);
my $file = pack("H*", $tmp2);
# print "family=$family file=$file\n";
} else {
# print "$saddr\n";
}
}
このスクリプトはこれの一部です。CERNウェブサイトのTWikiページ、下にLinuxのサポート。ページのタイトルは次のとおりです。IDSNet接続レコーダー興味のある2つのファイルが含まれています。上記のスクリプトの1つは監査log.plの解析、もう一つはサンプルです監査ログ文書。
スクリプトの実行
これら2つのファイルをダウンロードすると、これがあなたが要求しているものであることがわかります。
はい
$ ./parse-audit-log.pl -l audit.log
x.x.x.x:x -> 0.0.0.0:22
x.x.x.x:x -> 137.138.32.52:22
137.138.32.52:22 <- x.x.x.x:x
x.x.x.x:x -> 0.0.0.0:22
x.x.x.x:x -> 137.138.32.52:0
x.x.x.x:x -> 137.138.16.5:53
x.x.x.x:x -> 137.138.16.5:53
x.x.x.x:x -> 137.138.16.5:53
x.x.x.x:x -> 137.138.128.158:88
x.x.x.x:x -> 137.138.16.5:53
x.x.x.x:x -> 137.138.16.5:53
x.x.x.x:x -> 137.138.16.5:53
x.x.x.x:x -> 137.138.128.148:750
x.x.x.x:x -> 137.138.16.5:53
x.x.x.x:x -> 137.138.16.5:53
x.x.x.x:x -> 137.138.16.5:53
x.x.x.x:x -> 137.138.128.158:88
x.x.x.x:x -> 137.138.32.52:0
x.x.x.x:x -> 137.138.16.5:53
x.x.x.x:x -> 137.138.16.5:53
x.x.x.x:x -> 137.138.16.5:53
x.x.x.x:x -> 137.138.128.158:88
x.x.x.x:x -> 127.0.0.1:6010
パーサーロジック抽出
上記の内容をパーサーで圧縮できますsaddr
。これは私のアンインストールバージョンです。
$ cat parse_saddr.pl
#!/usr/bin/perl -w
# Getopt::Std module from the perl package
use Getopt::Std;
my %Options;
getopt('s', \%Options);
if (defined($Options{'s'})) {
$saddr = $Options{'s'};
} else {
print "saddr not given\n";
exit(-1);
}
sub hex2dec($) { return hex $_[0] }
sub parse_saddr
{
my $saddr = $_[0];
($f1, $f2, $p1, $p2, @addr) = unpack("A2A2A2A2A2A2A2A2", $saddr);
$family = hex2dec($f1) + 256 * hex2dec($f2);
$port = 256 * hex2dec($p1) + hex2dec($p2);
$ip1 = hex2dec($addr[0]);
$ip2 = hex2dec($addr[1]);
$ip3 = hex2dec($addr[2]);
$ip4 = hex2dec($addr[3]);
#print "$saddr\n";
if ($family eq 2) { #&& $ip1 ne 0) {
my $dst_addr = "$ip1.$ip2.$ip3.$ip4:$port";
print "family=$family $dst_addr\n\n";
} elsif ($family eq 1) {
$tmp1 = 0;
($tmp1, $tmp2) = unpack("A4A*", $saddr);
my $file = pack("H*", $tmp2);
print "family=$family file=$file\n";
} else {
print "$saddr\n";
}
}
&parse_saddr($saddr);
Saddrパーサースクリプトのサンプル実行
次のように実行できます。
$ ./parse_saddr.pl -s 02000035898A1005000000000000000030BED20858D83A0010000000
family=2 137.138.16.5:53
saddr=..
その後、次のコマンドを使用して上記のファイルのすべての行を解析できます。audit.log
$ for i in $(grep saddr audit.log | cut -d"=" -f4);do echo $i; \
./parse_saddr.pl -s $i;done | less
上記のコードはfamily = 1型を処理しないようにまとめられているため、詳しく見てみる必要がありますsaddr
。
出力例
$ for i in $(grep saddr audit.log | cut -d"=" -f4);do echo $i; \
./parse_saddr.pl -s $i;done | less
...
01002F6465762F6C6F67000000000000
family=1 file=/dev/log^@^@^@^@^@^@
...
02000035898A10050000000000000000726E2E6368009A0900000000
family=2 137.138.16.5:53
...
02000058898A809E0000000000000000
family=2 137.138.128.158:88
...
020002EE898A80940000000000000000
family=2 137.138.128.148:750
...
0200177A7F0000010000000000000000
family=2 127.0.0.1:6010
...
Perlのパッキング/パッキング解凍機能
これらの機能は、その仕組みを理解すると非常に強力です。以前に使ったことがない場合は、チュートリアルを見てみましょう。パーパクトゥット。
これらの機能の基本的な概念は、テンプレートをデータ構成構造として使用してデータを受け取り、テンプレートを使用してそのデータを返すことです。
ここにもう一度簡単なPerlスクリプトがありますsaddr
。
$ cat unpack.pl
#!/usr/bin/perl
$saddr = "02000035898A1005000000000000000030BED20858D83A0010000000";
($f1, $f2, $p1, $p2, @addr) = unpack("A2A2A2A2A2A2A2A2", $saddr);
printf "org string: $saddr\n";
printf "org values==> f1: %s f2: %s p1: %s p2: %s addr: %s\n",
$f1,$f2,$p1,$p2,join("",@addr);
printf "new values==> f1: %2s f2: %2s p1: %2s p2: %2s addr: %s.%s.%s.%s\n\n",
hex($f1),hex($f2),hex($p1),hex($p2),hex($addr[0]),hex($addr[1]),hex($addr[2]),hex($addr[3]);
次を生成します。
$ ./unpack.pl
org string: 02000035898A1005000000000000000030BED20858D83A0010000000
org values==> f1: 02 f2: 00 p1: 00 p2: 35 addr: 898A1005
new values==> f1: 2 f2: 0 p1: 0 p2: 53 addr: 137.138.16.5
そこに含まれているデータを取得し、Tell関数を$saddr
呼び出してunpack()
一度に2バイトのデータを取得します(A2)。これを10回繰り返します。最初の4つのブロックA2
は実際にはそれぞれ2つの文字で、変数、、、、$f1
に格納されます。残りの文字は配列に保存されます。$f2
$p1
$p2
@addr
答え2
この-i
オプションを使用してくださいausearch
-i、--説明
デジタルエンティティをテキストとして解釈します。たとえば、uidはアカウント名に変換されます。変換は、検索を実行しているコンピュータの現在のリソースを使用して実行されます。アカウントの名前を変更したり、コンピュータに同じアカウントがない場合は、誤った結果が表示されることがあります。
これはまたエントリsaddr
のsをデコードしますtype=SOCKADDR
。
答え3
2.6以降、auditd
豊富なロギングを有効にする新しいロギングオプションがあります。
/etc/audit/auditd.confのlog_formatを次のように変更しますENRICHED
。
log_format = ENRICHED
これにより、ユーザー、グループ、システムコールなど、さまざまなフィールドに意味のある名前のフィールドが出力されます。資本化された地域は豊富な地域です。SOCKADDR
イベントには、デコードされたソケットIP、ポート、またはファイル名があります。
例:
type=SYSCALL msg=audit(1583352267.747:333333): arch=c000003e syscall=59 成功=例終了=0 a0=19eed30 a1=19e7360 a2=19e6ff0 a3=7ffce33 id= 0 あなたの電話番号 = 0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1681 comm="tail" exe="/usr/bin/tail" subj=unconfined_u:unconfined_r : unconfined_t :s0-s0:c0.c1023 key="EXECVE" ARCH=x86_64 SYSCALL=execve AUID="root" UID="root" GID="root" EUID="root" SUID="root" FSUID="root "EGID="ルート" SGID="ルート" FSGID="ルート"
タイプ=SOCKADDR msg=audit(1583352273.046:333334): saddr=0200028F000000000000000000000000SADDR={fam=inet laddr=0.0.0.0 lport=6
答え4
私はこれを使用してpowershellでこれを達成します。
function parseSocketAddr {
[CmdletBinding()]
param(
[parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)]
[string]$Saddr
)
begin {
$re = [regex]"^(?<socket>(?:02|0A)00)(?<port>[a-fA-F0-9]{4})(?<ip>[a-fA-F0-9]{8})(?<remainder>[a-fA-F0-9]+)$"
}
process {
$socket, $port, $ip, $remainder = $re.Match($saddr).groups.Where({$_.Name -ne '0'}).value
$ipRev = ($ip -split "(\w{2})").Where({$_ -ne ""})[4..0] -join ""
return [PSCustomObject]@{
type = $socket
IPAddress = ([IPAddress][convert]::ToInt64($ip,16)).IPAddressToString
Port = [convert]::ToInt32($port,16)
Remainder = $remainder
}
}
}