매개변수를 기록하려고 하므로 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 페이지, 아래에리눅스 지원. 페이지 제목은 다음과 같습니다.IDSNet 연결 레코더관심 있는 파일 2개가 포함되어 있습니다. 위에서 언급한 스크립트 중 하나는감사 log.pl 구문 분석, 다른 하나는 샘플입니다감사 로그문서.
스크립트 실행
이 두 파일을 다운로드하면 이것이 귀하가 요청하는 내용임을 알 수 있습니다.
예
$ ./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=7ffce315f1e0 항목=2 ppid=28317 pid=30555 auid= 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=655}
답변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
}
}
}