Start with Fundamentals
by J. Edward Durrett
The most important thing of any business is knowing what you have. You need to know how much cash is on hand and how much
inventory is on the shelf. You need to know who works for you and what they are supposed to be doing. When it comes to
Information Technology, and by extension Information Security, knowing what you have is also essential. You can not maintain
and protect things that you don't know you have. Just as it should raise suspicions to see a warehouse worker going
through filing cabinets in the accounting department, knowing what your software should and should not be doing is key to
proper security hygiene. If you don't know what software you have, how could you possibly know when it is, to return to
the human metaphor above, going through the filling cabinets in the accounting department?
Numerous security frameworks, regulatory requirements and best practice guidelines predominately declare that this is a must.
The CIS Critical Security Controls, NIST, PCI DSS, just t name a few, require and inventory of software   . In that
light, one would think that organizations have long ago adopted some type of inventory management into their Information
Technology / Information Security programs. In the past year, I have been to several organizations, both large and small, some
even household names, who do not have a functioning inventory program in place. The reasons given ranged from it being too
hard to not having enough money in the budget (or, put better, all the money was wasted on a license for a security solution
that doesn't work because there isn't an inventory).
Creating an inventory is not hard or expensive. Most of the tools to get a simple inventory of software are already embedded
in the operating system and can be scripted so that weekly or even daily inventories can be taken without user intervention.
Below I will show two methods for generating an inventory of installed software for *NIX systems. Of course, the same thing
could be done in power shell on Windows systems and sent to the same location or database. Since my expertise is with *NIX,
I'll stick to that lest I give bad Windows advice.
The first thing is to get the information into a central place. Keeping an inventory list on each client computer is of little
help. There are two approaches to this. The first is a call out method, where the central server calls the clients to get the
software inventory. The drawback to this approach is the central server must already know what devices are on the network and
where they are. Also, laptops and other devices which might not be on the LAN could be impossible to reach. And the last
drawback is the central server must authenticate to every client. That means either the the server must maintain
authentication credentials details for each client or use a single credential for all the clients.
Another method is the phone in method. In this case, the client sends an inventory to the central server. The clients can use
the same authentication credentials to the central server making it much easier to manage. Care must be taken to validate the
incoming data on the client side as well as to isolate the central inventory application from crucial systems. In deploying
clients, the script and key can be distributed at creation. This means an organization to start implementing a software
inventory as they roll out old clients and as they replace old clients. This makes the task of inventorying 30,000 clients
incremental and a lot easier to handle.
Obviously, by my choice of wording in the above paragraphs, I prefer the phone in method. However, everyone is different and
requirements vary to I will give examples of both the phone in and call out methods.
For the call out method, the server calls the client gets the inventory of software and either stores is in a file or pushes
it to a script to insert into a database:
Call out to a RHEL client creating a text file with the inventory:
ssh -i key_file user@client "yum list installed" > client.inventory.out
Call out to a RHEL client piping inventory into a script for adding to a database:
ssh -i key_file user@client "yum list installed" | my_database_script.py
Call out to a FreeBSD client:
ssh -i key_file user@client "pkg info" > client.inventory.out
Call out to a FreeBSD client piping inventory into a script for adding to a database:
ssh -i key_file user@client "pkg info" | my_database_script.py
Call out to a Debian client:
ssh -i key_file user@client "dpkg --list" > client.inventory.out
Call out to a Debian client piping inventory into a script for adding to a database:
ssh -i key_file user@client "dpkg --list" | my_dtatbase_script.py
Phone in from RHEL to some *NIX:
yum list installed | ssh -i key_file user@server "cat > client_inventory.out"
Phone in from RHEL to some *NIX and pipe into a script:
yum list installed | ssh -i key_file user@server "my_database_script.py"
Phone in from FreeBSD to some *NIX:
pkg info | ssh -i key_file user@server "cat > client_inventory.out"
Phone in from FreeBSD to some *NIX and pipe into a script:
pkg info | ssh -i key_file user@server "my_database_script.py"
Phone in from Debian to some *NIX:
dpkg --list | ssh -i key_file user@server "cat > client_inventory.out"
Phone in from Debian to some *NIX and pipe into a script:
dpkg --list | ssh -i key_file user@server "my_database_script.py"
Although these will produce the desired data for an inventory of software, managing it is highly dependent on the environment.
It is easy when all of the clients are homogeneous however when there are different systems with different requirements the
managing of the inventory becomes more complex. Also, relying on the package management system might overlook software
installed with out using the package management system like web applications. The above demonstrates the simplicity in
starting to go down the path of having a complete software inventory for all your systems. The complexities found once started
can be handled one by one and should not be barriers for not working toward a complete inventory.