攻防对抗是这本书的主要研究内容,也是安全领域永恒的一个主题。这里我们重点介绍基于英文邮件的垃圾邮件绕过技术。在垃圾邮件检测中,处理的最小单元往往是单词,所以绕过的突破点就在单词上。人在查看邮件时,明显的错别字、多余的回车、换行符和制表符等基本不影响人的阅读,但是对于机器来说却可以破坏基于单词的识别机制,例如下面这封垃圾邮件:
raw="thank you ,your email address was obtained from a purchased list ," \ "reference # 2020 mid = 3300 . if you wish to unsubscribe"
在单词中插入TAB基本不会影响人的阅读,但是却可以破坏机器对单词的识别,比如上面那段代码就可以转化成:
thank you ,your ema il address was obtained from a purchased list ,reference # 2020 mid = 3300 . if you wish to unsubscribe
一种简单的实现就是在文本中随机选择英文字符,在该字符后面增加TAB即可,替换的个数也可以随机在1~3之间选择,代码如下:
def addTab(self,str,seed=None): matchObjs = re.findall(r'[a-qA-Q]', str, re.M | re.I) if matchObjs: #选择替换的字符 modify_char=random.choice(matchObjs) #生成替换的内容 modify_char_tab=" {}".format(modify_char) #替换 str=re.sub(modify_char, modify_char_tab, str,count=random.randrange(1,3)) return str
在单词中插入回车也基本不会影响人的阅读,但是却可以破坏机器对单词的识别,比如上面那段代码就可以转化成:
th ank you ,your em ail address was obtained from a purchased list, reference # 2020 mid = 3300 . if you wish to unsubscribe
一种简单的实现就是在文本中随机选择英文字符,在该字符前面增加回车即可。为了避免影响阅读,将替换的个数设置为1,代码如下:
def addEnter(self,str,seed=None): matchObjs = re.findall(r'[a-qA-Q]', str, re.M | re.I) if matchObjs: #选择替换的字符 modify_char=random.choice(matchObjs) #生成替换的内容 modify_char_enter="\\r\\n{}".format(modify_char) #替换 str=re.sub(modify_char, modify_char_enter, str,count=1) return str
有的检测规则是大小写敏感的,所以也可以使用大小写混淆的方式来尝试绕过,比如12.2节最前面的那段代码就可以转化成:
thank you ,your email ADDRESS was obtained from a purchased list ,reference # 2020 mid = 3300 . if you wish to unsubscribe
一种简单的实现就是在文本中随机选择英文单词,将该单词大小混淆即可。替换的个数也可以随机在1~3之间选择,代码如下:
def confusionCase(self,str,seed=None): matchObjs = re.findall(r'\b\w+\b', str, re.M | re.I) if matchObjs: #选择替换的单词 modify_word=random.choice(matchObjs) #生成替换的内容 modify_word_swapcase=modify_word.swapcase() #替换 str=re.sub(modify_word, modify_word_swapcase, str,count=random.randrange(1,3)) return str
需要说明的是,大小混淆有可能会影响个别单词的理解,尤其是专有名词的理解。
插入换行符也基本不会影响人的阅读,但是却可以破坏机器对单词的识别,比如12.2节最前面的那段代码就可以转化成:
than/k you ,your email address was obtained from a purchased list ,reference # 2020 mid = 3300 . if you wish to unsubscribe
一种简单的实现就是在文本中随机选择英文字符,在该字符后面增加换行符即可。替换的个数也可以随机在1~3之间选择,代码如下:
def lineBreak(self,str,seed=None): matchObjs = re.findall(r'[a-qA-Q]', str, re.M | re.I) if matchObjs: # 选择替换的字符 modify_char = random.choice(matchObjs) # 生成替换的内容 modify_char_lb = "{}/".format(modify_char) # 替换 str = re.sub(modify_char, modify_char_lb, str, count=random.randrange(1, 3)) return str
插入连字符也基本不会影响人的阅读,但是却可以破坏机器对单词的识别,比如12.2节最前面那段代码就可以转化成:
thank you ,your email ad-d-ress was obtained from a purchased list ,reference # 2020 mid = 3300 . if you wish to unsubscribe
一种简单的实现就是在文本中随机选择英文字符,在该字符后面增加连字符即可。替换的个数也可以随机在1~3之间选择,代码如下:
def addHyphen(self,str,seed=None): matchObjs = re.findall(r'[a-qA-Q]', str, re.M | re.I) if matchObjs: # 选择替换的字符 modify_char = random.choice(matchObjs) # 生成替换的内容 modify_char_lb = "{}-".format(modify_char) # 替换 str = re.sub(modify_char, modify_char_lb, str, count=random.randrange(1, 3)) return str
人在阅读的时候可以识别明显的语法错误以及错别字,但不影响对原文的理解,不过机器在进行垃圾邮件识别时,面对错别字有可能产生判断失误,比如12.2节最前面那段代码就可以转化成:
thank you ,your eemail addreess was obtained from a purchased list ,reference # 2020 mid = 3300 . if you wish to unsubscribe
一种简单的实现就是在文本中随机选择英文字符,将该字符替换成两个即可。替换的个数也可以随机在1~3之间选择,代码如下:
def doubleChar(self,str,seed=None): matchObjs = re.findall(r'[a-qA-Q]', str, re.M | re.I) if matchObjs: #选择替换的字符 modify_char=random.choice(matchObjs) #生成替换的内容 modify_char_enter="{}{}".format(modify_char,modify_char) #替换 str=re.sub(modify_char, modify_char_enter, str,count=random.randrange (1,3)) return str