Self-hosted service
lefayjey/linWinPwn avatar
lefayjey/linWinPwn

linWinPwn: a menu driven wrapper that puts a dozen Active Directory tools behind one prompt

linWinPwn is a bash script that streamlines the use of a number of Active Directory tools

2,224 stars311 forksShellMIT

At a glance

What is it?
A bash script that chains impacket, netexec, BloodHound, certipy and dozens of other tools into an interactive menu, with an enumeration only automated mode for scripted runs.
Who is it for?
linWinPwn's value is sequencing rather than capability. It does not implement a single exploit; it knows which of thirty or more installed tools to run in which order against which target, which is exactly the knowledge that a first-time operator lacks and a practised one has written down a hundred times.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 7, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the wrapper actually wraps

The repository is small on disk and large in scope. The tree holds a `Dockerfile`, an `install.sh`, the main `linWinPwn.sh`, a `helpers/` directory and a `MENUS.md` that documents the menu structure. That is the whole project, and it is a bash script plus its installer.

What the script wraps is a long list, given explicitly in the README's description: impacket, bloodhound, netexec, enum4linux-ng, ldapdomaindump, lsassy, smbmap, kerbrute, certipy, silenthound, bloodyAD and DonPAPI, described as many others. The functional breakdown the README gives covers four areas. Enumeration spans LDAP, RPC, ADCS, MSSQL, Kerberos and SCCM. Vulnerability checks cover noPac, ZeroLogon, MS17-010 and MS14-068. Object modifications cover password changes, group membership, RBCD and Shadow Credentials. Password dumping covers secretsdump, lsassy, nanodump and DonPAPI.

That division is the useful mental model. A single tool like netexec does many of these things, but not all, and not in the order that avoids wasting an hour. The wrapper's job is to notice that kerbrute spraying makes more sense after enumeration has produced a user list, and to sequence accordingly.

The project is MIT licensed, has 2,220 stars and 310 forks, and its last push was 2026-09-27 with zero open issues. The topic tags are the standard pentest vocabulary: active-directory, adcs, adsecurity, bloodhound, kerberoast, kerberos, mssql, sccm, pentest-tool.

Two modes, and why the automated one refuses to exploit

The script runs in one of two modes, and the distinction matters more than any individual check.

Interactive mode is the default. It opens a menu and lets you pick checks one at a time, which is the right mode when you are reading output and deciding what to try next. The usage line shows the full set of credentials it accepts in that mode.

bash
linWinPwn -t <Domain_Controller_IP> [-d <AD_domain> -u <AD_user> -p <AD_password> -H <hash[LM:NT]> -K <kerbticket[./krb5cc_ticket]> -A <AES_key> -C <cert[./cert.pfx]> -o <output_dir>]

Automated mode is entered with `--auto` and the README is explicit about its scope: enumeration only, with no exploitation, no modifications and no password dumping. That limit is what makes it reasonable to script.

bash
linWinPwn -t <Domain_Controller_IP> --auto [-o <output_dir>]

The checks also change based on what you supply. With no credentials at all, the unauthenticated pass runs anonymous enumeration across netexec, enum4linux-ng, ldapdomaindump and ldeep, a RID bruteforce via netexec, a kerbrute user spray, a Pre2k check against discovered computers, ASREPRoast over the collected user list with cracking attempted through john the ripper and rockyou, blind Kerberoasting, the CVE-2022-33679 exploit, a check for insecure DNS updates for AS-REQ abuse via krbjack, anonymous SMB share enumeration, and service enumeration for WebDav, dfscoerce, shadowcoerce and Spooler. It finishes with a sweep for ms17-010, zerologon, petitpotam, nopac, smb-signing, ntlmv1 and runasppl weaknesses.

Supply a password, NTLM hash, Kerberos ticket, AES key or pfx certificate and the authenticated pass takes a different route: DNS extraction through netexec, BloodHound data collection, a wider enumeration sweep including bloodyAD and SCCM tooling, a generated wordlist for cracking, and checks that only make sense with credentials, including ADCS extraction via certipy, targeted Kerberoasting, SMB share enumeration, the same service checks, MSSQL privilege escalation paths and MSSQL relay possibilities. A second vulnerability list appears here too, adding ms14-068, certifried, ldapnightmare and badsuccessor.

Flags that change the whole run rather than a single check

Most flags on this tool do not select a check, they change the conditions the whole run happens under, which is why the README groups them separately from the mode.

`--auto-config` runs NTP synchronisation against the target domain controller and adds an entry to `/etc/hosts` before the modules start. Both halves matter for Kerberos work, where clock skew causes authentication to fail in confusing ways and where the hostname has to resolve to the right address. `-I` or `--interface` picks the network interface, which is what you need when traffic should leave through a specific adapter such as a tunnel.

`--ldaps` switches from LDAP to LDAPS on port 636, and `--force-kerb` forces Kerberos authentication over NTLM where the protocol allows it. `--verbose` turns on all verbose and debug output, which you will want when something fails and not want otherwise.

Two flags are about scoping the target set. `--targets` accepts `DC`, `All`, an `IP=` value or a `File=` path to a server list, and the short form `-T` takes the same values.

bash
linWinPwn -t <Domain_Controller_IP> --targets All
linWinPwn -t <Domain_Controller_IP> -T File=./list_servers.txt

Finally, `-U` and `-P` take custom user and password wordlists, with the README's examples pointing at the xato-net ten-million lists under `/usr/share/seclists`. That matters because the default kerbrute spray assumes rockyou, which is a poor guess list for a corporate domain and one of the more common reasons an automated run finds nothing.

Why the README documents an SSH tunnel in detail

The tunneling section is the most unusual thing in the README and the reason some people use this script instead of the tools directly. The argument runs like this: on a Windows host you can attack from, the enumeration tools either do not exist or leave traces, because PowerShell commands land in the event log, files land on disk, and endpoint detection software notices. Running the same tools from a Linux machine over a tunnel avoids most of that.

The mechanics are a reverse SSH port forward opened from Windows, with proxychains on the Linux side doing the routing.

powershell
ssh.exe kali@<linux_machine> -R 1080 -NCqf

The Linux side needs a line added to `/etc/proxychains4.conf` pointing at `socks5 127.0.0.1 1080`, and then a wrapper command:

bash
linWinPwn_proxychains -t <Domain_Controller_IP>  -d <AD_domain> -u <AD_user> [-p <AD_password> -H <hash[LM:NT]> -K <kerbticket[./krb5cc_ticket]> -A <AES_key> -C <cert[./cert.pfx]>] [-o <output_dir>] [--auto]

The README frames this as being particularly useful when you have limited time inside a target environment, because you can enumerate from a remote laptop or VPS and collect evidence in one place. That is a real workflow advantage. It is also a technique with a legitimate footprint reduction motive, so the reasoning is not purely about evasion: fewer artefacts on the assessed machine means fewer false leads about who did what during the engagement.

The last thing the README covers is a support matrix, presented as a table, mapping each wrapped tool against null session, password, NTLM and other authentication methods. That table is the fastest way to see which of your credentials actually unlock the checks you care about.

The Docker image, and what the build actually installs

Three installation paths are documented. The native one is a clone and an installer run.

bash
git clone https://github.com/lefayjey/linWinPwn
cd linWinPwn
chmod +x install.sh
./install.sh

The Docker path is the one most people will actually use, and the image is published as `lefayjey/linwinpwn:latest`. The README goes further than a pull command and shows how to wrap it in a shell function so the long docker invocation becomes `linWinPwn_docker`.

bash
docker pull lefayjey/linwinpwn:latest
bash
docker run --rm --init -it --net=host -v $(pwd):/opt/lwp-output linwinpwn -t <DC_IP>

Two details in the Dockerfile explain the runtime behaviour. The base is `python:3.12-slim`, and the entrypoint checks whether stdin is a terminal: if it is, the script runs under `rlwrap` so the interactive menu has working arrow keys and history, and if it is not, it drops straight into the script with no line editing wrapper. That single conditional is what lets the same image serve both the menu and a scripted `--auto` run.

The build runs `install.sh` and nothing else in that layer, with the comment noting it caches all thirty or more tool installations, then copies the main script in a later layer so editing `linWinPwn.sh` does not invalidate the expensive layer. The system packages installed up front are the ones those tools need at compile time: build-essential, libsasl2-dev, libldap2-dev and libkrb5-dev for Kerberos, plus nmap, john, ntpsec-ntpdate, swig, jq, openssl, rlwrap and smbmap. Output is bind-mounted from `/opt/lwp-output` back to your working directory, and the image also creates `/opt/lwp-wordlists`.

What the repository does not settle

There are no releases. Not an old set, not any at all, which means the usual advice about pinning a version does not apply directly and you are pinning to a commit hash instead. The zero open issues and recent push date suggest the project is being worked on, but there is no changelog telling you what changed or when a check was added, so if a module misbehaves there is nothing to diff against.

The tools underneath change on their own schedules too. impacket, netexec and BloodHound each release frequently and occasionally change command syntax, and a wrapper that shells out to them inherits those breaks without a version pin of its own. That is the structural weakness of any shell wrapper and the reason the script is worth reading before running.

Scope is the other question. The description covers an unusually wide surface, from LDAP enumeration through SCCM and MSSQL relay to ADCS abuse, and the README does not say which of those paths are current practice versus legacy protocol exploitation. The presence of MS17-010 and MS14-068 in the check lists says the script keeps historical coverage, which is reasonable for a lab or an assessment where you do not know the vintage, and also means a run includes checks that no current domain will be vulnerable to.

The `helpers/` directory and `MENUS.md` are referenced but not described, so the menu structure is documented separately from the README and worth opening directly if you want to know what is selectable before you start.

Editorial conclusion

linWinPwn's value is sequencing rather than capability. It does not implement a single exploit; it knows which of thirty or more installed tools to run in which order against which target, which is exactly the knowledge that a first-time operator lacks and a practised one has written down a hundred times. Two decisions shape everything else. The default interactive mode presents a menu of individual checks so you can run one thing and look at it, while `--auto` restricts itself to enumeration and refuses to touch exploitation, modification or password dumping, which makes it defensible to run unattended on a client network. The Docker image exists for the second reason the README gives: running from Linux rather than from a Windows workstation leaves fewer artefacts on the box you are assessing. There are no tagged releases at all, so pin to a commit rather than a version, and read `linWinPwn.sh` and `install.sh` before you run either one, since both are large shell scripts with wide blast radius. The practical starting point is one interactive run against a lab domain controller, then a scripted `--auto` pass with an output directory you have somewhere to put.

Frequently asked questions

What is linWinPwn?

It is a bash script that wraps more than thirty Active Directory security tools, including impacket, netexec, BloodHound, certipy, kerbrute and DonPAPI, behind an interactive menu or an automated run.

Does the automated mode perform exploitation or password attacks?

No. The README states that `--auto` runs enumeration tools only, with no exploitation, no object modifications and no password dumping. Those capabilities are available through the interactive menu instead.

How do I supply credentials to linWinPwn?

Six methods are supported on the command line: a null session with no credentials, a password via -p, an NTLM hash via -H, a Kerberos ticket via -K, an AES key via -A and a pfx certificate via -C. The set of enabled checks changes depending on which one you supply.

Why would I run this from Docker over a tunnel?

Because running the tools from a Linux machine instead of the Windows host leaves fewer artefacts on the machine being assessed, such as PowerShell commands, event log entries and files on disk. The README shows an SSH reverse tunnel plus proxychains as the way to do it.

Does linWinPwn have releases or a version I can pin to?

No. The repository has no tagged releases at all, so pinning means choosing a commit. The last push was 2026-09-27 and the issue tracker is empty, which gives you activity but no changelog to compare against.

Can I supply my own wordlists?

Yes, with -U for users and -P for passwords, taking a path to a file. The README's examples point at the xato-net ten-million lists under /usr/share/seclists, which is worth doing since the defaults assume rockyou.

Official sources

  1. Issues
  2. lefayjey/linWinPwn on GitHub
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/lefayjey-linwinpwn.svg)](https://hysenlabs.com/projects/lefayjey-linwinpwn)