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
$PID
PID 번호는 어디에 있습니까?
따라서 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/environ
Linux의 경우)에서 경로(역시 상대 경로일 수 있음)를 찾을 수도 있습니다.
그럼에도 불구하고 스크립트는 시작 시 먼저 자체적으로 삭제될 가능성이 높습니다.
네가 원한다면바라보다이 코드의 경우 httpd.pl
프로세스 메모리의 내용을 덤프하는 것이 더 좋습니다(Linux에서와 같이 gcore
attachment 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 셸에 의해 설정된 백도어이며 웹사이트 어딘가에 로드됩니다.
추가 자료: