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
78591556
Commit
78591556
authored
Sep 17, 2026
by
易初
🖐🏻
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update incident_containment_cleanup_v1.sh
parent
b0862410
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
115 additions
and
8 deletions
+115
-8
incident_containment_cleanup_v1.sh
incident_containment_cleanup_v1.sh
+115
-8
No files found.
incident_containment_cleanup_v1.sh
View file @
78591556
...
...
@@ -15,7 +15,7 @@ set -u
umask
077
export
LC_ALL
=
C
VERSION
=
"1.
0.1
"
VERSION
=
"1.
1.0
"
APPLY
=
0
BLOCK_IOCS
=
1
REMOVE_KEYS
=
1
...
...
@@ -42,6 +42,11 @@ Options:
--ack-unload-risk Acknowledge possible kernel panic/network disruption
-h, --help Show this help
Credential safety:
The script never changes passwords, deletes unknown historical SSH keys, or
rewrites sshd_config. It records mandatory manual actions in plan.tsv so an
operator can preserve a tested administrative access path and avoid lockout.
Safe first run:
bash incident_containment_cleanup_v1.sh --output /root
...
...
@@ -144,14 +149,14 @@ capture_state() {
grep
-E
'^(ata_linkq|nvme_hctxq|xen_gntq|YL4Qr|9mLHs|3ja8C|8bmOn)[[:space:]]'
/proc/modules 2>/dev/null
||
true
echo
'===== suspicious processes ====='
ps
-ef
2>/dev/null |
grep
-E
\
'[A]liyunSysAssist|[i]rqbalance|[r]ngd|/
tmp
/[d]bg|nvme_sqmap|scsi_cmdq|usb_portctl'
||
true
'[A]liyunSysAssist|[i]rqbalance|[r]ngd|/
(tmp|var/tmp|var/opt|usr/local/sbin)
/[d]bg|nvme_sqmap|scsi_cmdq|usb_portctl'
||
true
echo
'===== suspicious sockets ====='
if
have ss
;
then
ss
-anp
2>/dev/null |
grep
-E
\
'hpgoc2|101\.201\.148\.142|8\.217\.173\.211|AliyunSysAssist|irqbalance|rngd'
||
true
'hpgoc2|101\.201\.148\.142|8\.217\.173\.211|
47\.237\.187\.64|39\.108\.93\.196|
AliyunSysAssist|irqbalance|rngd'
||
true
elif
have netstat
;
then
netstat
-anp
2>/dev/null |
grep
-E
\
'hpgoc2|101\.201\.148\.142|8\.217\.173\.211|AliyunSysAssist|irqbalance|rngd'
||
true
'hpgoc2|101\.201\.148\.142|8\.217\.173\.211|
47\.237\.187\.64|39\.108\.93\.196|
AliyunSysAssist|irqbalance|rngd'
||
true
fi
echo
'===== suspect files ====='
for
path
in
\
...
...
@@ -159,6 +164,8 @@ capture_state() {
/usr/lib/libnuma_hint.so /usr/lib/libcpu_balance.so
\
/usr/local/share/aliyun-sys-assist/AliyunSysAssist
\
/usr/sbin/aliyun-sys-assist-setup
\
/tmp/dbg /tmp/dbg-el6 /var/tmp/dbg /var/opt/dbg /usr/local/sbin/dbg
\
/tmp/sys.rpm /tmp/elf.rpm /tmp/kd.rpm
\
/usr/lib/nvme_sqmap /usr/lib/scsi_cmdq /usr/lib/usb_portctl
\
/etc/modules-load.d/ata_linkq.conf /etc/modules-load.d/nvme_hctxq.conf
\
/etc/modules-load.d/xen_gntq.conf /etc/sysconfig/modules/vmware-tools.modules
...
...
@@ -169,6 +176,18 @@ capture_state() {
done
echo
'===== package verification ====='
have rpm
&&
rpm
-V
irqbalance aliyun-sys-assist ata_linkq nvme_hctxq xen_gntq 2>&1
||
true
have rpm
&&
rpm
-V
kernel-devel elfutils-libelf-devel 2>&1
||
true
echo
'===== effective SSH policy ====='
if
have sshd
;
then
sshd
-T
2>/dev/null |
grep
-Ei
\
'^(permitrootlogin|passwordauthentication|pubkeyauthentication|authorizedkeyscommand|authorizedkeysfile)'
||
true
fi
grep
-nE
'^[[:space:]]*#?[[:space:]]*(PermitRootLogin|PasswordAuthentication|PubkeyAuthentication|AuthorizedKeysCommand|AuthorizedKeysCommandUser|AuthorizedKeysCommandRunAs)'
\
/etc/ssh/sshd_config 2>/dev/null
||
true
echo
'===== SSH private-key inventory ====='
find /root /home
-xdev
-type
f
\
\(
-name
id_rsa
-o
-name
id_dsa
-o
-name
id_ecdsa
-o
-name
id_ed25519
\)
\
-exec
stat
{}
\;
2>/dev/null
||
true
echo
'===== firewall ====='
have iptables-save
&&
iptables-save 2>/dev/null
||
true
}
>
"
$output
"
2>&1
...
...
@@ -190,12 +209,17 @@ backup_copy() {
}
quarantine_path
()
{
local source
destination digest
local source
destination digest
attrs
source
=
"
$1
"
test
-e
"
$source
"
||
test
-L
"
$source
"
||
return
0
destination
=
"
$QUARANTINE
/files
$source
"
digest
=
""
test
-f
"
$source
"
&&
digest
=
"
$(
hash_file
"
$source
"
)
"
attrs
=
""
if
have lsattr
;
then
attrs
=
"
$(
lsattr
-d
"
$source
"
2>/dev/null
||
true
)
"
printf
'attributes\t%s\t%s\n'
"
$source
"
"
$(
sanitize
"
$attrs
"
)
"
>>
"
$MANIFEST
"
fi
if
test
"
$APPLY
"
-ne
1
;
then
result quarantine
"
$source
"
planned
"sha256=
$digest
destination=
$destination
"
return
0
...
...
@@ -205,6 +229,18 @@ quarantine_path() {
printf
'%s\t%s\t%s\n'
"
$digest
"
"
$source
"
"
$destination
"
>>
"
$MANIFEST
"
result quarantine
"
$source
"
applied
"sha256=
$digest
destination=
$destination
"
log
"quarantined
$source
"
elif
test
-f
"
$source
"
&&
printf
'%s'
"
$attrs
"
|
grep
-Eq
--
'[-a-zA-Z]*i[-a-zA-Z]*[[:space:]]'
;
then
# Exact campaign files were sometimes made immutable. Preserve the original
# attribute string above, then clear only the immutable bit for this file.
if
have chattr
;
then
chattr
-i
"
$source
"
>>
"
$LOG
"
2>&1
||
true
;
fi
if
mv
"
$source
"
"
$destination
"
>>
"
$LOG
"
2>&1
;
then
printf
'%s\t%s\t%s\n'
"
$digest
"
"
$source
"
"
$destination
"
>>
"
$MANIFEST
"
result quarantine
"
$source
"
applied
"immutable bit cleared; sha256=
$digest
destination=
$destination
"
log
"cleared immutable bit and quarantined
$source
"
else
have chattr
&&
chattr +i
"
$source
"
>>
"
$LOG
"
2>&1
||
true
result quarantine
"
$source
"
failed
"destination=
$destination
; immutable bit restored when possible"
fi
else
result quarantine
"
$source
"
failed
"destination=
$destination
"
fi
...
...
@@ -251,7 +287,7 @@ block_ip() {
fi
}
KNOWN_BLOCK_IPS
=
"101.201.148.142 8.217.173.211
${
EXTRA_BLOCK_IPS
:+
$EXTRA_BLOCK_IPS
}
"
KNOWN_BLOCK_IPS
=
"101.201.148.142 8.217.173.211
47.237.187.64 39.108.93.196
${
EXTRA_BLOCK_IPS
:+
$EXTRA_BLOCK_IPS
}
"
for
address
in
$KNOWN_BLOCK_IPS
;
do
block_ip
"
$address
"
done
...
...
@@ -264,7 +300,7 @@ do
disable_service
"
$service
"
done
KNOWN_PROCESS_HASHES
=
'aa0eb857cbb40a1516ba0f6ac33d2265d0b49e9067abeec4264057193e440e09 87f629925728922e2b092036b214b364b2419452a514d0b44f033ebe4a0d873c a3d832da2bd83bff45fb1df576de814f57b004777ea0dd7d1beaa46340d8ca49 79b10ffb3c14b7745d7a7eb5e90c708b2d5eca52fe2ff65106ba4f391c02eacd 8ca077298ca5a46655be209bd993268e5e224f0bc10a079825e023e036d342fe'
KNOWN_PROCESS_HASHES
=
'aa0eb857cbb40a1516ba0f6ac33d2265d0b49e9067abeec4264057193e440e09 87f629925728922e2b092036b214b364b2419452a514d0b44f033ebe4a0d873c a3d832da2bd83bff45fb1df576de814f57b004777ea0dd7d1beaa46340d8ca49 79b10ffb3c14b7745d7a7eb5e90c708b2d5eca52fe2ff65106ba4f391c02eacd 8ca077298ca5a46655be209bd993268e5e224f0bc10a079825e023e036d342fe
0e1bd634d5fc8f4df1c91f0072a4556eb11f41ecc95b05f5a2ffb0e0b914613d 0eb8af527d40c3a1e27293be935504b6201db991fed028c6e4b805dca7f9f15d ca3c6256354a8053812c85feff0c540b6e2feddfc8fc7804ef2637628e9426e8 ca90137ec7f88f9426e2a0b591d125b6ee20f75b30e4fd9445cdbbf402594a57
'
is_known_process_hash
()
{
case
"
$KNOWN_PROCESS_HASHES
"
in
...
...
@@ -277,7 +313,10 @@ is_known_process_path() {
case
"
$1
"
in
/usr/local/share/aliyun-sys-assist/
*
|
/usr/lib/aliyun-sys-assist-payload/
*
|
\
/usr/lib/nvme_sqmap|/usr/lib/scsi_cmdq|/usr/lib/usb_portctl|
\
'/tmp/dbg (deleted)'
|
/tmp/dbg
)
return
0
;;
'/tmp/dbg (deleted)'
|
'/tmp/dbg-el6 (deleted)'
|
\
'/var/tmp/dbg (deleted)'
|
'/var/opt/dbg (deleted)'
|
\
'/usr/local/sbin/dbg (deleted)'
|
\
/tmp/dbg|/tmp/dbg-el6|/var/tmp/dbg|/var/opt/dbg|/usr/local/sbin/dbg
)
return
0
;;
*
)
return
1
;;
esac
}
...
...
@@ -371,6 +410,50 @@ remove_campaign_keys() {
remove_campaign_keys
record_manual_credential_actions
()
{
local
effective risky keyfile keyinfo accepted_159
effective
=
""
risky
=
""
if
have sshd
;
then
effective
=
"
$(
sshd
-T
2>/dev/null
||
true
)
"
risky
=
"
$(
printf
'%s\n'
"
$effective
"
\
|
grep
-Ei
'^(permitrootlogin[[:space:]]+yes|passwordauthentication[[:space:]]+yes)'
\
|
tr
'\n'
' '
)
"
fi
if
test
-n
"
$risky
"
;
then
result ssh_policy /etc/ssh/sshd_config manual_required
\
"effective risky settings:
$risky
; establish and test a trusted non-root key before hardening"
else
result ssh_policy /etc/ssh/sshd_config review_required
\
'compare PermitRootLogin, PasswordAuthentication and AuthorizedKeysCommand against the trusted baseline'
fi
result credential root manual_required
\
'rotate the root password from a trusted channel; the stolen cloud credential reset root passwords during the incident'
result cloud_credential account manual_required
\
'disable the compromised AccessKey and active sessions; require MFA and least-privilege RAM/STS credentials'
find /root /home
-xdev
-type
f
\
\(
-name
id_rsa
-o
-name
id_dsa
-o
-name
id_ecdsa
-o
-name
id_ed25519
\)
\
-print
2>/dev/null |
while
IFS
=
read
-r
keyfile
;
do
keyinfo
=
""
if
test
-r
"
${
keyfile
}
.pub"
&&
have ssh-keygen
;
then
keyinfo
=
"
$(
ssh-keygen
-lf
"
${
keyfile
}
.pub"
2>/dev/null
||
true
)
"
fi
result ssh_private_key
"
$keyfile
"
manual_required
\
"rotate/revoke downstream trust; all private keys on a root-compromised host are exposed; public_fingerprint=
$keyinfo
"
done
accepted_159
=
"
$(
zgrep
-hE
'Accepted (publickey|password).* from 172\.18\.172\.159 '
\
/var/log/secure
*
2>/dev/null |
head
-8
||
true
)
"
if
test
-n
"
$accepted_159
"
;
then
result ssh_lateral_trust 172.18.172.159 manual_required
\
"successful inbound authentication was recorded; identify the accepted key and revoke the same trust across downstream hosts:
$accepted_159
"
fi
}
record_manual_credential_actions
# Remove malicious library preload references while preserving unrelated lines.
neutralize_ld_preload
()
{
local
file temp mode uid gid
...
...
@@ -423,6 +506,14 @@ for path in \
/usr/lib/usb_portctl
\
/tmp/dbg
\
/tmp/dbg-el6
\
/var/tmp/dbg
\
/var/opt/dbg
\
/usr/local/sbin/dbg
\
/tmp/sys.rpm
\
/tmp/elf.rpm
\
/tmp/kd.rpm
\
/tmp/v2_rpm.log
\
/tmp/v2_rpm.exit
\
/etc/init.d/aliyun-sys-assist
\
/etc/rc.d/init.d/aliyun-sys-assist
\
/usr/lib/systemd/system/aliyun-sys-assist.service
\
...
...
@@ -431,6 +522,18 @@ do
quarantine_path
"
$path
"
done
# Exact temporary/staging names recovered from the attacker's own cleanup
# commands. Dry-run remains the default, and APPLY moves them recoverably.
for
path
in
\
/tmp/.irq-stats-
*
/dev/shm/.hpgoc2_skag_
*
/dev/shm/.ov2
*
\
/tmp/CVE-2021-4034
*
/tmp/.pwn
*
/tmp/.k42
*
/var/opt/.k42
*
\
/tmp/.fs_i.sh /var/tmp/.fs_i.sh /tmp/.ht_
*
/var/tmp/.ht_
*
\
/tmp/getsshpwd /tmp/.getsshpwd /var/opt/getsshpwd
\
/tmp/ssh4.zip /tmp/c.tar.gz /tmp/.chlp
*
;
do
test
-e
"
$path
"
||
test
-L
"
$path
"
||
continue
quarantine_path
"
$path
"
done
# Quarantine irqbalance only when its executable hash is one of the confirmed
# malicious variants. A legitimate binary is left untouched.
if
test
-f
/usr/sbin/irqbalance
;
then
...
...
@@ -516,6 +619,7 @@ capture_state "$AFTER"
REMAINING_MODULES
=
"
$(
grep
-Ec
'^(ata_linkq|nvme_hctxq|xen_gntq|YL4Qr|9mLHs|3ja8C|8bmOn)[[:space:]]'
/proc/modules 2>/dev/null
||
true
)
"
FAILED_ACTIONS
=
"
$(
awk
-F
'\t'
'NR > 1 && $3 == "failed" {n++} END {print n+0}'
"
$PLAN
"
)
"
APPLIED_ACTIONS
=
"
$(
awk
-F
'\t'
'NR > 1 && $3 == "applied" {n++} END {print n+0}'
"
$PLAN
"
)
"
MANUAL_ACTIONS
=
"
$(
awk
-F
'\t'
'NR > 1 && ($3 == "manual_required" || $3 == "review_required") {n++} END {print n+0}'
"
$PLAN
"
)
"
{
echo
"Host:
$HOST_NAME
"
...
...
@@ -525,6 +629,7 @@ APPLIED_ACTIONS="$(awk -F '\t' 'NR > 1 && $3 == "applied" {n++} END {print n+0}'
echo
"Output:
$RUN_DIR
"
echo
"Applied actions:
$APPLIED_ACTIONS
"
echo
"Failed actions:
$FAILED_ACTIONS
"
echo
"Manual/review actions:
$MANUAL_ACTIONS
"
echo
"Campaign modules still visible as loaded:
$REMAINING_MODULES
"
echo
if
test
"
$APPLY
"
-ne
1
;
then
...
...
@@ -533,6 +638,8 @@ APPLIED_ACTIONS="$(awk -F '\t' 'NR > 1 && $3 == "applied" {n++} END {print n+0}'
echo
'Assessment: PARTIALLY CONTAINED; HOST REMAINS KERNEL-COMPROMISED'
elif
test
"
$FAILED_ACTIONS
"
-gt
0
;
then
echo
'Assessment: CONTAINMENT ATTEMPTED WITH FAILURES; REVIEW REQUIRED'
elif
test
"
$MANUAL_ACTIONS
"
-gt
0
;
then
echo
'Assessment: USERLAND CONTAINMENT APPLIED; MANDATORY CREDENTIAL/SSH ACTIONS REMAIN'
else
echo
'Assessment: CAMPAIGN COMPONENTS NEUTRALIZED AS FAR AS THIS HOST CAN REPORT; REBUILD STILL REQUIRED'
fi
...
...
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