-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added deluserfromgroup bof #36
base: main
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
BOFNAME := deluserfromgroup | ||
COMINCLUDE := -I ../../common | ||
LIBINCLUDE := -lnetapi32 | ||
CC_x64 := x86_64-w64-mingw32-gcc | ||
CC_x86 := i686-w64-mingw32-gcc | ||
CC := x86_64-w64-mingw32-clang | ||
|
||
all: | ||
$(CC_x64) -o $(BOFNAME).x64.o $(COMINCLUDE) -Os -c entry.c -DBOF | ||
$(CC_x86) -o $(BOFNAME).x86.o $(COMINCLUDE) -Os -c entry.c -DBOF | ||
mkdir -p ../../../Remote/$(BOFNAME) | ||
mv $(BOFNAME)*.o ../../../Remote/$(BOFNAME) | ||
|
||
test: | ||
$(CC_x64) entry.c $(COMINCLUDE) $(LIBINCLUDE) -o $(BOFNAME).x64.exe | ||
$(CC_x86) entry.c $(COMINCLUDE) $(LIBINCLUDE) -o $(BOFNAME).x86.exe | ||
|
||
scanbuild: | ||
$(CC) entry.c $(COMINCLUDE) $(LIBINCLUDE) -o $(BOFNAME).scanbuild.exe | ||
|
||
check: | ||
cppcheck --enable=all --suppress=missingIncludeSystem --suppress=unusedFunction $(COMINCLUDE) --platform=win64 entry.c | ||
|
||
clean: | ||
rm $(BOFNAME).*.exe |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
#include <windows.h> | ||
#include <stdio.h> | ||
#include <lmaccess.h> | ||
#include "beacon.h" | ||
#include "bofdefs.h" | ||
#include "base.c" | ||
|
||
|
||
DWORD DelUserFromDomainGroup(LPCWSTR lpswzServer, LPCWSTR lpswzUserName, LPCWSTR lpswzGroupName) | ||
{ | ||
NET_API_STATUS dwErrorCode = NERR_Success; | ||
dwErrorCode = NETAPI32$NetGroupDelUser(lpswzServer, lpswzGroupName, lpswzUserName); | ||
return dwErrorCode; | ||
} | ||
|
||
DWORD DelUserFromLocalGroup(LPCWSTR lpswzServer, LPCWSTR lpswzUserName, LPCWSTR lpswzGroupName, LPCWSTR lpswzDomainName) | ||
{ | ||
NET_API_STATUS dwErrorCode = NERR_Success; | ||
LOCALGROUP_MEMBERS_INFO_3 mi[1] = {0}; // https://learn.microsoft.com/en-us/windows/win32/api/lmaccess/ns-lmaccess-localgroup_members_info_3 | ||
mi[0].lgrmi3_domainandname = intAlloc(1024); | ||
if (lpswzDomainName != NULL) | ||
{ | ||
MSVCRT$wcscat(mi[0].lgrmi3_domainandname, lpswzDomainName); | ||
MSVCRT$wcscat(mi[0].lgrmi3_domainandname, L"\\"); | ||
} | ||
MSVCRT$wcscat(mi[0].lgrmi3_domainandname, lpswzUserName); | ||
dwErrorCode = NETAPI32$NetLocalGroupDelMembers(lpswzServer, lpswzGroupName, 3, (LPBYTE)mi, 1); | ||
return dwErrorCode; | ||
} | ||
|
||
#ifdef BOF | ||
VOID go( | ||
IN PCHAR Buffer, | ||
IN ULONG Length | ||
) | ||
{ | ||
DWORD dwErrorCode = ERROR_SUCCESS; | ||
datap parser = {0}; | ||
BeaconDataParse(&parser, Buffer, Length); | ||
LPCWSTR lpswzDomainName = (LPCWSTR)BeaconDataExtract(&parser, NULL); // $5 | ||
LPCWSTR lpswzHostName = (LPCWSTR)BeaconDataExtract(&parser, NULL); // $4 | ||
LPCWSTR lpswzUserName = (LPCWSTR)BeaconDataExtract(&parser, NULL); // $2 | ||
LPCWSTR lpswzGroupName = (LPCWSTR)BeaconDataExtract(&parser, NULL);// $3 | ||
if(lpswzHostName[0] == L'\0'){lpswzHostName = NULL;} | ||
if(lpswzDomainName[0] == L'\0'){lpswzDomainName = NULL;} | ||
|
||
if(!bofstart()) | ||
{ | ||
return; | ||
} | ||
|
||
if (lpswzDomainName == NULL && lpswzHostName != NULL) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the description all of the available arguments are listed as required If I give both a hostname and a domain name, SUCCESS. will be printed but nothing will happen. I'd split this into two aliases one to remove a user from a computer local group and one to remove it from a domain group. Then you can enforce this logic in the cna script easily. barring that the cna shouldn't list everything as required and should explain what is expected for local vs domain group deletion. |
||
{ | ||
BeaconPrintf(CALLBACK_OUTPUT, "Removing %S from %S\n", lpswzUserName, lpswzGroupName); | ||
dwErrorCode = DelUserFromDomainGroup(lpswzHostName, lpswzUserName, lpswzGroupName); | ||
if ( ERROR_SUCCESS != dwErrorCode ) | ||
{ | ||
BeaconPrintf(CALLBACK_ERROR, "Removing user from domain group failed: %lX\n", dwErrorCode); | ||
goto go_end; | ||
} | ||
} | ||
else if (lpswzHostName == NULL) | ||
{ | ||
BeaconPrintf(CALLBACK_OUTPUT, "Removing %S from local group %S\n", lpswzUserName, lpswzGroupName); | ||
dwErrorCode = DelUserFromLocalGroup(lpswzHostName, lpswzUserName, lpswzGroupName, lpswzDomainName); | ||
if (ERROR_SUCCESS != dwErrorCode) | ||
{ | ||
BeaconPrintf(CALLBACK_ERROR, "Unable to remove user to local group %lX\n", dwErrorCode); | ||
goto go_end; | ||
} | ||
} | ||
internal_printf("SUCCESS.\n"); | ||
|
||
go_end: | ||
printoutput(TRUE); | ||
bofstop(); | ||
}; | ||
#else | ||
#define TEST_USERNAME L"localadmin2" | ||
#define TEST_HOSTNAME L"" | ||
#define TEST_GROUPNAME L"Remote Desktop Users" | ||
#define TEST_DOMAIN L"WOOT" | ||
|
||
int main(int argc, char ** argv) | ||
{ | ||
DWORD dwErrorCode = ERROR_SUCCESS; | ||
LPCWSTR lpswzHostName = TEST_HOSTNAME; | ||
LPCWSTR lpswzUserName = TEST_USERNAME; | ||
LPCWSTR lpswzGroupName = TEST_GROUPNAME; | ||
LPCWSTR lpswzDomainName = TEST_DOMAIN; | ||
|
||
internal_printf("Removing %S from %S\n", lpswzUserName, lpswzGroupName); | ||
|
||
dwErrorCode = DelUserFromLocalGroup(lpswzHostName, lpswzUserName, lpswzGroupName, lpswzDomainName); | ||
if ( ERROR_SUCCESS != dwErrorCode ) | ||
{ | ||
BeaconPrintf(CALLBACK_ERROR, "Removing user from group failed: %lX\n", dwErrorCode); | ||
goto main_end; | ||
} | ||
|
||
internal_printf("SUCCESS.\n"); | ||
|
||
main_end: | ||
return dwErrorCode; | ||
} | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this memory should be freed using intFree()