《bash网络安全运维》 第六章

提取分析数据

awk

awk 不仅是一个命令,而且实际上是一种用于处理文本的编程语言。
常见命令选项:

  • -f:从指定的文件读入 awk 程序。

例:
awkusers.txt

Mike Jones
John Smith
Kathy Jones
Jane Kennedy
Tim Scott

使用 awk 打印用户的姓氏为 Jones 的每一行:

awk '$2 == "Jones" {print $0}' awkusers.txt 

awk 将遍历输入文件的每一行,将每一行单词读入字段。字段 $0 表示整行—— $1 表示第一个单词,$2 表示第二个单词,等等。awk 程序由模式和模式匹配时要执行的相应代码组成。我们检查 $2,看看这个字段是否是 Jones 。如果等于,awk 将运行程序大括号内的代码。
使用正则表达式也可以达到这个目的,两个斜杠之间就是正则表达式,不过注意,这种写法会匹配 Jones 是用户名称或较长名称的一部分的行。

awk '/Jones/{print $0}' awkusers.txt

join

join 组合有两个文件中有公共字段的行。为了使 join 正常工作,输入的文件必须事先排好序。
常见命令选项:

  1. -j:使用指定的字段号连接。字段号从 1 开始。
  2. -i:指定要用作字符分隔符的字符。空格是默认的字段分隔符。
  3. --header:使用每个文件的第一行作为标题。

示例:
usernames.txt

1,jdoe
2,puser
3,jsmith

accesstime.txt

0745,file1.txt,1
0830,file4.txt,2
0830,file5.txt,3

这两个文件都有一个公共的数据字段,即用户 ID。使用 join 合并这两个文件:

pwnki@LAPTOP-KETPO6R7:~/project/diliu$ join -1 3 -2 1 -t, accesstime.txt usernames.txt
1,0745,file1.txt,jdoe
2,0830,file4.txt,puser
3,0830,file5.txt,jsmith
pwnki@LAPTOP-KETPO6R7:~/project/diliu$

选项 -1 3 告诉 join 使用第一个文件的第三列,-2 1 告诉 join 使用第二个文件的第一列进行合并,选项 -t ,指定逗号字符作为字段分隔符。

sed

sed 允许你进行编辑操作,例如,替换数据流中的一些字符。
常见命令选项:

  1. -i:编辑指定的文件并进行覆盖。

示例:
ips.txt

ip,OS
10.0.4.2,Windows 8
10.0.4.35,Ubuntu 16
10.0.4.107,macOS
10.0.4.145,macOS

使用 sed 将 IP 地址是 10.0.4.35 的所有实例替换为 IP 地址为 10.0.4.27 的示例:

 pwnki@LAPTOP-KETPO6R7:~/project/diliu$ sed 's/10\.0\.4\.35/10.0.4.27/g' ips.txt
ip,OS
10.0.4.2,Windows 8
10.0.4.27,Ubuntu 16
10.0.4.107,macOS
10.0.4.145,macOS

sed 使用以下格式,每个组件之间用正斜杆分隔:

s/<regular expression>/<replace with>/<flags>/

第一部分 s 告诉 sed 进行替换操作;第二部分是一个正则表达式模式。第三部分是用来替换匹配的正则表达式模式的值。第四部分是可选标志,g 告诉 sed 替换与正则表达式模式匹配的所有实例。

tail

tail 命令用于输出文件的最后几行。默认情况下,tail 将输出文件的最后 10 行。
常见命令选项:

  1. -f:在文件不断添加数据行时,持续监测文件并输出文件中的数据行。
  2. -n:输出指定的行数。

示例:
输出 somefile.txt 文件中的最后一行:

tail -n 1 somefile.txt

tr

tr 命令用于从一个字符转换或映射到另一个字符,它还经常用于删除不需要的或无关的字符。它只从 stdin 读取数据,并将数据写入 stdout。
常见命令选项:

  1. -d:从输入流中删除指定的字符。
  2. -s:压缩,即用单个实例替换字符的重复实例。

示例:
使用 tr 命令将所有反斜杠转换为正斜杠,并将所有冒号转换为竖线:

tr '\\:' '/|' < infile.txt > outfile.txt

第一个参数中的字符映射到第二个参数中的对应字符。由于反斜杠对 tr 具有特殊的意义,所以需要两个反斜杠来指定单个反斜杠字符。
Winodw 系统中的文件通常在每行末尾都带有回车和换行符(CR & LF);Linux 和 macOS 系统只有换行符来结束一行。如果你把一个文件传输到 Linux ,并且想要去掉那些额外的回车字符:

tr -d '\r' < fileWind.txt > fileFixed.txt

相反,你可以使用 sed 将 Linux 行尾转换为 Windows 行尾:

sed -i 's/$/\r/' fileLinux.txt

处理带分隔符的文件

例:
scvex.txt

"name","username","phone","password hash"
"John Smith","jsmith","555-555-1212",5f4dcc3b5aa765d61d8327deb882cf99
"Jane Smith","jnsmith","555-555-1234",e10adc3949ba59abbe56e057f20f883e
"Bill Jones","bjones","555-555-6789",d8578edf8458ce06fbc5bb76a58c5ca4

要从文件中提取名称,可以使用 cut ,方法是将字段分隔符指定为逗号,并指定要返回的字段号:

pwnki@LAPTOP-KETPO6R7:~/project/diliu$ cut -d ',' -f1 csvex.txt
"name"
"John Smith"
"Jane Smith"
"Bill Jones"

将 cut 的输出通过管道输入到具有 -d 选项的 tr 命令:

pwnki@LAPTOP-KETPO6R7:~/project/diliu$ cut -d ',' -f1 csvex.txt | tr -d '"'
name
John Smith
Jane Smith
Bill Jones

使用 tail 命令删除字段头:

pwnki@LAPTOP-KETPO6R7:~/project/diliu$ cut -d ',' -f1 csvex.txt | tr -d '"' | tail -n +2
John Smith
Jane Smith
Bill Jones

选项 -n +2 告诉 tail 从第二行开始输出文件的内容。

遍历带分隔符的数据

例:
passwords.txt

password,md5hash
123456,e10adc3949ba59abbe56e057f20f883e
password,5f4dcc3b5aa765d61d8327deb882cf99
welcome,40be4e59b9a2a2b5dffb918c0e86b3d7
ninja,3899dcbab79f92af727c2190bbd8abc5
abc123,e99a18c428cb38d5f260853678922e03
123456789,25f9e794323b453885f5181f1b624d0b
12345678,25d55ad283aa400af464c76d713c07ad
sunshine,0571749e2ac330a7455809c6b0e7af90
princess,8afa847f50a716e64932d995c8e7435a
qwerty,d8578edf8458ce06fbc5bb76a58c5ca4

使用 awj 从 csvex.txt 中提取每个用户的哈希:

pwnki@LAPTOP-KETPO6R7:~/project/diliu$ awk -F "," '{print $4}' csvex.txt
"password hash"
5f4dcc3b5aa765d61d8327deb882cf99
e10adc3949ba59abbe56e057f20f883e
d8578edf8458ce06fbc5bb76a58c5ca4

默认情况下, awk 使用空格字符作为字段分隔符,因此 -F 选项用于表示自定义字段分隔符 (,),然后打印出第四个字段 $4。
使用 grep 每次从 awk 中提取一行输出,并在 password.txt 字典文件中搜索它,输出任何匹配项:

pwnki@LAPTOP-KETPO6R7:~/project/diliu$ grep "$(awk -F "," '{print $4}' csvex.txt)" passwords.txt
123456,e10adc3949ba59abbe56e057f20f883e
password,5f4dcc3b5aa765d61d8327deb882cf99
qwerty,d8578edf8458ce06fbc5bb76a58c5ca4

按字符位置处理

如果文件具有固定的字段大小,可以使用 cut 命令的 -c 选项按字符位置提取数据。csvex 中 10 位数字的电话号码就是一个例子:

pwnki@LAPTOP-KETPO6R7:~/project/diliu$ cut -d ',' -f3 csvex.txt | cut -c2-13 | tail -n +2
555-555-1212
555-555-1234
555-555-6789

首先使用 cut 提取字段 3 处的电话号码,再使用 -c 提取引号之间的字符,最后用 tail 删除文件头。

处理 XML

可扩展标记语言(XML)允许你任意创建描述数据的标记和元素。
例:
book.xml

<book title="Cybersecurity Ops with bash" edition="1"> <1>
  <author> <2>
    <firstName>Paul</firstName> <3>
    <lastName>Troncone</lastName>
  </author> <4>
  <author>
    <firstName>Carl</firstName>
    <lastName>Albing</lastName>
  </author>
</book>
  1. 这是一个包含起来的两个属性(也成为名称/值对)的开始标记。属性值必须用双引号括起来。
  2. 这是一个开始标记。
  3. 这是一个包含内容的元素。
  4. 这是一个结束标记。

使用 grep 找出所有的 firstName 元素。使用 -o 选项,只返回与正则表达式模式匹配的文本,而不是整行:

pwnki@LAPTOP-KETPO6R7:~/project/diliu$ grep -o '<firstName>.*<\/firstName>' book.xml
<firstName>Paul</firstName>
<firstName>Carl</firstName>

上面的正则表达式只在开始和结束标记位于同一行是查找 XML 元素。要跨多行查找模式,需使用两个特殊属性。

  1. -z:grep 将换行符视为搜索中的任何普通字符,并在找到的每个字符的末尾添加一个空值(ASCII 0)。
  2. -P选项和 (?s):这是一个特定于 Perl 的模式匹配修饰符。它修改 . 元字符,以便也能匹配换行符。
pwnki@LAPTOP-KETPO6R7:~/project/diliu$ grep -Pzo '(?s)<author>.*?<\/author>' book.xml
<author> <2>
    <firstName>Paul</firstName> <3>
    <lastName>Troncone</lastName>
  </author><author>
    <firstName>Carl</firstName>
    <lastName>Albing</lastName>
  </author>

要脱去 XML 开始和结束标记并提取其中的内容,可以将输入导入 sed:

pwnki@LAPTOP-KETPO6R7:~/project/diliu$ grep -Po '<firstName>.*?<\/firstName>' book.xml | sed 's/<[^>]*>//g'
Paul
Carl

处理 JSON

JavaScript 对象表示法是另一种流行的文件格式,特别是用于通过应用程序编程接口(API)交换数据。JSON 是一种简单的格式,由对象、数组和名称/质值对组成。
例:

{ <1>
  "title": "Cybersecurity Ops with bash", <2>
  "edition": 1,
  "authors": [ <3>
    {
      "firstName": "Paul",
      "lastName": "Troncone"
    },
    {
      "firstName": "Carl",
      "lastName": "Albing"
    }
  ]
}
  1. 这是一个对象。对象以 { 开始 ,以 } 结束。
  2. 这是一个名称/值对。值可以是字符串、数字、数组、布尔值或空。
  3. 这是一个数组。数组以 [ 开始,以 ] 结尾。

在处理 JSON 时,可以用 grep 提取键值对。

pwnki@LAPTOP-KETPO6R7:~/project/diliu$ grep -o '"firstName": ".*"' book.json
"firstName": "Paul"
"firstName": "Carl"

删除键并只显示值:

pwnki@LAPTOP-KETPO6R7:~/project/diliu$ grep -o '"firstName": ".*"' book.json | cut -d " " -f2 | tr -d '\"'
Paul
Carl

聚合数据

可以使用 XML 属性中的任何一个来查找数据,并将数据聚合到一个位置:

find /data -type f -exec grep '{}' -e 'ProductionWebServer' \; -exec cat '{}' >> ProductionWebServerAgg.txt \;

命令 find /data -type f 列出 /data 目录及其子目录中的所有文件。对于找到的每个文件,它运行 grep,查找字符串 ProducttionWebServer。如果找到,则将该文件附加到文件 ProductionWebServerAgg.txt 中。如果你希望将所有文件复制到某个位置而不是某个文件,那么可以使用 cp 和目录位置替换 cat 命令。
使用 join 合并两个文件:
示例:
ips.txt

ip,OS
10.0.4.2,Windows 8
10.0.4.35,Ubuntu 16
10.0.4.107,macOS
10.0.4.145,macOS

user.txt

user,ip
jdoe,10.0.4.2
jsmith,10.0.4.35
msmith,10.0.4.107
tjones,10.0.4.145
pwnki@LAPTOP-KETPO6R7:~/project/diliu$ join -t, -2 2 ips.txt user.txt
ip,OS,user
10.0.4.2,Windows 8,jdoe
10.0.4.35,Ubuntu 16,jsmith
10.0.4.107,macOS,msmith
10.0.4.145,macOS,tjones

选项 -t 告诉 join 使用逗号分隔。选项 -2 告诉 join 使用第二个文件 user.txt 中的第二列数据作为执行合并的键。

内容来源

《bash安全运维》

posted @ 2021-01-20 20:49  PwnKi  阅读(24)  评论(0编辑  收藏