Tips for an Information Security Analyst/Pentester Career - Ep. 100 - Anatomy of an Internal Pentest (Checklist and Lessons Learned)
Thanks to my buddy Aqeeb Hussain for finding the time to peer review my stuff on a Sunday night!
Guys, this series has finally made it to the number 100 post, I find it hard to believe it myself!
I long debated on what topic this post should discuss, and I returned on an idea that's been going through my mind for a while: Analyzing how to run an internal pentest from start to finish, alongside best practices and lessons learned over the numerous (8 to be exact) years attacking & hardening Active Directory environments for clients. I wanted to invent a list of guidelines, followed by a checklist which can be used for reference.
Sorry, it took me a while to bring this post to you, but this is the special 100 and it needed the right amount of effort! Whilst I do believe in the potential which AI has brought to many content creators, I like to gear my writing to be original and authentic, albeit it takes a while; it's a true reflection of me as an author and the writer of this series.
START - NETWORK RECONNAISSANCE
- Request password policy: Understanding the client's password policy empowers specific password spraying attacks, subsequently decreasing the likelihood of causing a mass account lockout. Therefore, I'm going to provide experience-based tips.
- Find domain name: I run two different types of AD tests, depending on where the client provides me with a scope (comprehensive tests) or no scope is supplied and it's left up to me to target all I can find (targeted tests). Each test has its rationale, but I prefer targeted tests, because of their challenging nature (no Nessus, all manual testing), naturally resembling the actions/steps taken by an adversary.
- AD Domain Identification: Regardless of the test type, we need to identify the AD domain. In fact, the client's AD domain isn't always the same as the client's external domain. In other words, if the external domain is acme.com, the AD domain can be the same as the former or different (e.g. acme.local), so making assumptions can be problematic to the host discovery phase here. My go-to tool for this scenario is NMAP's broadcast-dhcp-discover NSE script. The example below is from NMAP’s official documentation.
![]() | |||||
Output from NMAP Script |
- Find domain controller IP:
Anyhow, a foolproof method to discover the DC IP is to check whether TCP port 88, associated with Kerberos authentication, is open. This can be simply done through netcat (nc -nv $DC-IP 88), as shown in this example from my test lab.
![]() |
DC IP Found through netcat |
- Initial Host Discovery: The first step being host discovery, which can be conducted using the ARP protocol. This step can be very effective for networks which are not segmented into various VLANs, allowing discovery of all running hosts. The syntax would be as follows: arp-scan -l (Network interface). With some use of Linux power tools, we can retrieve a list of hosts which can then feed into further scans to support profiling and service/version detection.
- Nmap discovery and profiling scans: The first step is host discovery, which will identify live in-scope hosts. i.e. hosts which contain listening services, exposing open ports. With a list of live hosts, we now need to know what services they run (and especially service version(s) are in use), to tailor our attacks, so we move to the “services profiling stage”. For this purpose, especially for a high number of live hosts, I tend to scan specific ports, hosting potentially interesting services. An example of a scan I’d use is as follows:
With this information, we need to identify what hosts don’t enforce SMB signing, especially for targeted tests (for comprehensive tests, Nessus often identifies this specific vulnerability right away). The easiest way to do this is to leverage the smb-security-mode Nmap script. This information is needed to perform a relay attack through Responder + impacket-ntlmrelayx.
- Username Enumeration: As part of the enumeration phase, discovering usernames is a crucial and key step which can be executed in various ways. One method is to run a passive network sniffer (and credential grabber) Responder. Responder not only gives you a username you might need to authenticate to the target AD domain, but also provides their NTLMv2 credential hash which can be used to crack offline or with tools such as ntlmrelayx.
- Username enumeration: it’s now time to try finding valid AD accounts. Though this can be done in multiple ways, my favorite strategy leverages ldapnomnom along with statistically likely usernames. An example command for a Hack The Box machine is shown below.
![]() |
Username Enumeration |
- AD FOOTHOLD STRATEGIES: The previous stage leads us to a list of valid AD accounts, so the next logical step is to either find a password for at least one of them, or attempt to relay the existing credentials using relaying tools such as mitm6 or ntlmrelayx. Upon recovering a password, additional enumeration pathways and potential privilege escalation vectors can be unlocked.
- AS-REP-ROAST Attack: We don’t need a password to run this attack, we can leverage a script named impacket-GetNPUsers from the Impacket Framework. If we can find at least one user configured with no Kerberos pre-authentication, we can grab their password hash and attempt cracking it offline with either John the Ripper or Hashcat depending on your setup being CPU or GPU intensive. The chances to recover the plaintext password are dependent upon the client’s password policy, because the stronger it is, the less our chances of success. As a result of that and as a general rule, don’t sit on your hands waiting for the hashcat results, always keep the ball rolling by exploring other attack and enumeration pathways.
- Man-in-the-Middle Attacks: If LLMNR/NBT-NS protocols are enabled, as it can be in the majority of networks I’ve tested,we can leverage a vulnerability that makes them susceptible to MitM attacks. In other words, we can poison a connection request from a domain-joined computer communicating with the domain controller, redirecting it to our attacking computer through the use of Responder. In consequence, we can grab a NetNTLMv2 password hash for the user which performed the connection attempt. If we get lucky, we can relay the hash to other computers hosting SMB shares without enforcing SMB signing. Alternatively, if relaying is not an option, we can resort to attempt cracking the hash offline.
This attack can potentially allow us to progress, but may require multiple attempts to succeed and has the potential to cause network disruptions. Therefore, it would be courteous and recommended to give your client a heads up before doing so. On the other hand, a consultant must use their best judgment to decide whether the client should be contacted with the interest of time being a key factor. The last thing you need is causing your testing activities to become stuck due to waiting for client input.
These situations should always be avoided, especially if the client has not demonstrated a responsive attitude to your communications during the pre-sales, scoping and authorization stages of the assessment. Alternatively, another tool that can be used for MitM attacks is mitm6, leveraging an alike vulnerability with IPv6 and the DHCPv6 protocols by spawning a rogue DNS/DHCP server using the IPv6 protocol. Since Windows gives IPv6 addressing priority by default, the use of mitm6 causes all users on the network to use your attacking device for communications to the domain controller, allowing for potential capture of valuable information stored on the target domain.- Password Spraying Attacks: We can use a tool like kerbrute to try common passwords against the initial list of users we were able to enumerate. Once again, it’s a matter of luck, even though some OSINT on the client may suggest potential password patterns we could attempt. Other than during this initial stage, password spraying can be conducted to test for password reuse, hoping for an administrator account to use a weak password we discovered. A word of advice: this tool can lead to large scale AD account lockouts if used recklessly, as I have learned firsthand through experience. To minimize potential issues, make sure to always use the --safe option to suspend the attack when an account comes back as locked, reduce the number of threads (-t4 or -t2 are a safe choice) and to enable verbose output (--verbose). Also, it might be more prudent to spray small groups of users instead of all of them at the same time.
- Enumerate SMB Shares (Null Sessions): If we can enumerate SMB shares without authentication, we could find some interesting files containing cleartext credentials or other useful information. We can do that through NetExec and MANSPIDER. The latter tool also allows you to search for specific keywords of interest.
- Mountable NFS Shares: Same considerations as above apply here, provided the NFS shares can be mounted to the local filesystem through the mount command. Potential NFS shares and associated permissions can be enumerated via NMAP and the showmount binary using the -e switch.
- Web Services Recon: Time to analyze what’s running on web ports, using EyeWitness. If we can find network printers or multi-function devices accepting default administrative credentials, we might be in luck. In fact, if such devices support LDAP and this protocol is configured using a domain account and a hardcoded password, we could conduct a pass-back attack and recover the password in cleartext. All we need to do is edit the configuration, change the IP address for the DC to our IP, and then run a connection test. This is a very common attack vector. As a matter of fact, these devices are often configured with standard or no credentials in the name of convenience, because they were installed and forgotten or because internal security tends to be an afterthought compared with perimeter security due to being largely inaccessible from the outside thanks to core network designs such as NAT.
Other than this, web applications can sometimes be accessed with default credentials and contain user account information or other sensitive data that can be leveraged for a foothold. One notable case is associated with a version of Jenkins accepting standard credentials or configured without authentication, but there can be so many different scenarios that manual testing is absolutely compelling, and we can’t fit all possible attack vectors in this post. In other words, enumerate, enumerate, enumerate! - Web Directory Enumeration: Web apps can sometimes include pages containing useful information, so it can be worth enumerating the robots.txt file and other important directories. My go-to tools for this are gobuster and dirsearch.
- Anonymous FTP: FTP servers can sometimes allow anonymous login and enable an attacker to recover sensitive files. It’s something you need to try but has a low likelihood of being successful, in my experience.
- RCE Vulnerabilities: During internal pentests, it’s not so uncommon to identify remote code execution vulnerabilities rated as critical or high, often originated from missing security patches or unsupported versions of Windows and/or other software (such as ETERNALBLUE, BlueKeep, PrintNightmare, PetitPotam, etc.) allowing an unauthenticated user to fully compromise the target host(s). At a first look, these situations could seem to be very promising, as some of these issues could allow an attacker to obtain SYSTEM access to the target hosts, however not so fast.
- Can the exploit cause disruptions to the client’s operation? Some of the exploits for the specific vulnerabilities mentioned above are known to cause crashes. Regardless, for lesser-known exploits, we can’t exclude that this could happen as well and we don’t know if the affected hosts are strategic to the client’s business, so our best option is to document the vulnerability through an auxiliary module or the check functionality of the exploit (when supported by the specific Metasploit module) and contact the client for guidance. The client might be comfortable with an exploitation attempt or not but never skip this step, if you don’t want to end up a creek without a paddle!
- Is it worth running it for the target hosts? Sometimes the vulnerable hosts aren’t even domain-joined, because they’re located in kiosks or other isolated workstations. In these cases, compromising the target host(s) would lead nowhere and IMHO risks overweight benefits. So, I report the vulnerability right away, but I don’t even ask the client for authorization to exploit it, as I could perform no lateral movements afterward anyway. Another scenario that can lead to the same conclusion is when some situations causing tensions or contention with the client, like crashes, account lockouts or network disruptions have occurred during the test, so you want to avoid any further problems that could impact the client’s experience.
- Ask the Client for Credentials: I consider this as the last resort, and I treat it a lot like a personal defeat, but sometimes you need to swallow your pride and ask the client for a standard AD user account to conduct further testing as part of the assessment, to provide more value in the remaining time of the testing window.
I believe demonstrating a vulnerability which allows you to get an AD foothold totally on your own adds more value but sometimes you can run out of choices. When the client does most things right, a tester might not be able to access the usual attack vectors granting a foothold. For example, disabling LLMNR and other vulnerable protocols whilst monitoring alternative communication protocols such as IPv6 for malicious activity would greatly reduce the attack surface but, even without going that far, adopting a strong password policy would go a long way. In fact, even grabbing password hashes leads you nowhere if the client uses a 12+ -character password policy.
AUTHENTICATED ATTACKS / DEEP DOMAIN ENUMERATION / PRIVILEGE ESCALATION
- Deep Domain Enumeration: With valid credentials, we can now use various tools such as: BloodHound Legacy, BloodHound CE, PlumHound and ldapdomaindump to conduct further enumeration and analyze potential privilege escalation vectors. Ideally, we want to enumerate all domain users and associated groups in order to identify any opportunity of gaining domain or enterprise administrator access across the Active Directory estate. We also want to further enumerate available SMB shares leveraging the credential provisioned, especially when null sessions aren’t supported.
AUTHENTICATED ATTACKS
- Kerberoasting: We can now conduct an attack against the Kerberos authentication protocol known as Kerberoasting. If successful, the attack allows all users on the AD environment to retrieve the password hashes for affected Active Directory account(s) which have an SPN (Service Principal Name) associated to them.
PRIVILEGE ESCALATION
- Active Directory Certificate Services (AD CS): These services can be subjected to multiple vulnerabilities allowing a domain user or a domain machine account to request a certificate for any other user or machine account, including domain administrators, allowing for an opportunity of privilege escalation from a domain user to an administrator. Depending on the specific AD configurations, there can be multiple additional privilege escalation vectors, so many that cover all of them here is impossible.
CONCLUSIVE THOUGHTS
A point that’s often misunderstood is the escalation of one’s privilege from a standard user to domain/enterprise administrator is not always the ultimate goal of an internal pentest or the most effective outcome to discuss during the reporting stage. Alternatively, a strong focus towards accessing sensitive and confidential data on the internal network and explaining the potential business impacts of a live incident is far more beneficial to the client.
I previously reviewed a report which exemplifies the above point very effectively. The tester had captured a password hash belonging to a domain administrator and, as it happened to be associated with a weak password, the tester could collect the cleartext password which was cracked, and log on to the DC as an administrator; but that was it. The tester demonstrated no impact such as retrieval of confidential information with administrative access. On the contrary, I was sometimes unable to gain DA (Domain Administrator) access, yet found plenty of confidential data stored in cleartext across the network that the client was not at all concerned about that.
I have developed more experience dealing with this concept recently, but I refuse to hide that being unable to escalate my privileges had certainly caused me a lot of frustrations over my time as a penetration tester!
Conclusively, we have reached the end of this journey of post 100: From Zero to DA. if you got this far, I hope you learnt one thing or two along the way.
I hope you enjoyed the trip!