Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
S
Server Incident Scaner
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
易初
Server Incident Scaner
Commits
e01648b2
Commit
e01648b2
authored
Sep 17, 2026
by
易初
🖐🏻
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add new file
parents
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
866 additions
and
0 deletions
+866
-0
server_incident_scan_v3.sh
server_incident_scan_v3.sh
+866
-0
No files found.
server_incident_scan_v3.sh
0 → 100644
View file @
e01648b2
#!/bin/bash
# server_incident_scan_v3.sh
# Read-only, cross-host incident triage for the 2026-09-11 intrusion.
# Compatible with the older Bash/procps/findutils commonly found on CentOS 6/7.
#
# No processes are stopped, no packages are changed, no accounts/keys are
# modified, and no firewall/service/repository configuration is changed.
# The script only writes its evidence directory. Reading files may update atime
# on filesystems mounted with strict atime semantics.
set
-u
umask
077
export
LC_ALL
=
C
VERSION
=
"3.0.0"
SCAN_START
=
"
${
SCAN_START
:-
2026
-09-11 00
:00:00
}
"
SCAN_END
=
"
${
SCAN_END
:-
2026
-09-12 06
:00:00
}
"
BASE_OUT
=
"/var/tmp"
MODE
=
"standard"
usage
()
{
cat
<<
'
EOF
'
Usage:
server_incident_scan_v3.sh [--output DIR] [--start DATETIME] [--end DATETIME] [--deep]
Options:
--output DIR Evidence parent directory (default: /var/tmp)
--start DATETIME Incident window start (default: 2026-09-11 00:00:00)
--end DATETIME Incident window end (default: 2026-09-12 06:00:00)
--deep Add broader recent-file inspection under system paths
-h, --help Show this help
Backward compatibility:
A single positional directory is accepted as the output parent.
Examples:
bash server_incident_scan_v3.sh --output /root
bash server_incident_scan_v3.sh --output /root --deep
EOF
}
while
test
"$#"
-gt
0
;
do
case
"
$1
"
in
--output
)
test
"$#"
-ge
2
||
{
usage
>
&2
;
exit
1
;
}
BASE_OUT
=
"
$2
"
;
shift
2
;;
--start
)
test
"$#"
-ge
2
||
{
usage
>
&2
;
exit
1
;
}
SCAN_START
=
"
$2
"
;
shift
2
;;
--end
)
test
"$#"
-ge
2
||
{
usage
>
&2
;
exit
1
;
}
SCAN_END
=
"
$2
"
;
shift
2
;;
--deep
)
MODE
=
"deep"
;
shift
;;
-h
|
--help
)
usage
;
exit
0
;;
--
*
)
echo
"Unknown option:
$1
"
>
&2
;
usage
>
&2
;
exit
1
;;
*
)
BASE_OUT
=
"
$1
"
;
shift
;;
esac
done
have
()
{
command
-v
"
$1
"
>
/dev/null 2>&1
}
HOST_NAME
=
"
$(
hostname
2>/dev/null
||
echo
unknown-host
)
"
SAFE_HOST
=
"
$(
printf
'%s'
"
$HOST_NAME
"
|
tr
-c
'A-Za-z0-9._-'
'_'
)
"
STAMP
=
"
$(
date
+%Y%m%d-%H%M%S
)
"
OUT_DIR
=
"
${
BASE_OUT
%/
}
/incident-scan-v3-
${
SAFE_HOST
}
-
${
STAMP
}
"
ARTIFACTS
=
"
$OUT_DIR
/artifacts"
RAW
=
"
$OUT_DIR
/evidence.txt"
FINDINGS
=
"
$OUT_DIR
/findings.tsv"
SUMMARY
=
"
$OUT_DIR
/summary.txt"
EVENTS
=
"
$OUT_DIR
/chain_events.tsv"
PROCESSES
=
"
$OUT_DIR
/processes.tsv"
CONNECTIONS
=
"
$OUT_DIR
/public_remote_connections.tsv"
SSH_SUCCESS
=
"
$OUT_DIR
/ssh_success.log"
FILES
=
"
$OUT_DIR
/recent_files.tsv"
SCRIPTS
=
"
$OUT_DIR
/cloud_assist_scripts.tsv"
ENDPOINTS
=
"
$OUT_DIR
/candidate_endpoints.txt"
mkdir
-p
"
$ARTIFACTS
/processes"
"
$ARTIFACTS
/cloud-assist-scripts"
\
"
$ARTIFACTS
/authorized-keys"
"
$ARTIFACTS
/package-metadata"
\
"
$ARTIFACTS
/campaign-files"
"
$ARTIFACTS
/binary-indicators"
||
exit
1
:
>
"
$RAW
"
:
>
"
$SSH_SUCCESS
"
printf
'host\tseverity\tstage\tcategory\tevidence\n'
>
"
$FINDINGS
"
printf
'host\ttime\tstage\tsource\tindicator\tevidence\n'
>
"
$EVENTS
"
printf
'host\tpid\tppid\tuser\tstart\tcomm\texe\tsha256\tcmdline\n'
>
"
$PROCESSES
"
printf
'host\tprotocol\tlocal_address\tremote_address\tstate\tpid_program\n'
>
"
$CONNECTIONS
"
printf
'host\ttime_type\ttime\tmode\tuid_gid\tsize\tsha256\tpath\n'
>
"
$FILES
"
printf
'host\tmtime\tsha256\tpath\tclassification\n'
>
"
$SCRIPTS
"
:
>
"
$ENDPOINTS
"
# Confirmed campaign indicators.
BAD_KEY_SHA256
=
'SHA256:/6Ll/VlsnRWorwg3IpUSNSosKJxNNA6znrR+QTXQRaE'
CURSOR_KEY_FRAGMENT
=
'AAAAB3NzaC1yc2EAAAADAQABAAABAQCF8tdOgKz0byyI/1wsvYH7/dAH71F7QDr4W7PQu8aCH8'
PIVOT_KEY_FRAGMENT
=
'AAAAB3NzaC1yc2EAAAADAQABAAABAQC4evWpxa5XJ8KiL1+E32x1MB7FlijaDTHVhBOwL7xhr0GvZGLj'
KNOWN_AK_ID
=
'LTAI4FjyvUTRZZN4QyHoXQag'
IOC_TEXT_REGEX
=
'101\.201\.148\.142|8\.217\.173\.211|hdocf\.com|ddocf\.com|watch_dog_auth|hpgoc2([.-]|\.oss\.v2\.core)|cursor-agent-010|aliyun-sys-assist|AliyunSysAssist|/tmp/dbg([^A-Za-z0-9_.-]|$)|libnuma_hint\.so|url_key=hpgoc2|LTAI4FjyvUTRZZN4QyHoXQag'
IOC_EXEC_REGEX
=
'AuthorizedKeysCommand|authorized_keys|unset[[:space:]]+HISTFILE|rpm[[:space:]]+-Uvh|/tmp/sys\.rpm|/tmp/elf\.rpm|/tmp/kd\.rpm|dbg-el6|aliyun-sys-assist'
sanitize
()
{
local
_value
_value
=
"
$1
"
printf
'%s'
"
$_value
"
|
tr
'\t\r\n'
' '
}
section
()
{
local
_title
_title
=
"
$1
"
printf
'\n===== %s =====\n'
"
$_title
"
>>
"
$RAW
"
}
finding
()
{
local
_sev _stage _category _evidence _line
_sev
=
"
$1
"
_stage
=
"
$2
"
_category
=
"
$3
"
_evidence
=
"
$(
sanitize
"
$4
"
)
"
_line
=
"
$(
printf
'%s\t%s\t%s\t%s\t%s'
"
$HOST_NAME
"
"
$_sev
"
"
$_stage
"
"
$_category
"
"
$_evidence
"
)
"
if
!
grep
-Fqx
--
"
$_line
"
"
$FINDINGS
"
2>/dev/null
;
then
printf
'%s\n'
"
$_line
"
>>
"
$FINDINGS
"
fi
}
event
()
{
local
_time _stage _source _indicator _evidence
_time
=
"
$(
sanitize
"
$1
"
)
"
_stage
=
"
$(
sanitize
"
$2
"
)
"
_source
=
"
$(
sanitize
"
$3
"
)
"
_indicator
=
"
$(
sanitize
"
$4
"
)
"
_evidence
=
"
$(
sanitize
"
$5
"
)
"
printf
'%s\t%s\t%s\t%s\t%s\t%s\n'
\
"
$HOST_NAME
"
"
$_time
"
"
$_stage
"
"
$_source
"
"
$_indicator
"
"
$_evidence
"
>>
"
$EVENTS
"
}
hash_value
()
{
local
_target
_target
=
"
$1
"
if
have
sha256sum
;
then
sha256sum
"
$_target
"
2>/dev/null |
awk
'{print $1}'
elif
have shasum
;
then
shasum
-a
256
"
$_target
"
2>/dev/null |
awk
'{print $1}'
elif
have openssl
;
then
openssl dgst
-sha256
"
$_target
"
2>/dev/null |
awk
'{print $NF}'
fi
}
hash_label
()
{
local
_digest
_digest
=
"
$1
"
case
"
$_digest
"
in
aa0eb857cbb40a1516ba0f6ac33d2265d0b49e9067abeec4264057193e440e09
)
echo
"dbg payload"
;;
87f629925728922e2b092036b214b364b2419452a514d0b44f033ebe4a0d873c
)
echo
"malicious irqbalance variant 1"
;;
a3d832da2bd83bff45fb1df576de814f57b004777ea0dd7d1beaa46340d8ca49
)
echo
"malicious irqbalance variant 2"
;;
ca90137ec7f88f9426e2a0b591d125b6ee20f75b30e4fd9445cdbbf402594a57
)
echo
"malicious libnuma_hint.so"
;;
8ca077298ca5a46655be209bd993268e5e224f0bc10a079825e023e036d342fe
)
echo
"malicious AliyunSysAssist"
;;
f5403e362abf1ac6a4d3628f305110c6f1aa8d1ddea0922b3757ba3281ff7bc3
)
echo
"malicious aliyun-sys-assist core.so"
;;
b174e5a7debf48004811e58be69cfaad607af379c3dcbf268772f84be88a2b8f
)
echo
"malicious aliyun-sys-assist setup"
;;
17a45ace32f6343b35c3300658e1ebdd3865608c6b20d2e3c0e13344b3b73a68
)
echo
"malicious aliyun-sys-assist configuration"
;;
*
)
echo
""
;;
esac
}
classify_hash
()
{
local
_digest _path _label
_digest
=
"
$1
"
_path
=
"
$2
"
_label
=
"
$(
hash_label
"
$_digest
"
)
"
if
test
-n
"
$_label
"
;
then
finding CRITICAL execution
hash
"Known campaign hash
$_digest
(
$_label
) at
$_path
"
event
"
$(
date
'+%F %T %z'
)
"
execution filesystem
"
$_label
"
"
$_path
sha256=
$_digest
"
fi
}
copy_artifact
()
{
local
_source _destination
_source
=
"
$1
"
_destination
=
"
$2
"
test
-r
"
$_source
"
||
return
0
cp
-p
"
$_source
"
"
$_destination
"
>>
"
$RAW
"
2>&1
||
true
chmod
go-rwx
"
$_destination
"
2>/dev/null
||
true
}
file_evidence
()
{
local
_path _reason _digest _label _safe_name
_path
=
"
$1
"
_reason
=
"
$2
"
test
-e
"
$_path
"
||
test
-L
"
$_path
"
||
return
0
echo
"--
$_path
(
$_reason
) --"
>>
"
$RAW
"
stat
"
$_path
"
>>
"
$RAW
"
2>&1
file
"
$_path
"
>>
"
$RAW
"
2>&1
_digest
=
""
if
test
-f
"
$_path
"
&&
test
-r
"
$_path
"
;
then
_digest
=
"
$(
hash_value
"
$_path
"
)
"
echo
"sha256=
$_digest
"
>>
"
$RAW
"
classify_hash
"
$_digest
"
"
$_path
"
_label
=
"
$(
hash_label
"
$_digest
"
)
"
if
test
-n
"
$_label
"
\
||
test
"
$_path
"
=
/usr/sbin/aliyun-sys-assist-setup
\
||
printf
'%s'
"
$_path
"
|
grep
-q
'^/usr/local/share/aliyun-sys-assist/'
\
||
printf
'%s'
"
$_path
"
|
grep
-q
'^/usr/lib/aliyun-sys-assist-payload/'
\
||
{
test
"
$_path
"
=
/usr/sbin/irqbalance
&&
test
"
${
IRQ_RPM_BAD
:-
0
}
"
-eq
1
;
}
;
then
_safe_name
=
"
$(
basename
"
$_path
"
|
tr
-c
'A-Za-z0-9._-'
'_'
)
"
copy_artifact
"
$_path
"
"
$ARTIFACTS
/campaign-files/
${
_digest
}
-
${
_safe_name
}
"
fi
if
test
"
$_path
"
=
/usr/sbin/irqbalance
&&
test
"
${
IRQ_RPM_BAD
:-
0
}
"
-eq
1
;
then
finding CRITICAL execution
hash
"Altered /usr/sbin/irqbalance sha256=
$_digest
(known or newly observed variant)"
fi
fi
if
have rpm
;
then
rpm
-qf
"
$_path
"
>>
"
$RAW
"
2>&1
;
fi
}
START_EPOCH
=
"
$(
date
-d
"
$SCAN_START
"
+%s 2>/dev/null
||
echo
0
)
"
END_EPOCH
=
"
$(
date
-d
"
$SCAN_END
"
+%s 2>/dev/null
||
echo
0
)
"
if
test
"
$START_EPOCH
"
-eq
0
||
test
"
$END_EPOCH
"
-eq
0
||
test
"
$START_EPOCH
"
-ge
"
$END_EPOCH
"
;
then
echo
"Invalid incident window:
$SCAN_START
->
$SCAN_END
"
>
&2
exit
1
fi
START_MARK
=
"
$OUT_DIR
/.window-start"
END_MARK
=
"
$OUT_DIR
/.window-end"
touch
-d
"
$SCAN_START
"
"
$START_MARK
"
||
exit
1
touch
-d
"
$SCAN_END
"
"
$END_MARK
"
||
exit
1
section
"scan metadata"
{
echo
"scanner_version=
$VERSION
"
echo
"scan_time=
$(
date
'+%F %T %z'
)
"
echo
"scan_window=
$SCAN_START
->
$SCAN_END
"
echo
"mode=
$MODE
"
echo
"hostname=
$HOST_NAME
"
uname
-a
test
-r
/etc/redhat-release
&&
cat
/etc/redhat-release
test
-r
/etc/centos-release
&&
cat
/etc/centos-release
uptime
echo
"-- addresses --"
if
have ip
;
then
ip
-4
addr show
;
else
ifconfig
-a
2>/dev/null
;
fi
echo
"-- routes --"
if
have ip
;
then
ip route show
;
else
route
-n
2>/dev/null
;
fi
echo
"-- time --"
date
hwclock 2>/dev/null
||
true
}
>>
"
$RAW
"
2>&1
section
"accounts and local sessions"
{
stat
/etc/passwd /etc/shadow /etc/group /etc/sudoers 2>/dev/null
echo
"-- UID 0 accounts --"
awk
-F
:
'$3==0 {print}'
/etc/passwd
echo
"-- current sessions --"
who
-a
echo
"-- recent sessions --"
last
-Fai
2>/dev/null |
head
-200
}
>>
"
$RAW
"
2>&1
EXTRA_UID0
=
"
$(
awk
-F
:
'$3==0 && $1!="root" {print $1}'
/etc/passwd 2>/dev/null |
tr
'\n'
' '
)
"
if
test
-n
"
$EXTRA_UID0
"
;
then
finding HIGH persistence account
"Additional UID 0 account(s):
$EXTRA_UID0
"
fi
section
"targeted RPM and malicious package evidence"
IRQ_RPM_BAD
=
0
if
have rpm
;
then
echo
"-- relevant installed packages --"
>>
"
$RAW
"
rpm
-qa
--qf
'%{NAME}\t%{VERSION}-%{RELEASE}\t%{ARCH}\t%{INSTALLTIME}\n'
2>/dev/null
\
|
grep
-Eai
'^(aliyun|irqbalance|rng-tools|kernel-devel|elfutils-libelf-devel)'
>>
"
$RAW
"
echo
"-- recent RPM installs --"
>>
"
$RAW
"
rpm
-qa
--last
2>/dev/null |
head
-200
>>
"
$RAW
"
if
rpm
-q
irqbalance
>
/dev/null 2>&1
;
then
rpm
-qi
irqbalance
>>
"
$RAW
"
2>&1
IRQ_VERIFY
=
"
$(
rpm
-V
irqbalance 2>&1
||
true
)
"
printf
'%s\n'
"
$IRQ_VERIFY
"
>>
"
$RAW
"
if
printf
'%s\n'
"
$IRQ_VERIFY
"
|
grep
-q
'/usr/sbin/irqbalance'
;
then
IRQ_RPM_BAD
=
1
finding CRITICAL execution integrity
"RPM verification failed for /usr/sbin/irqbalance:
$IRQ_VERIFY
"
fi
fi
if
rpm
-q
aliyun-sys-assist
>
/dev/null 2>&1
;
then
finding CRITICAL persistence package
"Unsigned campaign package aliyun-sys-assist is installed"
rpm
-qi
aliyun-sys-assist
>
"
$ARTIFACTS
/package-metadata/aliyun-sys-assist-rpm-info.txt"
2>&1
rpm
-ql
aliyun-sys-assist
>
"
$ARTIFACTS
/package-metadata/aliyun-sys-assist-files.txt"
2>&1
rpm
-q
--scripts
aliyun-sys-assist
>
"
$ARTIFACTS
/package-metadata/aliyun-sys-assist-scripts.txt"
2>&1
rpm
-V
aliyun-sys-assist
>
"
$ARTIFACTS
/package-metadata/aliyun-sys-assist-verify.txt"
2>&1
||
true
cat
"
$ARTIFACTS
/package-metadata/aliyun-sys-assist-rpm-info.txt"
>>
"
$RAW
"
cat
"
$ARTIFACTS
/package-metadata/aliyun-sys-assist-scripts.txt"
>>
"
$RAW
"
_pkg_epoch
=
"
$(
rpm
-q
aliyun-sys-assist
--qf
'%{INSTALLTIME}'
2>/dev/null
||
true
)
"
if
test
-n
"
$_pkg_epoch
"
;
then
_pkg_time
=
"
$(
date
-d
"@
$_pkg_epoch
"
'+%F %T %z'
2>/dev/null
||
echo
"
$_pkg_epoch
"
)
"
event
"
$_pkg_time
"
persistence rpm aliyun-sys-assist
"unsigned package installed"
fi
_sig
=
"
$(
rpm
-qi
aliyun-sys-assist 2>/dev/null |
grep
-i
'^Signature'
||
true
)
"
if
printf
'%s'
"
$_sig
"
|
grep
-qi
'(none)'
;
then
finding CRITICAL execution signature
"aliyun-sys-assist RPM has no package signature:
$_sig
"
fi
fi
for
_build_pkg
in
$(
rpm
-qa
2>/dev/null |
grep
-E
'^(kernel-devel|elfutils-libelf-devel)'
)
;
do
_build_epoch
=
"
$(
rpm
-q
"
$_build_pkg
"
--qf
'%{INSTALLTIME}'
2>/dev/null
||
echo
0
)
"
if
test
"
$_build_epoch
"
-ge
"
$START_EPOCH
"
2>/dev/null
\
&&
test
"
$_build_epoch
"
-le
"
$END_EPOCH
"
2>/dev/null
;
then
_build_time
=
"
$(
date
-d
"@
$_build_epoch
"
'+%F %T %z'
2>/dev/null
||
echo
"
$_build_epoch
"
)
"
finding HIGH execution prerequisite
"Build prerequisite installed during incident window:
$_build_pkg
at
$_build_time
"
event
"
$_build_time
"
execution rpm build-prerequisite
"
$_build_pkg
"
fi
done
fi
section
"known and campaign-related files"
for
_path
in
\
/usr/sbin/irqbalance
\
/usr/lib64/libnuma_hint.so
\
/usr/lib/libnuma_hint.so
\
/usr/sbin/aliyun-sys-assist-setup
\
/usr/lib/aliyun-sys-assist-payload/AliyunSysAssist
\
/usr/lib/aliyun-sys-assist-payload/core.so
\
/usr/lib/aliyun-sys-assist-payload/.cfg.example
\
/usr/local/share/aliyun-sys-assist/AliyunSysAssist
\
/usr/local/share/aliyun-sys-assist/.cfg
\
/usr/local/share/aliyun-sys-assist/.epcache
\
/usr/local/share/aliyun-sys-assist/.helper.lock
\
/usr/local/share/aliyun-sys-assist/.helper.alive
\
/tmp/dbg /tmp/dbg-el6 /tmp/sys.rpm /tmp/elf.rpm /tmp/kd.rpm
\
/tmp/v2_rpm.log /tmp/v2_rpm.exit
;
do
file_evidence
"
$_path
"
campaign-target
done
section
"static indicators extracted from campaign binaries"
for
_binary
in
\
/usr/sbin/irqbalance
\
/usr/sbin/aliyun-sys-assist-setup
\
/usr/lib/aliyun-sys-assist-payload/AliyunSysAssist
\
/usr/lib/aliyun-sys-assist-payload/core.so
\
/usr/local/share/aliyun-sys-assist/AliyunSysAssist
\
/usr/lib64/libnuma_hint.so /usr/lib/libnuma_hint.so
\
/tmp/dbg /tmp/dbg-el6
;
do
test
-r
"
$_binary
"
||
continue
_binary_hash
=
"
$(
hash_value
"
$_binary
"
)
"
_binary_label
=
"
$(
hash_label
"
$_binary_hash
"
)
"
if
test
-z
"
$_binary_label
"
;
then
case
"
$_binary
"
in
/usr/sbin/irqbalance
)
test
"
${
IRQ_RPM_BAD
:-
0
}
"
-eq
1
||
continue
_binary_label
=
"altered irqbalance candidate"
;;
/usr/sbin/aliyun-sys-assist-setup|/usr/lib/aliyun-sys-assist-payload/
*
|
/usr/local/share/aliyun-sys-assist/
*
|
/tmp/dbg|/tmp/dbg-el6
)
_binary_label
=
"campaign-path candidate"
;;
*
)
continue
;;
esac
fi
_binary_name
=
"
$(
basename
"
$_binary
"
|
tr
-c
'A-Za-z0-9._-'
'_'
)
"
_indicator_file
=
"
$ARTIFACTS
/binary-indicators/
${
_binary_hash
}
-
${
_binary_name
}
.txt"
if
have strings
;
then
strings
-a
"
$_binary
"
2>/dev/null
\
|
grep
-Eai
'https?://|([0-9]{1,3}\.){3}[0-9]{1,3}|[A-Za-z0-9._-]+\.(com|net|org|cn)([:/]|$)|authorized_keys|HISTFILE|/tmp/|socket|curl|wget'
\
|
sort
-u
>
"
$_indicator_file
"
cat
"
$_indicator_file
"
>>
"
$ENDPOINTS
"
fi
if
have readelf
;
then
readelf
-h
-n
-d
"
$_binary
"
>>
"
$RAW
"
2>&1
fi
done
sort
-u
"
$ENDPOINTS
"
-o
"
$ENDPOINTS
"
2>/dev/null
||
true
if
test
-d
/usr/local/share/aliyun-sys-assist
;
then
finding CRITICAL persistence directory
"Malicious lookalike directory /usr/local/share/aliyun-sys-assist exists"
find /usr/local/share/aliyun-sys-assist
-xdev
-printf
'%M %u:%g %TY-%Tm-%Td %TH:%TM:%TS %s %p\n'
\
>>
"
$RAW
"
2>/dev/null
if
test
-r
/usr/local/share/aliyun-sys-assist/.cfg
&&
have strings
;
then
echo
"-- strings from malicious .cfg --"
>>
"
$RAW
"
strings
-a
/usr/local/share/aliyun-sys-assist/.cfg |
head
-200
>>
"
$RAW
"
if
strings
-a
/usr/local/share/aliyun-sys-assist/.cfg |
grep
-Eq
"
$IOC_TEXT_REGEX
"
;
then
finding CRITICAL command_control configuration
"aliyun-sys-assist .cfg contains campaign endpoint/key indicators"
fi
fi
fi
section
"running process correlation"
MATCHED_PIDS
=
""
CAMPAIGN_PIDS
=
""
IRQ_PIDS
=
""
for
_proc
in
/proc/[0-9]
*
;
do
test
-d
"
$_proc
"
||
continue
_pid
=
"
${
_proc
#/proc/
}
"
_exe
=
"
$(
readlink
"
$_proc
/exe"
2>/dev/null
||
true
)
"
_comm
=
"
$(
cat
"
$_proc
/comm"
2>/dev/null
||
true
)
"
_cmd
=
"
$(
tr
'\0'
' '
<
"
$_proc
/cmdline"
2>/dev/null
||
true
)
"
_maps_hit
=
"
$(
grep
-E
'libnuma_hint\.so|aliyun-sys-assist|/tmp/dbg'
"
$_proc
/maps"
2>/dev/null |
head
-20
||
true
)
"
_digest
=
""
test
-r
"
$_proc
/exe"
&&
_digest
=
"
$(
hash_value
"
$_proc
/exe"
)
"
_label
=
"
$(
hash_label
"
$_digest
"
)
"
_match
=
0
_campaign_match
=
0
case
"
$_comm
$_exe
$_cmd
$_maps_hit
$_label
"
in
*
irqbalance
*
|
*
AliyunSysAssist
*
|
*
aliyun-sys-assist
*
|
*
"/tmp/dbg"
*
|
*
libnuma_hint
*
|
*
"dbg payload"
*
|
*
"malicious "
*
)
_match
=
1
;
_campaign_match
=
1
;;
*
"(deleted)"
*
)
_match
=
1
;;
rngd
*
)
_match
=
1
;;
esac
test
"
$_match
"
-eq
1
||
continue
MATCHED_PIDS
=
"
$MATCHED_PIDS
$_pid
"
test
"
$_campaign_match
"
-eq
1
&&
CAMPAIGN_PIDS
=
"
$CAMPAIGN_PIDS
$_pid
"
case
"
$_comm
$_cmd
"
in
*
irqbalance
*
)
IRQ_PIDS
=
"
$IRQ_PIDS
$_pid
"
;;
esac
_ppid
=
"
$(
awk
'/^PPid:/ {print $2}'
"
$_proc
/status"
2>/dev/null
||
true
)
"
_user
=
"
$(
ps
-p
"
$_pid
"
-o
user
=
2>/dev/null |
awk
'{print $1}'
)
"
_start
=
"
$(
ps
-p
"
$_pid
"
-o
lstart
=
2>/dev/null |
sed
's/^[[:space:]]*//'
)
"
printf
'%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n'
\
"
$HOST_NAME
"
"
$_pid
"
"
$_ppid
"
"
$_user
"
"
$(
sanitize
"
$_start
"
)
"
\
"
$(
sanitize
"
$_comm
"
)
"
"
$(
sanitize
"
$_exe
"
)
"
"
$_digest
"
"
$(
sanitize
"
$_cmd
"
)
"
>>
"
$PROCESSES
"
_proc_report
=
"
$ARTIFACTS
/processes/pid-
${
_pid
}
.txt"
{
ps
-o
user,pid,ppid,lstart,etime,stat,cmd
-p
"
$_pid
"
echo
"comm=
$_comm
"
echo
"exe=
$_exe
"
echo
"sha256=
$_digest
"
echo
"cmdline=
$_cmd
"
echo
"-- maps IOC subset --"
printf
'%s\n'
"
$_maps_hit
"
echo
"-- file descriptors --"
ls
-l
"
$_proc
/fd"
echo
"-- limits --"
cat
"
$_proc
/limits"
2>/dev/null
}
>
"
$_proc_report
"
2>&1
if
test
"
$_campaign_match
"
-eq
1
&&
test
-r
"
$_proc
/exe"
;
then
_proc_size
=
"
$(
stat
-c
%s
"
$_proc
/exe"
2>/dev/null
||
echo
0
)
"
if
test
"
$_proc_size
"
-le
52428800 2>/dev/null
;
then
copy_artifact
"
$_proc
/exe"
"
$ARTIFACTS
/processes/pid-
${
_pid
}
-exe.bin"
else
echo
"process executable not copied due to size: pid=
$_pid
size=
$_proc_size
exe=
$_exe
"
>>
"
$RAW
"
fi
fi
test
-n
"
$_digest
"
&&
classify_hash
"
$_digest
"
"/proc/
$_pid
/exe (
$_exe
)"
if
test
-n
"
$_label
"
;
then
finding CRITICAL execution process
"PID
$_pid
runs
$_label
; comm=
$_comm
exe=
$_exe
"
fi
case
"
$_exe
"
in
/tmp/dbg|/tmp/dbg-el6|
"/tmp/dbg (deleted)"
|
"/tmp/dbg-el6 (deleted)"
)
finding CRITICAL execution process
"PID
$_pid
runs campaign payload
$_exe
; comm=
$_comm
"
;;
*
"(deleted)"
*
)
finding HIGH defense_evasion process
"PID
$_pid
runs deleted executable
$_exe
; comm=
$_comm
"
;;
esac
case
"
$_comm
$_exe
$_cmd
"
in
*
AliyunSysAssist
*
|
*
aliyun-sys-assist
*
)
finding CRITICAL persistence process
"PID
$_pid
is active malicious AliyunSysAssist component; exe=
$_exe
"
;;
esac
if
test
-n
"
$_maps_hit
"
&&
printf
'%s'
"
$_maps_hit
"
|
grep
-q
'libnuma_hint\.so'
;
then
finding CRITICAL execution process
"PID
$_pid
maps malicious libnuma_hint.so; exe=
$_exe
"
fi
event
"
$_start
"
execution process
"
$_comm
"
"pid=
$_pid
ppid=
$_ppid
exe=
$_exe
sha256=
$_digest
"
done
IRQ_COUNT
=
"
$(
printf
'%s\n'
$IRQ_PIDS
2>/dev/null |
awk
'NF {n++} END {print n+0}'
)
"
if
test
"
$IRQ_COUNT
"
-gt
1
;
then
finding HIGH execution process
"Multiple irqbalance-like processes are active (
$IRQ_COUNT
):
$IRQ_PIDS
"
fi
section
"network, C2 and local control sockets"
NET_ALL
=
""
UNIX_ALL
=
""
if
have netstat
;
then
NET_ALL
=
"
$(
netstat
-antup
2>/dev/null
||
true
)
"
UNIX_ALL
=
"
$(
netstat
-xap
2>/dev/null
||
true
)
"
elif
have ss
;
then
NET_ALL
=
"
$(
ss
-antup
2>/dev/null
||
true
)
"
UNIX_ALL
=
"
$(
ss
-xap
2>/dev/null
||
true
)
"
fi
printf
'%s\n'
"
$NET_ALL
"
>>
"
$RAW
"
printf
'%s\n'
"
$UNIX_ALL
"
>>
"
$RAW
"
if
printf
'%s\n'
"
$UNIX_ALL
"
|
grep
-Fq
'hpgoc2.oss.v2.core'
;
then
_sock_hit
=
"
$(
printf
'%s\n'
"
$UNIX_ALL
"
|
grep
-F
'hpgoc2.oss.v2.core'
|
head
-5
)
"
finding CRITICAL command_control socket
"Known campaign Unix socket is active:
$_sock_hit
"
event
"
$(
date
'+%F %T %z'
)
"
command_control socket hpgoc2.oss.v2.core
"
$_sock_hit
"
fi
if
printf
'%s\n'
"
$NET_ALL
"
|
grep
-Eq
'101\.201\.148\.142|8\.217\.173\.211'
;
then
_net_hit
=
"
$(
printf
'%s\n'
"
$NET_ALL
"
|
grep
-E
'101\.201\.148\.142|8\.217\.173\.211'
|
head
-10
)
"
finding CRITICAL command_control network
"Active connection to known campaign IP:
$_net_hit
"
event
"
$(
date
'+%F %T %z'
)
"
command_control network known-c2
"
$_net_hit
"
fi
if
have netstat
;
then
netstat
-antp
2>/dev/null |
awk
-v
host
=
"
$HOST_NAME
"
'
BEGIN {OFS="\t"}
$1 ~ /^tcp/ && $6 == "ESTABLISHED" {
remote=$5; ip=remote; sub(/:[^:]*$/, "", ip)
if (ip ~ /^::ffff:/) sub(/^::ffff:/, "", ip)
private=(ip ~ /^10\./ || ip ~ /^127\./ || ip ~ /^169\.254\./ ||
ip ~ /^192\.168\./ || ip ~ /^0\.0\.0\.0$/ ||
ip ~ /^172\.(1[6-9]|2[0-9]|3[01])\./)
if (!private && ip ~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/)
print host,$1,$4,$5,$6,$7
}
'
>>
"
$CONNECTIONS
"
elif
have ss
;
then
ss
-antp
2>/dev/null |
awk
-v
host
=
"
$HOST_NAME
"
'
BEGIN {OFS="\t"}
$1 == "ESTAB" {
remote=$5; ip=remote; sub(/:[^:]*$/, "", ip)
private=(ip ~ /^10\./ || ip ~ /^127\./ || ip ~ /^169\.254\./ ||
ip ~ /^192\.168\./ || ip ~ /^0\.0\.0\.0$/ ||
ip ~ /^172\.(1[6-9]|2[0-9]|3[01])\./)
if (!private && ip ~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/)
print host,"tcp",$4,$5,$1,$6
}
'
>>
"
$CONNECTIONS
"
fi
PUBLIC_COUNT
=
"
$(
awk
'NR>1 {n++} END {print n+0}'
"
$CONNECTIONS
"
)
"
test
"
$PUBLIC_COUNT
"
-gt
0
&&
finding INFO discovery network
"Recorded
$PUBLIC_COUNT
established public connection(s) for review"
for
_pid
in
$CAMPAIGN_PIDS
;
do
if
have netstat
;
then
_pid_net
=
"
$(
printf
'%s\n'
"
$NET_ALL
"
|
grep
-E
"[[:space:]]
${
_pid
}
/"
||
true
)
"
else
_pid_net
=
"
$(
printf
'%s\n'
"
$NET_ALL
"
|
grep
-E
"pid=
${
_pid
}
[,)]|pid=
\"
${
_pid
}
\"
"
||
true
)
"
fi
if
test
-n
"
$_pid_net
"
;
then
printf
'\n-- network for matched PID %s --\n%s\n'
"
$_pid
"
"
$_pid_net
"
>>
"
$RAW
"
finding HIGH command_control network
"Matched PID
$_pid
has active network connection(s):
$_pid_net
"
fi
done
section
"SSH keys and credential material"
for
_ssh_dir
in
/root/.ssh /home/
*
/.ssh
;
do
test
-d
"
$_ssh_dir
"
||
continue
find
"
$_ssh_dir
"
-maxdepth
2
-type
f
\(
-name
authorized_keys
-o
-name
authorized_keys2
\)
2>/dev/null
\
|
while
IFS
=
read
-r
_key_file
;
do
echo
"--
$_key_file
--"
>>
"
$RAW
"
stat
"
$_key_file
"
>>
"
$RAW
"
2>&1
_key_copy
=
"
$(
printf
'%s'
"
$_key_file
"
|
sed
's#/#_#g'
)
"
copy_artifact
"
$_key_file
"
"
$ARTIFACTS
/authorized-keys/
${
_key_copy
}
"
_key_info
=
"
$(
ssh-keygen
-E
sha256
-lf
"
$_key_file
"
2>/dev/null
||
ssh-keygen
-lf
"
$_key_file
"
2>/dev/null
||
true
)
"
printf
'%s\n'
"
$_key_info
"
>>
"
$RAW
"
if
printf
'%s\n'
"
$_key_info
"
|
grep
-Fq
"
$BAD_KEY_SHA256
"
\
||
grep
-Fq
"
$PIVOT_KEY_FRAGMENT
"
"
$_key_file
"
2>/dev/null
;
then
finding CRITICAL persistence ssh_key
"Known 159-generated attacker key is authorized in
$_key_file
"
fi
if
grep
-Fq
"
$CURSOR_KEY_FRAGMENT
"
"
$_key_file
"
2>/dev/null
\
||
grep
-Fq
'cursor-agent-010'
"
$_key_file
"
2>/dev/null
;
then
finding CRITICAL persistence ssh_key
"Known cursor-agent-010 key is authorized in
$_key_file
"
fi
done
done
for
_ssh_dir
in
/root/.ssh /home/
*
/.ssh
;
do
test
-d
"
$_ssh_dir
"
||
continue
find
"
$_ssh_dir
"
-maxdepth
2
-type
f
\(
-name
id_rsa
-o
-name
id_dsa
-o
-name
id_ecdsa
-o
-name
id_ed25519
\)
2>/dev/null
\
|
while
IFS
=
read
-r
_private_key
;
do
_key_mtime
=
"
$(
stat
-c
%Y
"
$_private_key
"
2>/dev/null
||
echo
0
)
"
_key_hash
=
"
$(
hash_value
"
$_private_key
"
)
"
echo
"private_key=
$_private_key
mtime_epoch=
$_key_mtime
sha256=
$_key_hash
"
>>
"
$RAW
"
stat
"
$_private_key
"
>>
"
$RAW
"
2>&1
if
test
"
$_key_mtime
"
-ge
"
$START_EPOCH
"
2>/dev/null
\
&&
test
"
$_key_mtime
"
-le
"
$END_EPOCH
"
2>/dev/null
;
then
_key_time
=
"
$(
date
-d
"@
$_key_mtime
"
'+%F %T %z'
2>/dev/null
||
echo
"
$_key_mtime
"
)
"
finding HIGH credential_access ssh_private_key
"Private SSH key changed during incident window:
$_private_key
at
$_key_time
sha256=
$_key_hash
"
event
"
$_key_time
"
credential_access filesystem ssh-private-key
"
$_private_key
sha256=
$_key_hash
"
fi
done
done
section
"SSH authentication timeline"
if
ls
/var/log/secure
*
>
/dev/null 2>&1
;
then
zgrep
-hE
'sshd.*Accepted (publickey|password)'
/var/log/secure
*
2>/dev/null
\
|
grep
-E
'^Sep[[:space:]]+(10|11|12)[[:space:]]'
>
"
$SSH_SUCCESS
"
cat
"
$SSH_SUCCESS
"
>>
"
$RAW
"
_from_159
=
"
$(
grep
-E
'Accepted (publickey|password).* from 172\.18\.172\.159 '
"
$SSH_SUCCESS
"
||
true
)
"
if
test
-n
"
$_from_159
"
;
then
finding CRITICAL lateral_movement ssh
"Successful SSH authentication from compromised pivot 172.18.172.159:
$(
printf
'%s\n'
"
$_from_159
"
|
head
-8
)
"
fi
_bad_fp_log
=
"
$(
grep
-F
"
$BAD_KEY_SHA256
"
"
$SSH_SUCCESS
"
||
true
)
"
if
test
-n
"
$_bad_fp_log
"
;
then
finding CRITICAL lateral_movement ssh
"Known attacker key fingerprint used successfully:
$(
printf
'%s\n'
"
$_bad_fp_log
"
|
head
-8
)
"
fi
while
IFS
=
read
-r
_ssh_line
;
do
test
-n
"
$_ssh_line
"
||
continue
_ssh_raw_time
=
"
$(
printf
'%s'
"
$_ssh_line
"
|
awk
'{print $1" "$2" "$3}'
)
"
_ssh_stamp
=
"
$(
date
-d
"2026
$_ssh_raw_time
"
'+%F %T %z'
2>/dev/null
||
echo
"2026
$_ssh_raw_time
"
)
"
event
"
$_ssh_stamp
"
lateral_movement secure-log ssh-accepted
"
$_ssh_line
"
done
<
"
$SSH_SUCCESS
"
else
finding INFO discovery logging
"No /var/log/secure* files were available"
fi
section
"Aliyun CLI and possible AccessKey exposure"
if
have aliyun
;
then
_aliyun_path
=
"
$(
command
-v
aliyun
)
"
file_evidence
"
$_aliyun_path
"
aliyun-cli
fi
for
_aliyun_cfg
in
/root/.aliyun/config.json /home/
*
/.aliyun/config.json
;
do
test
-f
"
$_aliyun_cfg
"
||
continue
stat
"
$_aliyun_cfg
"
>>
"
$RAW
"
2>&1
echo
"aliyun_cli_config=
$_aliyun_cfg
sha256=
$(
hash_value
"
$_aliyun_cfg
"
)
"
>>
"
$RAW
"
_ak_ids
=
"
$(
grep
-Eo
'LTAI[A-Za-z0-9]+'
"
$_aliyun_cfg
"
2>/dev/null |
sort
-u
|
tr
'\n'
' '
)
"
finding HIGH credential_access cloud_credential
"Aliyun CLI credential file exists on compromised host:
$_aliyun_cfg
access_key_ids=
$_ak_ids
"
if
grep
-Fq
"
$KNOWN_AK_ID
"
"
$_aliyun_cfg
"
2>/dev/null
;
then
finding CRITICAL credential_access cloud_credential
"Known compromised AccessKey ID is stored in
$_aliyun_cfg
"
fi
done
for
_hist_root
in
/root/.bash_history /root/.zsh_history /home/
*
/.bash_history /home/
*
/.zsh_history
;
do
test
-f
"
$_hist_root
"
||
continue
if
grep
-Eq
"
$IOC_TEXT_REGEX
|aliyun[[:space:]].*(RunCommand|ecs)|access[_-]?key"
"
$_hist_root
"
2>/dev/null
;
then
finding HIGH credential_access shell_history
"Cloud/campaign references found in
$_hist_root
; inspect locally for leaked credentials"
echo
"history_ioc_file=
$_hist_root
"
>>
"
$RAW
"
fi
done
section
"official Cloud Assistant inventory"
for
_official_root
in
/usr/local/share/aliyun-assist /opt/local/share/aliyun-assist
;
do
test
-d
"
$_official_root
"
||
continue
echo
"-- official root
$_official_root
--"
>>
"
$RAW
"
stat
"
$_official_root
"
>>
"
$RAW
"
2>&1
find
"
$_official_root
"
-maxdepth
4
-type
f
\
\(
-name
aliyun-service
-o
-name
aliyun_assist_update
-o
-name
assist_daemon
\
-o
-name
hash_file
-o
-name
version
-o
-name
region-id
\)
\
-printf
'%M %u:%g %TY-%Tm-%Td %TH:%TM:%TS %s %p\n'
>>
"
$RAW
"
2>/dev/null
find
"
$_official_root
"
-maxdepth
4
-type
f
\
\(
-name
aliyun-service
-o
-name
aliyun_assist_update
-o
-name
assist_daemon
\
-o
-name
hash_file
\)
2>/dev/null |
while
IFS
=
read
-r
_official_file
;
do
echo
"official_file=
$_official_file
sha256=
$(
hash_value
"
$_official_file
"
)
"
>>
"
$RAW
"
if
test
"
$(
basename
"
$_official_file
"
)
"
=
hash_file
;
then
_hash_copy
=
"
$(
printf
'%s'
"
$_official_file
"
|
sed
's#/#_#g'
)
"
copy_artifact
"
$_official_file
"
"
$ARTIFACTS
/package-metadata/
${
_hash_copy
}
"
fi
done
done
ps
-efww
2>/dev/null |
grep
-E
'[a]liyun-service|[a]ssist_daemon'
>>
"
$RAW
"
if
have rpm
;
then
rpm
-qa
2>/dev/null |
grep
-Eai
'^aliyun[_-]assist|cloud.*assist'
>>
"
$RAW
"
fi
section
"Cloud Assistant command artifacts"
for
_assist_root
in
/usr/local/share/aliyun-assist/work/script /opt/local/share/aliyun-assist/work/script
;
do
test
-d
"
$_assist_root
"
||
continue
find
"
$_assist_root
"
-type
f 2>/dev/null |
while
IFS
=
read
-r
_script
;
do
_script_mtime_epoch
=
"
$(
stat
-c
%Y
"
$_script
"
2>/dev/null
||
echo
0
)
"
_script_mtime
=
"
$(
date
-d
"@
$_script_mtime_epoch
"
'+%F %T %z'
2>/dev/null
||
echo
"
$_script_mtime_epoch
"
)
"
_script_hash
=
"
$(
hash_value
"
$_script
"
)
"
_classification
=
"inventory"
_matched
=
0
if
grep
-Eq
"
$IOC_TEXT_REGEX
"
"
$_script
"
2>/dev/null
;
then
_classification
=
"known-ioc"
_matched
=
1
finding CRITICAL execution cloud_assist
"Cloud Assistant script contains known campaign IOC:
$_script
"
elif
grep
-Eq
"
$IOC_EXEC_REGEX
"
"
$_script
"
2>/dev/null
;
then
_classification
=
"sensitive-command"
_matched
=
1
finding HIGH execution cloud_assist
"Cloud Assistant script contains sensitive execution/persistence command:
$_script
"
fi
if
test
"
$_script_mtime_epoch
"
-ge
"
$START_EPOCH
"
2>/dev/null
\
&&
test
"
$_script_mtime_epoch
"
-le
"
$END_EPOCH
"
2>/dev/null
;
then
_matched
=
1
test
"
$_classification
"
=
inventory
&&
_classification
=
"incident-window"
fi
printf
'%s\t%s\t%s\t%s\t%s\n'
"
$HOST_NAME
"
"
$_script_mtime
"
"
$_script_hash
"
"
$_script
"
"
$_classification
"
>>
"
$SCRIPTS
"
if
test
"
$_matched
"
-eq
1
;
then
_script_name
=
"
$(
basename
"
$_script
"
)
"
copy_artifact
"
$_script
"
"
$ARTIFACTS
/cloud-assist-scripts/
${
_script_name
}
"
echo
"-- cloud assist script
$_script
--"
>>
"
$RAW
"
stat
"
$_script
"
>>
"
$RAW
"
2>&1
sed
-n
'1,400p'
"
$_script
"
>>
"
$RAW
"
2>&1
event
"
$_script_mtime
"
execution cloud-assist-script
"
$_classification
"
"
$_script
sha256=
$_script_hash
"
fi
done
done
section
"persistence locations and IOC references"
for
_persist_root
in
\
/etc/systemd/system /usr/lib/systemd/system /lib/systemd/system
\
/etc/init.d /etc/rc.d /etc/cron.d /etc/cron.daily /etc/cron.hourly
\
/var/spool/cron /etc/profile.d /etc/ld.so.preload
;
do
test
-e
"
$_persist_root
"
||
continue
grep
-RIlE
"
$IOC_TEXT_REGEX
"
"
$_persist_root
"
>>
"
$RAW
"
2>/dev/null
done
_persist_hits
=
"
$(
grep
-RIlE
"
$IOC_TEXT_REGEX
"
\
/etc/systemd/system /usr/lib/systemd/system /lib/systemd/system
\
/etc/init.d /etc/rc.d /etc/cron.d /var/spool/cron /etc/profile.d
\
2>/dev/null |
head
-100
||
true
)
"
if
test
-n
"
$_persist_hits
"
;
then
finding CRITICAL persistence startup
"Campaign IOC found in persistence file(s):
$_persist_hits
"
fi
if
test
-s
/etc/ld.so.preload
;
then
cat
/etc/ld.so.preload
>>
"
$RAW
"
2>&1
finding HIGH persistence loader
"/etc/ld.so.preload is non-empty; review for userland hooking"
fi
if
have systemctl
;
then
systemctl status irqbalance
--no-pager
>>
"
$RAW
"
2>&1
systemctl list-unit-files
--no-pager
2>/dev/null |
grep
-Ei
'aliyun|assist|irqbalance|rngd|nvme'
>>
"
$RAW
"
elif
have chkconfig
;
then
chkconfig
--list
2>/dev/null |
grep
-Ei
'aliyun|assist|irqbalance|rngd|nvme'
>>
"
$RAW
"
fi
section
"recent files by ctime and mtime"
RECENT_ROOTS
=
"/usr/sbin /usr/local /usr/lib64 /usr/lib /etc /tmp /var/tmp /dev/shm /lib/modules/
$(
uname
-r
)
"
if
test
"
$MODE
"
=
deep
;
then
RECENT_ROOTS
=
"
$RECENT_ROOTS
/usr/bin /bin /sbin /lib /lib64 /opt"
fi
record_recent
()
{
local
_recent_path _time_type _size _mode _owner _recent_time _recent_hash
_recent_path
=
"
$1
"
_time_type
=
"
$2
"
test
-f
"
$_recent_path
"
||
return
0
_size
=
"
$(
stat
-c
%s
"
$_recent_path
"
2>/dev/null
||
echo
0
)
"
_mode
=
"
$(
stat
-c
%A
"
$_recent_path
"
2>/dev/null
||
echo
unknown
)
"
_owner
=
"
$(
stat
-c
'%U:%G'
"
$_recent_path
"
2>/dev/null
||
echo
unknown
)
"
if
test
"
$_time_type
"
=
ctime
;
then
_recent_time
=
"
$(
stat
-c
%z
"
$_recent_path
"
2>/dev/null
||
true
)
"
else
_recent_time
=
"
$(
stat
-c
%y
"
$_recent_path
"
2>/dev/null
||
true
)
"
fi
_recent_hash
=
""
if
test
"
$_size
"
-le
20971520 2>/dev/null
&&
test
-r
"
$_recent_path
"
;
then
_recent_hash
=
"
$(
hash_value
"
$_recent_path
"
)
"
test
-n
"
$_recent_hash
"
&&
classify_hash
"
$_recent_hash
"
"
$_recent_path
"
fi
printf
'%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n'
\
"
$HOST_NAME
"
"
$_time_type
"
"
$(
sanitize
"
$_recent_time
"
)
"
"
$_mode
"
"
$_owner
"
\
"
$_size
"
"
$_recent_hash
"
"
$(
sanitize
"
$_recent_path
"
)
"
>>
"
$FILES
"
case
"
$_recent_path
"
in
*
/irqbalance|
*
aliyun-sys-assist
*
|
*
libnuma_hint.so|
*
/tmp/dbg|
*
/tmp/dbg-el6|
*
/authorized_keys|
*
/id_rsa|
*
/id_rsa.pub
)
event
"
$_recent_time
"
defense_evasion filesystem
"
${
_time_type
}
-in-window"
"
$_recent_path
sha256=
$_recent_hash
"
;;
esac
}
for
_recent_root
in
$RECENT_ROOTS
;
do
test
-d
"
$_recent_root
"
||
continue
find
"
$_recent_root
"
-xdev
-type
f
-cnewer
"
$START_MARK
"
!
-cnewer
"
$END_MARK
"
-print0
2>/dev/null
\
|
while
IFS
=
read
-r
-d
''
_recent_file
;
do
record_recent
"
$_recent_file
"
ctime
;
done
find
"
$_recent_root
"
-xdev
-type
f
-newer
"
$START_MARK
"
!
-newer
"
$END_MARK
"
-print0
2>/dev/null
\
|
while
IFS
=
read
-r
-d
''
_recent_file
;
do
record_recent
"
$_recent_file
"
mtime
;
done
done
section
"kernel and module evidence"
{
echo
"-- loaded modules --"
if
have lsmod
;
then
lsmod
;
else
cat
/proc/modules 2>/dev/null
;
fi
echo
"-- module files changed in incident window --"
if
test
-d
"/lib/modules/
$(
uname
-r
)
"
;
then
find
"/lib/modules/
$(
uname
-r
)
"
-xdev
-type
f
\
-cnewer
"
$START_MARK
"
!
-cnewer
"
$END_MARK
"
\
-printf
'%CY-%Cm-%Cd %CH:%CM:%CS %s %p\n'
2>/dev/null
fi
echo
"-- recent kernel messages --"
dmesg 2>/dev/null |
tail
-500
}
>>
"
$RAW
"
2>&1
_module_changes
=
""
if
test
-d
"/lib/modules/
$(
uname
-r
)
"
;
then
_module_changes
=
"
$(
find
"/lib/modules/
$(
uname
-r
)
"
-xdev
-type
f
\
-cnewer
"
$START_MARK
"
!
-cnewer
"
$END_MARK
"
-print
2>/dev/null |
head
-50
)
"
fi
if
test
-n
"
$_module_changes
"
;
then
finding HIGH persistence kernel_module
"Kernel module file(s) changed during incident window:
$_module_changes
"
fi
section
"IOC references in selected data locations"
for
_search_root
in
\
/usr/local/share/aliyun-assist/work/script
\
/usr/local/share/aliyun-sys-assist
\
/opt/local/share/aliyun-assist/work/script
\
/root/.aliyun /home/
*
/.aliyun /root/.ssh /home/
*
/.ssh
\
/root/.bash_history /home/
*
/.bash_history
;
do
test
-e
"
$_search_root
"
||
continue
grep
-RIlE
"
$IOC_TEXT_REGEX
"
"
$_search_root
"
>>
"
$RAW
"
2>/dev/null
done
section
"scan limitations"
cat
>>
"
$RAW
"
<<
'
EOF
'
This live-host scan cannot prove that a root-compromised kernel, C library,
command binary, RPM database, logs, or timestamps are trustworthy. Attackers
can remove logs, forge mtime, hide processes, or modify verification tools.
ctime and multiple independent evidence sources are collected to reduce, not
eliminate, that limitation. Offline disk/memory forensics or rebuild remains
the trust-restoring action for confirmed hosts.
EOF
CRITICAL_COUNT
=
"
$(
awk
-F
'\t'
'NR>1 && $2=="CRITICAL" {n++} END {print n+0}'
"
$FINDINGS
"
)
"
HIGH_COUNT
=
"
$(
awk
-F
'\t'
'NR>1 && $2=="HIGH" {n++} END {print n+0}'
"
$FINDINGS
"
)
"
{
echo
"Scanner: server_incident_scan_v3.sh
$VERSION
"
echo
"Host:
$HOST_NAME
"
echo
"Scan time:
$(
date
'+%F %T %z'
)
"
echo
"Incident window:
$SCAN_START
->
$SCAN_END
"
echo
"Mode:
$MODE
"
echo
"Output:
$OUT_DIR
"
echo
"Critical findings:
$CRITICAL_COUNT
"
echo
"High findings:
$HIGH_COUNT
"
if
test
"
$CRITICAL_COUNT
"
-gt
0
;
then
echo
"Assessment: CONFIRMED/HIGH-CONFIDENCE COMPROMISE INDICATORS FOUND"
elif
test
"
$HIGH_COUNT
"
-gt
0
;
then
echo
"Assessment: SUSPICIOUS - MANUAL REVIEW REQUIRED"
else
echo
"Assessment: NO KNOWN IOC FOUND (NOT PROOF OF SAFETY)"
fi
echo
echo
"Detected stages:"
awk
-F
'\t'
'NR>1 && ($2=="CRITICAL" || $2=="HIGH") {print $3}'
"
$FINDINGS
"
|
sort
-u
|
sed
's/^/ - /'
echo
if
have column
;
then
column
-t
-s
"
$(
printf
'\t'
)
"
"
$FINDINGS
"
else
cat
"
$FINDINGS
"
fi
}
>
"
$SUMMARY
"
cat
>
"
$OUT_DIR
/README.txt"
<<
EOF
server_incident_scan_v3.sh
$VERSION
summary.txt Human-readable result
findings.tsv Cross-host findings with attack stages
chain_events.tsv Mergeable host timeline
processes.tsv Matched process inventory and hashes
public_remote_connections.tsv Established public peers for manual review
ssh_success.log Successful SSH/session entries around incident
recent_files.tsv ctime/mtime incident-window file inventory
cloud_assist_scripts.tsv Cloud Assistant command-script inventory
candidate_endpoints.txt Strings-derived endpoint candidates from known malware
evidence.txt Detailed raw evidence
artifacts/ Copies of selected evidence; mode 0700/0600
This scan performed no remediation. Reading files may update access time on
filesystems using strict atime. Treat copied executable artifacts as malware.
EOF
chmod
-R
go-rwx
"
$OUT_DIR
"
2>/dev/null
if
have
sha256sum
;
then
(
cd
"
$OUT_DIR
"
||
exit
1
find
.
-type
f
!
-name
checksums.sha256
-print
|
sort
|
while
IFS
=
read
-r
_manifest_file
;
do
sha256sum
"
$_manifest_file
"
done
)
>
"
$OUT_DIR
/checksums.sha256"
fi
cat
"
$SUMMARY
"
echo
echo
"Evidence directory:
$OUT_DIR
"
echo
"No processes, services, files, firewall rules, packages, repositories, or accounts were changed."
exit
0
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment