![열려 있는 모든 포트가 포함된 IP 목록을 인쇄하려면 awk를 사용하여 nmap 출력 파일을 구문 분석하세요.](https://linux55.com/image/107817/%EC%97%B4%EB%A0%A4%20%EC%9E%88%EB%8A%94%20%EB%AA%A8%EB%93%A0%20%ED%8F%AC%ED%8A%B8%EA%B0%80%20%ED%8F%AC%ED%95%A8%EB%90%9C%20IP%20%EB%AA%A9%EB%A1%9D%EC%9D%84%20%EC%9D%B8%EC%87%84%ED%95%98%EB%A0%A4%EB%A9%B4%20awk%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC%20nmap%20%EC%B6%9C%EB%A0%A5%20%ED%8C%8C%EC%9D%BC%EC%9D%84%20%EA%B5%AC%EB%AC%B8%20%EB%B6%84%EC%84%9D%ED%95%98%EC%84%B8%EC%9A%94..png)
명령을 사용하여 열려 있는 모든 포트가 포함된 IP 주소 목록을 찾고 싶습니다 awk
.
내 nmap 출력 파일은 다음과 같습니다.
# Nmap 7.01 scan initiated Sat Mar 18 06:27:08 2017 as: nmap -oG output.txt -T4 -f -iL iplist.txt
Host: 10.0.0.99 () Status: Up
Host: 10.0.0.99 () Ports: 135/open/tcp//msrpc///, 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds///, 514/filtered/tcp//shell///, 554/open/tcp//rtsp///, 10243/open/tcp//unknown///
Host: 192.168.0.1 () Status: Up
Host: 192.168.0.1 () Ports: 135/open/tcp//msrpc///, 139/open/tcp//netbios-ssn///, 445/open/tcp//microsoft-ds///, 10243/open/tcp//unknown///
Host: 192.168.0.101 () Status: Up
Host: 192.168.0.101 () Status: Up
# Nmap done at Sat Mar 18 06:29:02 2017 -- 3 IP addresses (3 hosts up) scanned in 113.19 seconds
예상 출력:
10.0.0.99 135
10.0.0.99 139
10.0.0.99 445
10.0.0.99 514
10.0.0.99 554
10.0.0.99 10243
192.168.0.1 135
192.168.0.1 139
192.168.0.1 445
192.168.0.1 10243
출력은 다른 파일(예:parse.txt)에 저장됩니다.
답변1
라고 물어보시 awk
겠지만 Perl에서는 정규식의 여러 일치 항목을 쉽게 반복할 수 있기 때문에 이것은 Perl과 관련하여 사소한 일입니다.
$ perl -ne '$host = $1 if /^Host: (\S+)/; while(m,(\d+)/open,g)
{ print "$host\t$1\n" } ' < nmap.out
10.0.0.99 135
10.0.0.99 139
...
perl -ne # Run the code for each input line
'$host = $1 if /^Host: (\S+)/ # If the line starts with "Host: ",
# save the next non-whitespace string
while( m,(\d+)/open,g ) { # Go through all matches of `<digits>/open`
# on the line, catching the digits
print "$host\t$1\n" # Print the saved hostname and the matched digits.
}'
답변2
이상한 방법:
$ awk -F'[/ ]' '{h=$2; for(i=1;i<=NF;i++){if($i=="open"){print h,$(i-1)}}}' file
10.0.0.99 135
10.0.0.99 139
10.0.0.99 445
10.0.0.99 554
10.0.0.99 10243
192.168.0.1 135
192.168.0.1 139
192.168.0.1 445
192.168.0.1 10243
-F[/ ]
입력 필드 구분 기호를 또는 공백으로 설정합니다 /
. 이는 호스트 IP $2
, 포트 번호 및 "open"이라는 단어가 해당 필드에 있음을 의미합니다. 따라서 행( )의 모든 필드를 반복하고 for(i=1;i<=NF;i++){}
현재 필드가 : 인 경우 open
호스트 이름과 이전 필드(포트)를 인쇄 할 수 있습니다 if($i=="open"){print h,$(i-1)}
.
답변3
여기서는 내 주장을 명확하게 표현할 수 없을 것 같습니다. 제가 강조하고 싶은 것은
piggyback
명시적인 루프를 사용하는 대신 정규 표현식 m//이 루프를 수행하도록 할 수 있다는 것입니다. 명확성을 위해 재구성된 정규 표현식은 다음과 같습니다.
perl -lne '
/^
Host: \s+ (\S+) \s+ # stuff $1 with hostname
.+?: # seek the nearest colon :
(?: # setup a loop
\s+(\d+)\/open\/\S+ # this pattern should repeat
(?{ print "$1\t$2" }) # print hostname+digits foreach turn
)* # (?{ CODE }) does a code execution during regex search
/x;
' yourfile