0×00
正则表达的理解
什么是正则表达式?简单理解正则表达式是被定义有特殊含义的普通字符串组成的特殊代码字符串,可用来查找符合代码规则的字符串。比如查找某个目录下的所有的word文档,我们会通过搜索*.doc,*会被解释成任意的字符串。和通配符类似,但是正则表达更复杂所以也就能更精确地描述你要匹配的需求。
0×01正则表达的规则
正则表达的字符匹配
1.grep “r..t” /etc/passwd
通过例子我们可以反推的含义是匹配任意单个字符。
2.grep “[123456]” /etc/passwd
通过例子我们可以知道[]中的字符都会被匹配,因此[]的作用是匹配指定范围内的任意单个字符。
3.grep “[^123456]” /etc/passwd
通过例子我们知道[^]与[]正好相反,^为逻辑非运算符,因此[^]的作用是匹配除指定范围外的任意单个字符。
4.grep “[1-9]” /etc/passwd
通过例子我们知道当我们要匹配123456789这些字符时,可以通过[-]来指定连续顺序的字符,如[A-Z]、[a-z]等匹配A到Z的左右大写字母或者a到z的所有小写字母。
除了上述所说的4种正则表达式可以任意匹配单个字符外,正则表达还定义了POSIX字符类来做更精细的字符匹配,具体如下:
[[:alpha:]]匹配任何字母、[[:digit:]]匹配任何数字、[[:lower:]]匹配任何小写字母 、[[:upepr:]] 匹配任何大写字母、[[:alnum:]] 匹配任何字母或数字。需要注意的是[[]]本身属于POSIX字符本身的组成部分 。
如:grep “[[:digit:]]” /etc/passwd
正则表达的匹配次数
用在要指定其出现的次数的字符的后面,用来限制其前面字符出现的次数,默认是匹配次数前的一位字符,如ro*t 的意思是匹配前面的o字符,如果要匹配ro则需要添加小括号(ro)*t ,这样才能匹配前面的ro字符串0次或者多次。
1.grep “ro*t” /etc/passwd
通过例子我们知道*的作用是匹配0次、1次、多次字符,0次匹配搭配到rt ;1次或多次匹配到root,即*控制的是匹配的次数。
2.grep “:/.*:” /etc/passwd
通过例子我们知道.表示匹配单个任意字符,加上*的意思就是匹配多次单个任意字符,也就是匹配任意长度的任意字符。贪婪模式,能匹配多长就匹配多长。
3.grep “roo\?” /etc/passwd
通过例子我们知道\?表示匹配其前面的字符0次或者1次,匹配0次的时候匹配结果为ro,匹配一次的时候匹配结果为roo。
4.rep “roo\+” /etc/passwd
通过例子我们知道 \+表示匹配其前面的字符一次或多次,即其前面的字符出现至少1次。
5.grep “ro\{1\}” /etc/passwd
通过例子我们知道 \{m\}表示匹配其前面的字符m次,这里表示匹配ro一次。
6.grep “ro\{1,3\}” xy
通过例子我们知道 \{m,n\}:匹配其前面的字符至少m次,至多n次,本例子表示匹配ro 1到3次。
7.grep “roo\{0,1\}” /etc/passwd
原理跟上面一样,\{0,n\}表示至多n次;
8.grep “ro\{2\}” /etc/passwd
同上\{m,\}表示至少m次;
正则表达的位置指定
1.grep “^root” /etc/passwd
该例子表示匹配首行字符为root的行,即^是用来指定行首的词。
2.grep “bash$” /etc/passwd
该例子表示匹配行尾字符为bash的行,即$是用来指定行尾的词。其中^$表示可以用来匹配空行,以及^[[:space:]]*$表示可以用来匹配空行或包含空白字符的行。
3.grep “\
该例子用于表示用于词首锚定,即可匹配指定开头字符的单词(非特殊字符组成的连续字符以及字符串都为单词),\
4.grep “login>” /etc/passwd
同理,>用来匹配单词词尾,用于单词的右侧匹配。
5.grep “\” /etc/passwd
用于某个单词的完整匹配。
正则表达的分组以及指定
1.grep “(r..t).*login” /etc/passwd
通过上面的例子可以看出()可以将一个或对多个字符绑在一起,然后再当做整体来进行处理。
2.grep “(r..t).*\1” /etc/passwd
grep “(r..t).*\r..t” /etc/passwd
通过上面的例子我们不难发现\1的意思就是表示正则表达式中第一个()所匹配到的内容,即第一个()匹配的结果和\1的结果是一样的,而\2则是第二个()所匹配的内容,以此类推。
3.grep -E “(root|bash)” /etc/passwd
通过(|)可以引用不同的匹配内容,| 即或的意思,匹配root或者bash。
正则的简单介绍就到这里,在正确理解了上面所说的简单正则匹配之后就可以根据实际的需要组合在一起使用,用来匹配更复杂更精确度字符串了。
小练习:尝试说明以下正则表达式的作用:
1. 0\d\d-\d\d\d\d\d\d\d\d2. \b\w{6}\b
3. ^\d{5,12}$
4. [\u4e00-\u9fa5]
5. /.|/
6. (0\d{2})[- ]?\d{8}|0\d{2}[- ]?\d{8}
7. ((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)
中文按一个字一个字符来算 。
0×02
正则表达式的分类
正则表达最初是由unix中的工具普及开来的,随着后来的发展扩展出以下几个分类:
1、BREs(基本的正则表达式)
2、EREs(扩展的正则表达式)
3、Python REs(Python的正则表达式)
4、Perl REs(Perl的正则表达式)
不同的工具支持的正则表达式的种类也各有不同:
(1) 文本过滤工具grep支持:BREs、EREs、PREs 正则表达式,默认是为”BREs“ ,当要使用“EREs“时则需要在grep 指令后跟 ”-E” 参数,grep 指令后跟 “-P” 参数,则表示要使用 “PREs”。
(2) 文本编辑工具sed支持:BREs、EREs,sed指令后跟参数 “-r ” ,则表示要使用“EREs”
(3) Awk 文本工具支持:EREs,默认使用EREs。
不同分类的正则表达式主要区别在于元字符的不同,比如扩展的正则表达式()的使用。
BREs和EREs区别
0×03
EOF
类似多行echo输出,可以用文件的方式输入。
0×04
AWK
的简单使用
1.awk ‘{print}’ /etc/passwd , 等价于cat /etc/passwd
2.awk ‘{print $1}’ /etc/passwd
$1类似于shell命令的位置变量,这里的意思是输出每一行的第一列字符,第二列则取$2以此类推,同时根据结果可知道awk的默认以空格为每行列数的分隔符。
3.awk -F “:” ‘{print $1}’ /etc/passwd
当然除了默认以空格为分隔符,awk还可通过-F来指定分隔符。
4.awk -f awk /etc/passwd , 可以-f参数导入awk命令文件的方式执行awk, awk为文件。
5.awk -F “:” ‘{print $1”%-10s” $3}’ /etc/passwd , 参数(位置变量)不用单引号括起来,用双引号会原样输出。
awk -F “:” ‘{print $1’\t’ $3}’ /etc/passwd
6.awk -F “:” ‘{print $1\t $3}’ /etc/passwd
awk -F “:” ‘{print $1”\t” $3}’ /etc/passwd
awk -F “:” ‘{print $1’\t’ $3}’ /etc/passwd
格式控制符需要通过双引号括起来,不可以不使用,使用单引号无作用。
7.awk -F “:” ‘{printf $1 “\t” \$3}’ /etc/passwd
awk中同时提供了print和printf两种打印输出的函数。
其中print函数的参数可以是变量、数值或者字符串。字符串必须用双引号引用,参数用逗号分隔。如果没有逗号,参数就串联在一起而无法区分。这里,逗号的作用与输出文件的分隔符的作用是一样的,只是后者是空格而已。printf函数,其用法和c语言中printf基本相似,可以格式化字符串,输出复杂时,printf更加好用,代码更易懂。
0×04
综合应用
linux基线脚本的编写:
例子:检查点:账号策略检查
#! /bin/bash
cat <
*************************************************************
linux安全配置基线检查脚本:
1. 输出结果也可以在当前目录的out.txt中查看
2. 检查范围:
-》账号策略检查
-》...
*************************************************************
EOF
rm -rf ./out.txt
echo -e "\n"
echo "[1] 账号策略检查中..."
passmax=`cat /etc/login.defs | grep PASS_MAX_DAYS | grep -v ^# | awk '{print $2}'`
passmin=`cat /etc/login.defs | grep PASS_MIN_DAYS | grep -v ^# | awk '{print $2}'`
passlen=`cat /etc/login.defs | grep PASS_MIN_LEN | grep -v ^# | awk '{print $2}'`
passage=`cat /etc/login.defs | grep PASS_WARN_AGE | grep -v ^# | awk '{print $2}'`
if [ $passmax -le 90 -a $passmax -gt 0 ];then
echo " [OK]口令生存周期为${passmax}天,符合要求" >> out.txt
else
echo " [ X ] 口令生存周期为${passmax}天,不符合要求,建议设置不大于90天" >> out.txt
fi
if [ $passmin -ge 6 ];then
echo " [OK]口令更改最小时间间隔为${passmin}天,符合要求" >> out.txt
else
echo " [ X ] 口令更改最小时间间隔为${passmin}天,不符合要求,建议设置大于等于6天" >> out.txt
fi
if [ $passlen -ge 8 ];then
echo " [OK]口令最小长度为${passlen},符合要求" >> out.txt
else
echo " [ X ] 口令最小长度为${passlen},不符合要求,建议设置最小长度大于等于8" >> out.txt
fi
if [ $passage -ge 30 -a $passage -lt $passmax ];then
echo " [OK]口令过期警告时间天数为${passage},符合要求" >> out.txt
else
echo " [ X ] 口令过期警告时间天数为${passage},不符合要求,建议设置大于等于30并小于口令生存周期" >> out.txt
fi
echo "..."
echo 'check over'
echo -e "\n"
echo "-------------------------------------------------------"
echo ""
echo "检查结果:"
echo ""
cat ./out.txt
echo ""
echo "--------------------------------------------------------"
echo ""
执行脚本 sh check.sh。
然后根据基线检查的需要不断的完善和添加脚本,整理出不同linux操作系统的基线检查脚本。