Skip to content

Commit d18caa0

Browse files
authored
Merge pull request #73 from noraj/windapsearch
add windapsearch
2 parents 20cfa65 + 71ced53 commit d18caa0

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# windapsearch
2+
3+
> Utility to enumerate users, groups and computers from a Windows domain through LDAP queries.
4+
5+
## Getting computer information
6+
7+
### Intro
8+
9+
The `computers` module can be used to enumerate all AD computers and the results can be saved as JSON with `--json`.
10+
11+
```
12+
$ windapsearch -d <domain> -u <user> -p <password> --dc <dc_ip> --module computers --json > scans/windapsearch_computers.json
13+
```
14+
15+
### Parsing results
16+
17+
Of course the text or JSON results can be used as is but:
18+
19+
1. Having the DNS hostname (`dNSHostName`) can be nice but having the IP address is important and `windapsearch` doesn't offer it because it's not a LDAP information, it has to be retrieved from the DNS server. Having the IP address can be useful to quickly understand in which VLAN the machine is.
20+
2. The AD is often bloated with old objects like computers that doesn't exist anymore. So `windapsearch` will retrieve a lot of computers that don't have a DNS hostname or have one but that can't be resolved since the DNS entry was removed. As an auditor/pentester we mostly care about computers that are existing and reachable, old entries is noise to us.
21+
22+
So here is a Ruby script that can:
23+
24+
- displays the same output as `windapsearch` (dns hostname, cn, dn, OS infos) but with the IP address(es) on top (`full` command)
25+
- displays only cn and ip address(es) (`cnip` command)
26+
- displays only computers with a resolvable DNS host name
27+
28+
```ruby
29+
require 'resolv'
30+
require 'json'
31+
32+
data = JSON.load_file('windapsearch_computers.json')
33+
34+
resolver = Resolv::DNS.new(nameserver: ['<dns_1>', '<dns_2>'], search: ['<domain>'], ndots: 1)
35+
36+
def getips(res, name)
37+
if name.nil? || name.empty?
38+
'none'
39+
else
40+
ips = res.getaddresses(name)
41+
if ips.empty?
42+
'none'
43+
else
44+
ips.join(', ')
45+
end
46+
end
47+
end
48+
49+
if ['cnip','full'].include?(ARGV[0])
50+
data.each do |computer|
51+
ips = getips(resolver, computer['dNSHostName'])
52+
unless ips == 'none'
53+
puts "cn: #{computer['cn']}"
54+
puts "ip(s): #{ips}"
55+
if ARGV[0] == 'full'
56+
puts "dNSHostName: #{computer['dNSHostName']}"
57+
puts "dn: #{computer['dn']}"
58+
puts "operatingSystem: #{computer['operatingSystem']}"
59+
puts "operatingSystemVersion: #{computer['operatingSystemVersion']}"
60+
puts "operatingSystemServicePack: #{computer['operatingSystemServicePack']}"
61+
end
62+
puts
63+
end
64+
end
65+
else
66+
puts "[+] Usage: <cnip|full>\n\n"
67+
puts 'cnip: displays only cn and ip address(es)'
68+
puts "full: same as cnip + dns hostname, dn, OS infos\n\n"
69+
puts 'Note: displays only computers with a resolvable DNS hostname'
70+
end
71+
```
72+
73+
`<dns_1>` and `<dns_2>` need to be replaced with the DNS servers IP address (often the DC) and `<domain>` with the search domain.
74+
75+
Example of output for one computer with the `full` command:
76+
77+
```
78+
cn: MACHINE1
79+
ip(s): 10.0.0.42
80+
dNSHostName: MACHINE1.example.org
81+
dn: CN=MACHINE1,OU=WSUS,DC=example,DC=org
82+
operatingSystem: Windows Server 2008 R2 Standard
83+
operatingSystemVersion: 6.1 (7601)
84+
operatingSystemServicePack: Service Pack 1
85+
```
86+
87+
Ref.:
88+
89+
- [THTT - windapsearch](https://trove.raw.pm/tools/windapsearch/)

0 commit comments

Comments
 (0)