Welcome to our

Cyber Security News Aggregator

.

Cyber Tzar

provide a

cyber security risk management

platform; including automated penetration tests and risk assesments culminating in a "cyber risk score" out of 1,000, just like a credit score.

Episode #180: Open for the Holidays!

published on 2014-12-31 12:00:00 UTC by Tim Medin @timmedin
Content:
Not-so-Tiny Tim checks in with the ghost of Christmas present:

I know many of you have been sitting on Santa's lap wishing for more Command Line Kung Fu. Well, we've heard your pleas and are pushing one last Episode out before the New Year!

We come bearing a solution for a problem we've all encountered. Ever try to delete or modify a file and receive an error message that the file is in use? Of course you have! The real problem is trying to track down the user and/or process that has the file locked.

I have a solution for you on Windows, "openfiles". Well, sorta. This time of year I can't risk getting on Santa's bad side so let me add the disclaimer that it is only a partial solution. Here's what I mean, let's look for open files:

C:\> openfiles

INFO: The system global flag 'maintain objects list' needs
to be enabled to see local opened files.
See Openfiles /? for more information.


Files opened remotely via local share points:
---------------------------------------------

INFO: No shared open files found.

By default when we run this command it gives us an error that we haven't enabled the feature. Wouldn't it be nice if we could simply turn it on and then look at the open files. Yes, it would be nice...but no. You have to reboot. This present is starting to look a lot like a lump of coal. So you need know that you will encounter the problem before it happens so you can be ready for it. Bah-Humbug!

To enable "openfile" run this command:

C:\> openfile /local on

SUCCESS: The system global flag 'maintain objects list' is enabled.
This will take effect after the system is restarted.

...then reboot.

Of course, now that we've rebooted the file will be unlocked, but we are prepared for next time. So next time when it happens we can run this command to see the results (note: if you don't specify a switch /query is implied):

C:\> openfiles /query

Files Opened Locally:
---------------------

ID Process Name Open File (Path\executable)
===== ==================== ==================================================
8 taskhostex.exe C:\Windows\System32
224 taskhostex.exe C:\Windows\System32\en-US\taskhostex.exe.mui
296 taskhostex.exe C:\Windows\Registration\R00000000000d.clb
324 taskhostex.exe C:\Windows\System32\en-US\MsCtfMonitor.dll.mui
752 taskhostex.exe C:\Windows\System32\en-US\winmm.dll.mui
784 taskhostex.exe C:\..\Local\Microsoft\Windows\WebCache\V01tmp.log
812 taskhostex.exe C:\Windows\System32\en-US\wdmaud.drv.mui
...

Of course, this is a quite long list. You can use use "find" or "findstr" to filter the results, but be aware that long file names are truncated (see ID 784). You can get a full list by changing the format with "/fo LIST". However, the file name will be on a separate line from the owning process and neither "find" nor "findstr" support context.

Another oddity, is that there seems to be duplicate IDs.

C:\> openfiles /query | find "888"
888 chrome.exe C:\Windows\Fonts\consola.ttf
888 Lenovo Transition.ex C:\..\Lenovo\Lenovo Transition\Gui\yo_btn_g3.png
888 vprintproxy.exe C:\Windows\Registration\R00000000000d.clb

Different processes with different files, all with the same ID. This means that when you disconnect the open file you better be careful.

Speaking of disconnecting the files, we can do just that with the /disconnect switch. We can disconnect by ID (ill advised) with the /id switch. We can also disconnect all the files based on the user:

C:\> openfiles /disconnect /a jacobmarley

Or the file name:

C:\> openfiles /disconnect /op "C:\Users\tm\Desktop\wishlist.txt" /a *

Or even the directory:

C:\> openfiles /disconnect /op "C:\Users\tm\Desktop\" /a *

We can even run this against a remote system with the /s SERVERNAME option.

This command is far from perfect, but it is pretty cool.

Sadly, there is no built-in capability in PowerShell to do this same thing. With PowerShell v4 we get Get-SmbOpenFile and Close-SmbOpenFile, but they only work on files opened over the network, not on files opened locally.

Now it is time for Mr. Scrooge Pomeranz to ruin my day by using some really useful, built-in, and ENABLED features of Linux.

It's a Happy Holiday for Hal:

Awww, Tim got me the nicest present of all-- a super-easy Command-Line Kung Fu Episode to write!

This one's easy because Linux comes with lsof, a magical tool surely made by elves at the North Pole. I've talked about lsof in severalotherEpisodesalready but so far I've focused more on network and process-related queries than checking objects in the file system.

The simplest usage of lsof is checking which processes are using a single file:

# lsof /var/log/messages
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd 1250 root 1w REG 8,3 13779999 3146461 /var/log/messages
abrt-dump 5293 root 4r REG 8,3 13779999 3146461 /var/log/messages

Here we've got two processes that have /var/log/messages open-- rsyslogd for writing (see the "1w" in the "FD" column, where the "w" means writing), and abrt-dump for reading ("4r", "r" for read-only).

You can use "lsof +d" to see all open files in a given directory:

# lsof +d /var/log
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd 1250 root 1w REG 8,3 14324534 3146461 /var/log/messages
rsyslogd 1250 root 2w REG 8,3 175427 3146036 /var/log/cron
rsyslogd 1250 root 5w REG 8,3 1644575 3146432 /var/log/maillog
rsyslogd 1250 root 6w REG 8,3 2663 3146478 /var/log/secure
abrt-dump 5293 root 4r REG 8,3 14324534 3146461 /var/log/messages

The funny thing about "lsof +d" is that it only shows you open files in the top-level directory, but not in any sub-directories. You have to use "lsof +D" for that:

# lsof +D /var/log
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd 1250 root 1w REG 8,3 14324534 3146461 /var/log/messages
rsyslogd 1250 root 2w REG 8,3 175427 3146036 /var/log/cron
rsyslogd 1250 root 5w REG 8,3 1644575 3146432 /var/log/maillog
rsyslogd 1250 root 6w REG 8,3 2663 3146478 /var/log/secure
httpd 3081 apache 2w REG 8,3 586 3146430 /var/log/httpd/error_log
httpd 3081 apache 14w REG 8,3 0 3147331 /var/log/httpd/access_log
...

Unix-like operating systems track open files on a per-partition basis. This leads to an interesting corner-case with lsof: if you run lsof on a partition boundary, you get a list of all open files under that partition:

# lsof /
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
init 1 root cwd DIR 8,3 4096 2 /
init 1 root rtd DIR 8,3 4096 2 /
init 1 root txt REG 8,3 150352 12845094 /sbin/init
init 1 root DEL REG 8,3 7340061 /lib64/libnss_files-2.12.so
init 1 root DEL REG 8,3 7340104 /lib64/libc-2.12.so
...
# lsof / | wc -l
3500

Unlike Windows, Linux doesn't really have a notion of disconnecting processes from individual files. If you want a process to release a file, you kill the process. lsof has a "-t" flag for terse output. In this mode, it only outputs the PIDs of the matching processes. This was designed to allow you to easily substitute the output of lsof as the arguments to the kill command. Here's the little trick I showed back in Episode 22 for forcibly unmounting a file system:

# umount /home
umount: /home: device is busy
# kill $(lsof -t /home)
# umount /home

Here we're exploiting the fact that /home is a partition mount point so lsof will list all processes with files open anywhere in the file system. Kill all those processes and Santa might leave coal in your stocking next year, but you'll be able to unmount the file system!

Article: Episode #180: Open for the Holidays! - published almost 10 years ago.

http://blog.commandlinekungfu.com/2014/12/episode-180-open-for-holidays.html   
Published: 2014 12 31 12:00:00
Received: 2021 06 06 09:05:29
Feed: Command Line Kung Fu
Source: Command Line Kung Fu
Category: News
Topic: Security Tooling
Views: 1

Custom HTML Block

Click to Open Code Editor