명령을 사용하여 열려 있는 모든 포트가 포함된 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