Profiling Python

# At the top of the file in global scope
# next to the imports
import cProfile as profile
pr = profile.Profile()

# right before the function call to profile

# right after the function call to profile
# Now save results to file, with
# This should only be called once, if in doubt
# place right before your program exits.

alternatively for a whole script file:

python -m cProfile -o profile.pstat

Within a terminal do:

pip install pyprof2calltree
pyprof2calltree -i profile.pstat -o script.calltree
kcachegrind script.calltree

Bypass chrome tls security checks

Normally things like invalid certificates throw an error within google chrome, and if the page has hsts in place, there is no way to bypass that.
For normal users this is a good thing, but if you’re the developer/admin and have logged out yourself because of a miss configured server or you’re a pentester and want to access the contents of a wrongly configured web server, this can be frustrating.

And there is a way to access the pages, even though it is not available in the normal google chrome version.
You need to use the selenium driver. Therefore in turn you need the WebDriver library and the chromedriver.

1. Download the latest WebDriver
2. Download the latest ChromeDriver (Keep in mind, that Version 2.10 is higher than 2.9)
3. Open PowerShell and import the WebDriver using “Import-Module” (or more specifically the correct dll for your installed .net version)
4. Unzip the chromedriver and place it inside of “./bin/selenium.chromedriver/”
5. Use PowerShell or C# to launch a new browser instance

$options = [OpenQA.Selenium.Chrome.ChromeOptions]::new()

Or use this script to install it inside of your current directory:

function Install-PSArchive {
    $null = Install-PackageProvider -Name PowerShellGet -Force -Scope CurrentUser
    Install-Module -Name 'Microsoft.PowerShell.Archive' -Force -Repository PSGallery -Scope CurrentUser -WarningAction SilentlyContinue

function Install-Selenium {
    param($ChromeSeleniumVersion = '2.45')
    Invoke-WebRequest -Uri '' -UseBasicParsing -OutFile './'
    Expand-Archive -Path ./ -Force
    $null = New-Item -Name './lib/selenium.webDriver' -ItemType Directory -Force
    Copy-Item -Path ./selenium.webDriver.nupkg/lib/netstandard2.0/WebDriver.dll -Destination ./lib/selenium.webDriver -Force
    Copy-Item -Path ./selenium.webDriver.nupkg/lib/netstandard2.0/WebDriver.xml -Destination ./lib/selenium.webDriver -Force
    Remove-Item -Recurse -Force -Path './selenium.webDriver.nupkg'
    Remove-Item -Recurse -Force -Path './'

    $ChromeSeleniumURLLinux = '{0}/' -f $ChromeSeleniumVersion
    $ChromeSeleniumURLMacOS = '{0}/' -f $ChromeSeleniumVersion
    $ChromeSeleniumURLWindows = '{0}/' -f $ChromeSeleniumVersion
    If ($IsWindows) {
        Invoke-WebRequest -Uri $ChromeSeleniumURLWindows -OutFile ''
    elseif ($IsLinux) {
        Invoke-WebRequest -Uri $ChromeSeleniumURLLinux -OutFile ''
    elseif ($IsMacOS) {
        Invoke-WebRequest -Uri $ChromeSeleniumURLMacOS -OutFile ''
    else {
        Write-Error -Message 'Platform not supported.'
    $null = New-Item -Name './bin/selenium.chromedriver' -Force -ItemType Directory
    Expand-Archive -Path '' -Force -DestinationPath ./bin/selenium.chromedriver
    Remove-Item -Recurse -Force -Path './'
    If ($IsLinux -or $IsMacOS) {
        chmod a+x ./bin/selenium.chromedriver/chromedriver

function Install-HtmlAgilityPack {
    Invoke-WebRequest -Uri '' -OutFile ./
    Expand-Archive -Path './' -Force
    $null = New-Item -Name './lib/HtmlAgilityPack' -ItemType Directory -Force
    Copy-Item -Path ./HtmlAgilityPack/lib/netstandard2.0/HtmlAgilityPack.dll -Destination ./lib/HtmlAgilityPack -Force
    Copy-Item -Path ./HtmlAgilityPack/lib/netstandard2.0/HtmlAgilityPack.xml -Destination ./lib/HtmlAgilityPack -Force
    Remove-Item -Force -Recurse -Path './HtmlAgilityPack'
    Remove-Item -Force -Recurse -Path './'

Import-Module -Name 'Microsoft.PowerShell.Archive'
Import-Module './lib/selenium.webDriver/WebDriver.dll'

## If you need to parse some html inside of your scripts and want to have cross platform functionality (or if internet explorer is not enabled), you also need to install HtmlAgilityPack, as powershell on windows relies upon it for parsing html into objects.
Import-Module './lib/HtmlAgilityPack/HtmlAgilityPack.dll'

Using Amazon Windows Images

If you tried to use some windows images on aws, you may have noticed, that they have no password specified. In fact, there agent fails to set one.

I’ve tried multiple ways to reset the password, after the support told me, that in order to help me I first need to buy a higher support level…

The one that was the simplest and easiest is usually the utilman.exe trick, but as aws does not allow to interact with the console session, this is out of scope.

So I’ve tried different autostart locations, but most are only invoked after a user has logged on.

Therefore mounting the volume on another instance and editing the registry to add a custom service was one possibility and it worked great.

What you need to do:

    1. Spawn one of the buggy instances and one of “2016 Base Datacenter”
    2. Start the buggy instance once, to check if amazon has fixed the bug to receive the admin password.
    3. If this bug is still there, stop this instance again (not terminate!)
    4. Go to volume and disconnect, and attach to the server 2016 server instance as ‘xvdf’
    5. Remote into the 2016 image as usual
    6. Open the disk manager
    7. Switch the 2nd drive online (and keep the window open for later)
    8. Open Regedit
    9. Load the System hive from the offline windows as ‘offline.SYSTEM’.
    10. Copy the following text into a text file a.reg on the desktop.
      Windows Registry Editor Version 5.00
    11. Apply this registry keys to the registry by double clicking it.
    12. Unload the hive
    13. Switch the drive offline again
    14. Make sure rdp from the buggy instance is only available from your ip (not before continuing.
    15. Detach the drive from the 2016 image.
    16. Attach the drive to the buggy image as ‘/dev/sda1’ (yes, it is windows, but you need to specify this here, or the instance is unable to start)
    17. Start the buggy instance.
    18. Connect to it with “Administrator” and “P@ssw0rd”
    19. Open Regedit and delete ‘HKLM\SYSTEM\ControlSet001\Services\test’
    20. Set a secure Password
    21. Install OpenSSH
    22. Add your public key to “C:/Users/Administrators/.ssh/authorized_keys”
    23. Remove the ports TCP-3389 and UDP-3389 from your security group. It is not recommended to have rdp publicly available to the internet (if you still want to connect over public set up a remote desktop gateway, as it is intended to be accessible publicly and in combination with ADFS allows onetime passwords for pre-authentication.

Hacking an SQL-Server

Basically if you’re admin you own everything.

So how would you access an SQL-Server if you don’t have SQL-Permissions but you’re administrator on the system the SQL-server is running on?

Basically you can abuse the fact, that the sql-server has to have at least one account with the necessary permissions. Often this is the local system user.

  1. So just become system using psexec (or anything else): psexec -s cmd.exe
  2. Search for your local SQL-Instance: osql -L
  3. Connect to your SQL-Server using your current (system) credentials: osql -S <InstanceName> -E
  4. If the connection is successful, just enable the sa account and set a new password for it. After that you can use the SQL-Management Studio to administer all permissions:
    /* Enable SQL-User authentication and set sa password */
    /* Reset the password, requires CONTROL SERVER permission */
    ALTER LOGIN sa WITH PASSWORD = '<newPassword>';
    /* just set sa password (alternative way)*/
    sp_password NULL, '<newPassword>', 'sa';
    /* To add an windows user to the admins role do this */
    EXEC sp_addsrvrolemember 'DOMAIN\USER', 'sysadmin';

    If the above is throwing an access denied error for you try a different user for example the mssql service user use process hacker to run a cmd prompt in the context of that user and try again. If also that fails, check if there is any application accessing the database that could have an account with too much permissions e. g. Server Admin instead of db_owner and try that one.

  5. If that all does not help, you have one last way of getting into the database, but that causes a downtime.
  6. Stop your SQL-Server Services (Server, Browser, Agent, …) and open an elevated cmd.
  7. Navigate to the folder containing the executable of the service and start it with the parameter “-m” for single user mode without authentication. After the server is back up do Step 4 and after that stop the server and restart the services you stopped earlier.


MMC and ServerManager is dead

This year on the Microsoft Ignite conference Microsoft announced the modern replacement for MMC and ServerManager.
It is called Honolulu:
Also Microsoft ranted about Admins using RDP for Administration. “It was never designed for it. Those admins should read the documentation. It states, it allows two channels only for emergency administration. But that problem will fix itself, as we discontinue the gui on servers. Also if you want to Administer GPOs for Windows 10 clients you have to do that form a Windows 10 client, as some settings are not available on a Server-Type OS.”
Also Microsoft once again urges Admins not to use Jump hosts, but instead Implement PAW (aka. SAW).
PAW (Privileged Admin Workstation) or SAW (Secure Admin Workstation) is an advanced security concept for admins.
It’s key features are:

  • Isolated Environments, day-to-day stuff like e-mail or webbrowser don’t have access to privileged sessions or applications. In fact they don’t know that those exist at all.
  • Does not need special hardware, it only needs a Computer with an TPM and uefi (and even those are not mandatory, but highly recommended)
  • At minimum two OSes running in parallel, recommended is one per tier.
    Credential Guard enabled
  • Windows Defender Application Guard enabled

Other things to consider:

  • Tier 0 Admins should be blocked access to Tier 1 and Tier 2 *¹
  • Tier 1 Admins should be blocked access to Tier 0 and Tier 2 *¹
  • Tier 2 (Workstation) Admins should be blocked access to Tier 0 and Tier 1 *¹
  • Only PAW/SAW allow local logon for Admins, but Applocker blocks Windows Logon for admins, so only UAC elevation works (windows hello with fingerprint for elevation, recommended).
  • LAPS should be installed everywhere
  • Recommended Applocker Rules Video 01:15:40 (only about 12 Rules)
  • Use IPSec, every client and every server should communicate over IPSec, so having physical access to the network is non compromising (works for everything after Windows 2000).
    Use Exploit Guard (former EMET)
  • IPSec with ESP and AH (IPv6) and IPSec with ESP for IPv4 if there is (or could be) a NAT
  • Use Device Guard for single purpose machines like ATMs, except if admins are bored (as high administrative effort is required)
  • Look at ESAE
  • Look at Protected Accounts
  • Disable RDP. Only use Remote Administration through WinRM (PowerShell), as that does not allow Credential Theft
  • Disable NTLM authentication for Shared folders (access by IP-Address), as NTLM makes Credential Theft easy.
  • Enable SMB Encryption (or IPSec), as requests can be intercepted otherwise.
  • Maybe add PIN auth to bitlocker in addition to TPM
  • Restrict outgoing Connections (also the destinations) using Windows Firewall (through GPO recommended)
  • Use Kerberos
  • Block Internet Access from Secure context, that requires:
    • Having an internal WSUS
    • Having an KMS for Windows (Re-)Aktivaton
    • Having an internal PowerShell Help-Server, to update PowerShell command help *²
    • Having an internal PowerShell Script and Modules repository *²
  • Use TOTP (RFC6238) for your APS.NET Core stuff 2nd video at 17:31
  • Don’t use SMS or E-Mail for Two Factor auth

Summary Talk about Security concerns

  1. Mastering the lions PAW: How to build a privileged access workstation | BRK3286
  2. Security and identity in ASP.NET Core | BRK3283

*¹: (Deny: “Access to computer from the network”, “logon as a batch job”, “log on as a service”, “log on locally”, “log on through terminal services”)
*²: Recommended for administrative support, by me.

Encrypted LVM remote unlock

Sometimes you want to have a strong Disk encryption but be still able to unlock it remotely. Sure, this is a compromise between security and usability, but here is what I come up with.
Before you follow my instructions, I allude you to carefully consider what that means for your thread model and system security.

0. You start with an normal lvm encrypted operating system.
1. Install dropbear and busybox
2. Edit the file /etc/initramfs-tools/initramfs.conf and add/modify Device and Network settings accordingly:

The last line requires some explanation. It consists of:
To bypass the ssh host checks (which would fail, because effectively the preboot environment is an autonomous os, independent of the other), you should select a different IP than that of the fully booted system.
3. Place your ssh-public key into the initramf’s root users home directory
rm /etc/initramfs-tools/root/.ssh/*
vi /etc/initramfs-tools/root/.ssh/authorized_keys

For privacy reasons (if you don’t want someone to associate this device with you through the use of your public key) you may want to use a separate key-pare, as this public key.
4. After you’ve added your public key, you need to regenerate the initramfs image using:
update-initramfs -u
5. After that reboot using
systemctl reboot
6. Now while the System is waiting for you to enter the password, go to a different client and connect using your private key (User: root) and your predefined IP address.
7. To unlock your device and continue booting (which will uninitialize the initramfs leaving you within a shell without any mounted file systems or applications) you have to somehow insert the Plain-text password into /lib/cryptsetup/passfifo (without a line break at the end)
The easyest (but also unsafest) way is a simple echo:
echo -n "EncryptionKey" > /lib/cryptsetup/passfifo

Install a VMWare ESXi 6.0 Hypervisor in a Hyper-V VM

Recently I’ve been playing around with the new Hyper-V Nested Virtualization feature within Windows 10 (build 10565 and greater) and Windows Server 2016. It is pretty cool to be able to creat…

Quelle: Install a VMWare ESXi 6.0 Hypervisor in a Hyper-V VM

Hyper-V Nested Virtualization

Part 1 – Prepare the ESXi ISO
Install VMWare PowerCLI:
Open PowerCLI
Download ESXi-Customizer PowerShell Skript: and place it in D:\ESXi-Hyper-V
Enter the following commands:

cd D:\ESXi-Hyper-V
.\ESXi-Customizer-PS-v2.5.ps1 -v60 -vft -load net-tulip

Part 2 – Create the Hyper-V VM
– Generation 1
– Startup Memory > 4096 MB
– Use Dynamic Memory for this Virtual Machine: $false
– Virtual Hard Disk: >10 GB
– Install an operating system from a bootable CD/DVD-ROM
– Image ile (.iso): select the in Part 1 generated iso
Now edit the Settings of the ESXi VM:
– Processor: 2
– Remove the “Network Adapter”
– Add a “Legagy Network Adapter”
– Select a Virtual Switch
– Save the settings

Part 3 – Enable Nested Virtualization
– Open PowerShell and write:

Import-Module Hyper-V;
Set-VMProcessor -VMName <VMName> -ExposeVirtualizationExtensions $true;
Get-VMNetworkAdapter -VMName <VMName> | Set-VMNetworkAdapter -MacAddressSpoofing On;

Part 4 – Boot ESXi Virtual Machine
– At the Bootscreen of the installation Media quickly press “Tab” and append “ignoreHeadless=TRUE” at the end of the Boot Options.
– Complete the setup process.
– Remove the installation disk and press “Enter” to reboot.

Part 5 – Configure the ESXi Boot Options:
– At the boot menue quickly press SHIFT+O and add the “ignoreHeadless=TRUE” Boot Option.
– After ESXi has started, press F2 and navigate to “Troubleshooting Options” => “Enable ESXi Shell”
– Press ALT+F1 to switch to the ESXi Shell
– Login to the shell
– Execute esxcfg-advcfg –set-kernel “TRUE” ignoreHeadless
– After that press STRG+D to logoff.
– Now press ALT+F2 to switch back to the GUI.
– Optionally turn off ESXi Shell.
– Esc out off the Options menu.

Now you have a fully funktional ESXi Host within a Hyper-V Virtual Machine. It should be noted, that this setup is not supported neither by VMWare nor by Microsoft.

iptables to rsyslog

log all dropped connections to syslog

iptables -N LOGGING
iptables -A INPUT -j LOGGING
iptables -A OUTPUT -j LOGGING
iptables -j LOG --log-prefix "iptables: "
iptables -A LOGGING -j DROP

check that this line is in /etc/rsyslog.conf

$ModLoad imklog

after that create the file /etc/rsyslog.d/01-iptables.conf with the content:

:msg, startswith, "iptables: " -/var/log/iptables.log
& ~
:msg, regex, "^\[ *[0-9]*\.[0-9]*\] iptables: " -/var/log/iptables.log
& ~

line 1 and line 3 are filters and log file locations, if they match the log is written to the specified log file.
line 2 and 4 tell rsyslog “don’t process future rules (if the one before matches), it’s done for this log entry”

now the only thing left is to create a log rotation rule
create the file /etc/logrotate.d/iptables with this content:

/var/log/iptables.log {
	rotate 7
		invoke-rc.d rsyslog rotate > /dev/null
		iptables-save >> /var/log/iptables.log