열려 있는 모든 포트가 포함된 IP 목록을 인쇄하려면 awk를 사용하여 nmap 출력 파일을 구문 분석하세요.

열려 있는 모든 포트가 포함된 IP 목록을 인쇄하려면 awk를 사용하여 nmap 출력 파일을 구문 분석하세요.

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

관련 정보