lsof é um comando dos sistemas Unix que permite listar os descritores de arquivos abertos pelos processos em execução no sistema operacional. O nome do comando é abreviatura de “list open files” ou listar arquivos abertos. Só pode ser executado por um super usuário.
O comando lsof basicamente mostra os arquivos abertos no sistema. Entenda-se por arquivos abertos, os arquivos regulares, os diretórios, os links, arquivos de blocos e caracteres, bibliotecas compartilhadas, pipes, named pipes (FIFO), sockets de Internet, sockets do Unix e muitos outros. Além disso, o lsof associa a cada um desses arquivos outras informações úteis, como o processo que abriu tal arquivo, o dono do processo, arquivo descritor, etc.
Exemplos de uso:
A seguir listarei alguns exemplos de uso do comando e sempre que possível detalharei as opções usadas.
1 – Verificar qual processo abriu determinado arquivo
Você pode passar o nome de um arquivo para o lsof para descobrir quais processos manipulam tal arquivo:
# lsof /home/Agility/arquivo.txt
Um exemplo útil para atacantes é descobrir servidores de logs de um sistema:
# lsof /dev/log
2 – Descobrindo qual processo está travando um ponto de montagem
# lsof /media/4CB0-7B91
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bash 23040 daemonio cwd DIR 8,16 8192 1 /media/4CB0-7B91
Para desmontar com sucesso esta partição, os processos listados devem ser finalizados. Esse exemplo nos mostra como o diretório atual de um processo é importante, porque ele pode impedir um sistema de arquivos de ser desmontado. É por isso que processos que rodam em background (os daemons) sempre dão chdir() para o diretório root ou um diretório montando em / para que eles não travem a desmontagem de algum sistema de arquivo do usuário.
3 – Arquivos abertos por determinados processos
A opção -c filtra pelo nome de um processo:
# lsof -c lsof
Faz o mesmo que o comando seguir, porém de uma forma muito mais rápida:
# lsof | grep lsof # prefira o uso da opção -c por ser mais rápido
A saída mostra todos os arquivos abertos pelo processo lsof. O nome do processo não precisa ser completo, bastando apenas indicar o início do nome do mesmo.
Se vários processos são desejados, a opção -c pode ser usada mais de uma vez:
# lsof -c bash -c zsh
Nesse caso, a opção trabalha como um OU: tantos os arquivos do processo bash e do zsh foram mostrados. Para simular um AND, use a opção -a, como veremos mais à frente.
4 – Arquivos abertos por um usuário
A opção -u filtra os arquivos abertos por determinado usuário:
# lsof -u agility
O lsof é bastante livre e aceita o uso das opções ao mesmo tempo:
# lsof -u agility -c bash
A saída contém todos os arquivos do usuário agility e do processo bash. Para mostrar os arquivos que sejam do agility e do processo em questão, use a opção -a, que realiza um AND na entrada:
# lsof -a -u agility -c bash
5 – Negando padrões
As opções -u e -c, e muitas outras, podem receber um padrão negado, isto é, podemos obter os arquivos que não sejam de determinados usuários e processos.
# lsof -u ^assistec
Mostra os arquivos de todos os usuários, exceto os do usuário assistec.
Com a opção -p, filtramos os arquivos abertos por um processo de pid PID:
# lsof -p 1 # o PID 1 é do init
Vários PIDs podem ser separados por vírgula:
# lsof -p 1,4458,3396
E também negados:
# lsof -p ^1 # excluindo o PID do init
O comando lsof é um dos mais importantes comandos para quem administra sistemas Linux, principalmente na área de segurança. Este comando lista todos os arquivos abertos por todos os processos. Aqui quando eu falo arquivo, não são apenas arquivos comuns, mas sim recursos que funcionam como arquivos (podem ser abertos, mapeados na memória, entre outros). Isso inclui bibliotecas, sockets, arquivos comuns, diretórios e por aí vai. Em outras palavras, este comando nos fornece um mapeamento completo do que o programa está usando no sistema. Lembre-se que usando apenas o comando lsof, esta lista fica muito grande, pois mostra todos os arquivos de todos os processos.