nmap 출력을 grep하는 방법은 무엇입니까?

nmap 출력을 grep하는 방법은 무엇입니까?

나는 거대한 scan.gnmap파일을 가지고 있습니다 :

Host: 1.1.1.1 ()    Status: Up
Host: 1.1.1.1 ()    Ports: 80/open/tcp//http//nginx/, 443/open/tcp//ssl|http//nginx/    Ignored State: filtered (4998)
Host: 2.2.2.2 (foo.com) Status: Up
Host: 2.2.2.2 (foo.com) Ports: 80/open/tcp//http//awselb|2.0/, 443/open/tcp//ssl|http//Apache httpd 2.4.41 (() PHP|5.3.29)/ Ignored State: filtered (4998)
Host: 3.3.3.3 (bar.com) Status: Up
Host: 3.3.3.3 (bar.com) Ports: 25/open/tcp//smtp?///    Ignored State: filtered (4999)
Host: 4.4.4.4 ()    Status: Up
Host: 4.4.4.4 ()    Ports: 80/open/tcp//http//Microsoft-Azure-Application-Gateway|v2/, 443/open/tcp//ssl|https//Microsoft-Azure-Application-Gateway|v2/ Ignored State: filtered (4998)
Host: 5.5.5.5 (foobar.com)  Status: Up
Host: 5.5.5.5 (foobar.com)  Ports: 80/open/tcp//http?///, 443/open/tcp//ssl|https?///   Ignored State: filtered (4998)
Host: 6.6.6.6 ()    Status: Up
Host: 6.6.6.6 ()    Ports: 80/open/tcp//http//Microsoft IIS httpd 10.0/, 443/open/tcp//ssl|http//Microsoft IIS httpd 10.0/, 454/open/tcp//ssl|upnp//Microsoft IIS httpd/, 1221/open/tcp//http//Microsoft HTTPAPI httpd 2.0 (SSDP|UPnP)/, 4022/open/tcp//dnox?///, 4024/open/tcp//tnp1-port?///, 7654/open/tcp//unknown///   Ignored State: filtered (4993)

포트 번호를 추가하는 동안 모든 HTTP 서비스(포트 1221, 454 및 443의 서비스 포함)를 추출하려고 시도했지만 실패했습니다.

$ awk '/open/{print $2" "$5}' scan.gnmap | sed -e 's/\// /g' | awk '/http/{print $1":"$2}'

1.1.1.1:80
2.2.2.2:80
4.4.4.4:80
5.5.5.5:80
6.6.6.6:80

모든 HTTP 호스트:포트 조합을 추출하는 가장 쉬운 방법은 무엇입니까?

답변1

POSIX awk를 사용하여 요구 사항에 대한 가능한 설명은 다음과 같습니다.

$ cat tst.awk
BEGIN { OFS=":" }
{ ip = $2 }
sub(/^([^[:space:]]+[[:space:]]+){3}Ports:[[:space:]]+/,"") {
    n = split($0,f,/\/[^,]+(,[[:space:]]*|[[:space:]]*$)/)
    for (i=1; i<n; i++) {
        port = f[i]
        if ( !seen[ip,port]++ ) {
            print ip, port
        }
    }
}

$ awk -f tst.awk file
1.1.1.1:80
1.1.1.1:443
2.2.2.2:80
2.2.2.2:443
3.3.3.3:25
4.4.4.4:80
4.4.4.4:443
5.5.5.5:80
5.5.5.5:443
6.6.6.6:80
6.6.6.6:443
6.6.6.6:454
6.6.6.6:1221
6.6.6.6:4022
6.6.6.6:4024
6.6.6.6:7654

awk가 문자 클래스를 지원하지 않아 POSIX와 호환되지 않는 경우 모든 것을 및 [[:space:]]으로 변경하세요 [ \t].[^[:space:]][^ \t]

답변2

#!/usr/bin/perl
use strict;

while(<>) {
  next unless m/^Host: ([0-9.]+) .* Ports: (.*)(?:\s+Ignored.*)?/;
  # $1 and $2 are the values from the capture groups in the previous regex
  my ($ip, $ports) = ($1, $2);

  # split $ports into array @ports
  my @ports = split /,\s+/, $ports;

  # iterate over the array and output the IP and port number only when http appears
  foreach (@ports) {
    next unless s=^(\d+)\/.*http.*=$1=;
    printf "%s: %s\n", $ip, $_;
  };
}

예를 들어 다른 이름으로 저장 grep-http-ports.pl하고 다음과 같이 실행합니다 chmod +x grep-http-ports.pl.

$ ./grep-http-ports.pl scan.gnmap 
1.1.1.1: 80
1.1.1.1: 443
2.2.2.2: 80
2.2.2.2: 443
4.4.4.4: 80
4.4.4.4: 443
5.5.5.5: 80
5.5.5.5: 443
6.6.6.6: 80
6.6.6.6: 443
6.6.6.6: 454
6.6.6.6: 1221

콜론 뒤의 공백은 :선택 사항입니다. 제 생각에는 그들은 그것을 더 "사람이 읽을 수 있게" 만듭니다. 그러나 마음에 들지 않거나 다른 스크립트를 사용하여 추가 처리를 위한 출력인 경우 printf형식 문자열을 편집하여 제거하면 됩니다.


호스트 이름도 추출하려면 다음과 같이 쉽게 수행할 수 있습니다.

#!/usr/bin/perl
use strict;

while(<>) {
  next unless m/^Host: ([0-9.]+) \(([^)]*)\).* Ports: (.*)(?:\s+Ignored.*)?/;
  my ($ip, $host, $ports) = ($1, $2, $3);

  my @ports = split /,\s+/, $ports;

  foreach (@ports) {
    next unless s=^(\d+)\/.*http.*=$1=;
    printf "%s:%s:%s\n", $ip, $host, $_;
  };
}
1.1.1.1::80
1.1.1.1::443
2.2.2.2:foo.com:80
2.2.2.2:foo.com:443
4.4.4.4::80
4.4.4.4::443
5.5.5.5:foobar.com:80
5.5.5.5:foobar.com:443
6.6.6.6::80
6.6.6.6::443
6.6.6.6::454
6.6.6.6::1221

또는 각 IP 주소와 포트 번호를 쉼표와 공백으로 구분하여 한 줄에 입력합니다.

#!/usr/bin/perl
use strict;

while(<>) {
  next unless m/^Host: ([0-9.]+) .* Ports: (.*)(?:\s+Ignored.*)?/;
  my ($ip, $ports) = ($1, $2);

  next unless $ports =~ m/http/;
  my @ports = split /,\s+/, $ports;

  my @http = ();
  foreach (@ports) {
    next unless s=(\d+)\/.*http.*=$1=;
    push @http, $_;
  };

  printf "%s: %s\n", $ip, join(", ", @http);
}
$ ./grep-http-ports2.pl scan.gnmap 
1.1.1.1: 80, 443
2.2.2.2: 80, 443
4.4.4.4: 80, 443
5.5.5.5: 80, 443
6.6.6.6: 80, 443, 454, 1221

마찬가지로 콜론과 쉼표 뒤의 공백은 선택 사항입니다. 필요에 따라 printf형식 문자열과 문자열을 편집합니다.join

관련 정보