lsof -i 결과에서 명령의 전체 경로를 찾는 방법

lsof -i 결과에서 명령의 전체 경로를 찾는 방법

lsof훌륭한 유틸리티입니다. 이제 막 사용하기 시작했습니다.

lsof -i | grep smtp=> 다음과 같은 결과가 나옵니다.

httpd.pl  212548          global    3u  IPv4 893092369      0t0  TCP server07.host...blah...

위의 예에서는 httpd.pl스팸을 보내는 Perl 스크립트입니다.

명령의 전체 경로를 어떻게 알 수 있습니까? 즉, 위 결과에서, 전체 경로를 알고 싶습니다.httpd.pl

홈 디렉토리에서 검색을 시도했지만 파일이 httpd.pl존재하지 않습니다. 또한, 나는 그것을 시도했지만 lsof -p PID그것의 경로도 제공하지 않습니다.

이 파일의 전체 경로를 얻을 수 있는 방법이 있습니까?

참고: 이 문제는 공유 호스팅 환경에서 흔히 발생합니다. 따라서 공유 호스팅이나 웹 서버 관리자에게 매우 유용합니다.

답변1

lsof -i:$PORT첫째, grep을 통해 인터넷 주소가 주어진 $PORT 번호(또는 서비스 이름)를 사용하는 파일 목록을 선택할 필요가 없습니다 .

lsof -i:smtp

귀하의 경우에는 그것으로 충분합니다.

명령 이름을 이미 알고 있는 경우 lsof -c $COMMAND$COMMAND라는 명령을 실행한 프로세스의 파일 목록을 선택합니다. 예:

lsof -c httpd.pl

세 번째 개념: 프로세스의 PID를 알고 있으면 다음을 사용하여 전체 명령 경로를 얻을 수 있습니다.

ps -p $PID -o command

$PIDPID 번호는 어디에 있습니까?

따라서 lsof의 결과에서 명령의 전체 경로를 찾으려면 다음을 사용할 수 있습니다.

ps -p $(lsof -i:$PORT |awk 'NR>1 {print $2}' |sort -n |uniq) -o comm

또는

ps -p $(lsof -c $COMMAND |awk 'NR>1 {print $2}' |sort -n |uniq) -o comm

참고 1: awk, sort, uniq는 출력에서 ​​헤더 행을 건너뛰고 PID 번호별로 목록을 집계하는 데 필요합니다.

참고 2: $PORT를 사용하는 대상 포트가 여러 프로세스(예: https)에서 사용되는 경우 각 줄을 개별적으로 구문 분석해야 합니다.

for PID in $(lsof -i:$PORT |awk 'NR>1 {print $2}' |sort -n |uniq); do
  ps -p $PID -o comm
done

답변2

한 가지 방법은 프로세스에서 열린 파일을 확인하는 것입니다. FD열에 표시된 유형lsof:

FD         is the File Descriptor number of the file or:

               cwd  current working directory;
               ...
               txt  program text (code and data);

따라서 다음을 시도해 보십시오.

lsof -a -d txt -p 212548

스크립트의 경우 사용된 인터프리터의 경로가 표시됩니다(예 /bin/bash: ). 쉘 스크립트의 경우 스크립트 파일이 내 시스템의 fd 255에서 열리는 것처럼 보이지만 Perl 스크립트의 경우 출력에 스크립트 파일이 전혀 언급되지 않습니다 lsof.

답변3

httpd.pl,이름의 과정. 이는 프로세스가 마지막으로 실행한 파일의 기본 이름에서 초기화되지만 다른 방법으로 수정할 수 있습니다.

의 경우 perl다음 값을 할당하면 됩니다 $0.

$ perl -e '$0 = "httpd.pl"; sleep 10' & ps -fp $!
[2] 11954
UID        PID  PPID  C STIME TTY          TIME CMD
stephane 11954 31685  0 09:57 pts/8    00:00:00 httpd.pl

따라서 이것이 httpd.pl이와 같은 이름의 파일인지 아니면 다른 이름의 파일인지 알 수 없습니다. 다른 파일이나 표준 입력에서 perl전달된 코드를 사용하여 실행하는 것이 여전히 가능합니다.-e

Perl 코드가 이름이 지정된 파일(또는 기타 관련 파일)에서 httpd.pl로드되는 경우 perl해당 파일은 일반적으로 내용을 읽은 후 닫혀서 lsof -p PID.

스크립트가 실제로 perl인터프리터에 전달되고 Perl 코드가 이후에 프로세스 이름이나 매개변수를 수정하지 않는 경우 를 사용하여 명령줄 인수를 보면 단서를 얻을 수 있습니다 ps -fp PID.

그러면 매개변수로 전달된 파일 경로가 표시됩니다. 이는 상대 경로일 수 있으며, 이 경우 cwd해당 항목을 볼 수 있으며 lsof이는 스크립트가 현재 작업 디렉터리를 변경하지 않는 한 도움이 될 것입니다.

스크립트가 셸에서 실행되면 _환경 변수( grep -z '^_=' /proc/PID/environLinux의 경우)에서 경로(역시 상대 경로일 수 있음)를 찾을 수도 있습니다.

그럼에도 불구하고 스크립트는 시작 시 먼저 자체적으로 삭제될 가능성이 높습니다.

네가 원한다면바라보다이 코드의 경우 httpd.pl프로세스 메모리의 내용을 덤프하는 것이 더 좋습니다(Linux에서와 같이 gcoreattachment gdb또는 views /proc/PID/{maps,mem}). 그 안에 있는 코드를 찾아보세요.

예를 들어, #!NUL로 구분된 레코드를 찾으려면 다음을 수행하십시오.

perl -e '$p=shift;open MAPS, "/proc/$p/maps";
  open MEM, "/proc/$p/mem" or die "open mem: $!";
  for $m (grep !m{/|\[v}, <MAPS>){
    ($a,$b) = map hex, $m =~ /[\da-f]+/g;
    seek MEM, $a, 0 or die "seek: $!";
    read MEM, $c, $b - $a or die "read: $!";
    print $c
  }' PID | grep -z '#!'

원래 소스 코드가 더 이상 존재하지 않을 수도 있지만 YYMV입니다. 그런 다음 미리 컴파일된 코드를 찾아서 디코딩해야 합니다.

이 스택오버플로우 Q&A그러면 당신이 이 일을 하는 데 도움이 될 것입니다.

답변4

그 자체로는 lsof -i인터넷 정보만 나열합니다. 파일 정보를 추가하거나 표시할 수 있습니다.대신에) 이 -d옵션을 사용하세요. 예를 들어:

lsof -d txt | grep -E '/httpd.pl$'

프로세스가 실행 이름을 변경하지 않는 한 명령 이름은 로드된 실제 파일 이름과 일치하기 때문입니다.

물론 파일은 실행 가능해야 하지만 파일이 로드하는 공유 라이브러리도 실행 가능해야 합니다. 정말 병적인 경우에는 공유 라이브러리를 로드하는 스크립트(예: Python으로 작성)에서 프로그램을 실행하고 프로세스 목록에서 이름을 바꿀 수 있습니다.

CentOS 스레드에 따르면의심스러운 프로세스 httpd.pl, 자신을 호출하는 PHP 스크립트에서 시작되는 프로세스가 있습니다 httpd.pl.

관심있는 사람을 위해. 이것은 PHP 쉘에 의해 설치되는 백도어입니다. 첫 번째 청소 라운드에서는 이를 포착하지 못했습니다.

또 다른 스레드,CentOS 서버에서 실행되는 의심스러운 프로세스자세한 내용을 제공하세요.

httpd.pl은 Perl을 실행하는 스푸핑된 프로세스입니다.

이는 일반적으로 PHP 셸에 의해 설정된 백도어이며 웹사이트 어딘가에 로드됩니다.

추가 자료:

관련 정보