1

regex

I need to extract the IP address and file path from a Nessus report using text handlers such as Grep / Awk / Sed / Tr etc....

I've got the script to isolate the IP address and file path but I need to handle the text further and remove the "has not been patched remote version...."

192.168.1.1   - C:\WINDOWS\SYSTEM32\GPPREF.DLL HAS NOT BEEN PATCHED.    REMOTE VERSION : 6.2.9200.16384    SHOULD BE      : 6.2.9200.16859"

192.168.1.2 THE REMOTE HOST IS MISSING ONE OF THE FOLLOWING ROLLUP KBS :   - 4022719  - 4022722C:\WINDOWS\SYSTEM32\BCRYPT.DLL HAS NOT BEEN PATCHED.    REMOTE VERSION : 6.1.7601.23796    SHOULD BE      : 6.1.7601.23816"

192.168.1.3   - C:\WINDOWS\SYSTEM32\GPPREF.DLL HAS NOT BEEN PATCHED.    REMOTE VERSION : 6.2.9200.16384    SHOULD BE      : 6.2.9200.16859"

192.168.1.4   - C:\PROGRAM FILES\MICROSOFT SQL SERVER\MSSQL12.ACT7\MSSQL\BINN\SQLSERVR.EXE HAS NOT BEEN PATCHED.    REMOTE VERSION : 2014.120.5000.0    SHOULD BE      : 2014.120.5203.0"

So the end result should output the following from the above examples:

192.168.1.1 \WINDOWS\SYSTEM32\GPPREF.DLL

192.168.1.2 \WINDOWS\SYSTEM32\BCRYPT.DLL

192.168.1.3 \WINDOWS\SYSTEM32\GPPREF.DLL

192.168.1.4 \PROGRAM FILES\MICROSOFT SQL SERVER\MSSQL12.ACT7\MSSQL\BINN\SQLSERVR.EXE



My script so far:

!/bin/bash

*if [ "$1" == "" ]; then

echo "No file specified."

echo "Usage: nesparse [filename.csv]"

else

cat $1 | tr -d "\n" | tr "\r" "\n" | awk -F '","' '{ print $5,$13 }' | grep "has not been patched." | sort -u | awk '{ match($0,/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*[cC]:\\(.*) has.*/; ip=substr $0,RSTART,RLENGTH);print ipadd ip} '

*

The section of the code below handles the text to the examples above, with $5 printing the IP address and $13 printing the file path:

!/bin/bash

* if [ "$1" == "" ]; then

echo "No file specified."

echo "Usage: nesparse [filename.csv]"

else

cat $1 | tr -d "\n" | tr "\r" "\n" | awk -F '","' '{ print $5,$13 }' | 

grep "has not been patched." | sort -u *

The second awk pipe

* awk '{ match($0,/([0-9]+.[0-9]+.[0-9]+.[0-9]+).[cC]:\(.) has.*/ *

has the correct regex to match the output I need(see pic), but i'm having an issue with printing the regex'd output

Which is this line:

* ip=substr $0,RSTART,RLENGTH);print ipadd ip} ' *

Bonus point:

The IP regex matches any digit so 192.168.1.1 / 1.1.1.1 but its also matching against the version numbers in the above examples (2014.120.5203.0) ideally I need to modify this regex: * [0-9]+.[0-9]+.[0-9]+.[0-9]+ *

to restrict it to 0.0.0.0 --> 255.255.255.255

1
  • Your description of the problem conflicts with your example output. The only line where the filename is "dynamic" aren't listed in your output (the line about missing the rollup KBS), and neither is the one with with SQLSERVER.EXE. Are they supposed to be output? I've assumed they are because the question doesn't have any "dynamic" component if they aren't.
    – cas
    Aug 3, 2017 at 14:35

4 Answers 4

2

sed solution:

sed -E 's/^(([0-9]+\.){3}[0-9]+).*(C:\\.+) *HAS NOT BEEN PATCHED.*/\1 - \3/' reportfile
1
$ sed -E -n -e '/ HAS NOT BEEN PATCHED/ {
                  s/^(\[[^]]*\]).*([A-Z]:)/\1 - \2/;
                  s/ HAS NOT BEEN PATCHED.*//p}' nessus.log
[IP address] - C:\WINDOWS\SYSTEM32\GPPREF.DLL
[IP address] - C:\WINDOWS\SYSTEM32\BCRYPT.DLL
[IP address] - C:\WINDOWS\SYSTEM32\GPPREF.DLL
[IP address] - C:\PROGRAM FILES\MICROSOFT SQL SERVER\MSSQL12.ACT7\MSSQL\BINN\SQLSERVR.EXE

For every line that matches HAS NOT BEEN PATCHED, strip everything between the IP address and the first drive letter ([A-Z]:). The "IP Address" is defined as everything inside the square-brackets at the start of the line that isn't a close-square-bracket ([^]]*). Then strip everything from HAS NOT BEEN PATCHED to the end of the line, and print the modified line.

My recommendation would be to use a tab character \t as the field separator between IP Address and pathname instead of - (space,dash,space). That would make it easier to work with later.

The / HAS NOT BEEN.../ regexps include a space at the start to avoid leaving a dangling space character on the output.

0
 sed -rn '/NOT BEEN PATCHED/ {s/(^\[.*\]).*C:(.*) HAS.*$/\1 - \2/p} ' filename

Concentrate on the entries that have "NOT BEEN PATCHED" and then then pull out the sections of the string we require (in brackets), substituting the text for sections on and two ( the ip address and the filename)

I am assuming that the ip address is always going to be in square brackets here. If it isn't then you would need to pattern match for the IP address.

1
  • -r works but is deprecated. -E is the POSIX standard for extended regexps in sed. GNU & FreeBSD sed support -r (FreeBSD's man page says it does so for GNU compatibility). Mac OS sed doesn't support -r.
    – cas
    Aug 3, 2017 at 14:31
0

Awk solution:

awk '/HAS NOT BEEN PATCHED/ { match($0,/\[.*\]/);ipadd=substr($0,RSTART,RLENGTH);match($0,/C.* HAS/);fle=substr($0,RSTART,RLENGTH-4);print ipadd" - "fle }' filename

Pattern match against "HAS NOT BEEN PATCHED" and then extract the ip address and filename with awk's match function. Attain the subsection of the string that is related to the ip address and the file name using the returned RSTART and RLENGTH variables along with awk's substr function. Print the ipadd and fle variables created.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.