生活随笔
收集整理的这篇文章主要介绍了
Java实现伪造邮件发信人
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
Java实现伪造邮件发信人
- 关键词
- 效果预览
- 背景说明
- 参考说明
- 实现代码
- 代码解析及输出
- 测试及避坑
- 启示
- 拓展阅读
关键词
Java、邮件、SMTP、伪造、发信人、邮箱、由……代发
效果预览
背景说明
作业背景
最近在做设计,设计里涉及到邮件通知功能,但是直接使用自己个人邮箱发送的话显得那啥一点,并且在Python SMTP发送邮件里发现是可以伪造邮件的,故打算把自己的邮箱“打扮”一下,将自己的设计模拟的更真实一点。可不要拿来做不好的事情哦
环境
- Win10、Linux
- Java8(不需要额外的jar)
参考说明
看了不少做JavaEmail的文章,基本上都是采用javax.mail.jar包做的,但是无法实现伪造发信人(这里的发信人指的是邮箱,这个包昵称是可以指定的。可能之前的setSender可以,但是我没用过,我下载的1.6.2版本的,MimeMessage对象没有setSender方法),主要参考了两篇文章(后面给出),都写的很好,我写这篇文章的目的是让朋友们多一个维度参考。下面是我参考的文章:
1.JAVA实现SMTP邮件发送
2.java发送邮件的两种实现方式(包括如何伪造发件人及其原理)
对了还有一篇:Java8 Base64 | 菜鸟教程
实现代码
喜欢图片的朋友看这个,喜欢代码的在后面
源代码:
import java
.io
.*
;
import java
.net
.Socket
;
import java
.nio
.charset
.StandardCharsets
;
import java
.util
.Base64
;public class SMTPSendMail {public static void main(String
[] args
) {String loginUsername
= "sample@163.com"; String loginPassword
= "JCTAJSNCUPEMKPZO"; String realAddressee
= "receiver@xxx.com"; String smtpServer
= "smtp.163.com"; int port
= 25;String b64Username
= Base64
.getEncoder().encodeToString(loginUsername
.getBytes(StandardCharsets
.UTF_8
));String b64Password
= Base64
.getEncoder().encodeToString(loginPassword
.getBytes(StandardCharsets
.UTF_8
));try {Socket socket
= new Socket(smtpServer
, port
);BufferedReader bfr
= new BufferedReader(new InputStreamReader(socket
.getInputStream()));PrintWriter pw
= new PrintWriter(socket
.getOutputStream(), true);pw
.println("helo " + "Stephen");System
.out
.println(bfr
.readLine());pw
.println("auth login");System
.out
.println(bfr
.readLine());pw
.println(b64Username
); System
.out
.println(bfr
.readLine());pw
.println(b64Password
); System
.out
.println(bfr
.readLine());pw
.println("mail from:<"+loginUsername
+">");System
.out
.println(bfr
.readLine());pw
.println("rcpt to:<" + realAddressee
+ ">");System
.out
.println(bfr
.readLine());pw
.println("data");System
.out
.println(bfr
.readLine());pw
.println("subject:" + "主题什么的随随便便就好了"); pw
.println("from:" + "一方巨鳄 <xxxxxx@163.com>"); pw
.println("to:" + "管理员 <" + realAddressee
+ ">"); pw
.println("Content-Type:text/html;charset=\"utf-8\""); pw
.println();String text
= "<html><body><table border=\"1\"> <h1>表格</h1>" +"<tr><th>姓名</th><td>理智</td></tr>" +"<tr><th>性别</th><td align=\"center\">男</td></tr></table></body></html>";pw
.println(text
);pw
.println();pw
.println("."); System
.out
.println(bfr
.readLine());pw
.println("rset");System
.out
.println(bfr
.readLine());pw
.println("quit");System
.out
.println(bfr
.readLine());} catch (IOException e
) {e
.printStackTrace();}}
}
代码解析及输出
可以看到,上面的代码主要是pw.println()和bfr.readLine(),前者主要是发命令的,而后者则是接收响应的。模拟Telnet客户端发邮件[1]。
输出
邮件效果在开头已给出,那是我用学校邮箱的smtp服务器发的,改了收件人显示的信息,没有被退信。
测试及避坑
我在使用smtp.163.com服务器的情况下在to:命令之后接假收件人时遇到这个
554 DT:SPM 163 smtp10,DsCowAD3__ck_rxeJqxmBw--.19039S2 1589444132,please see
http://mail.163.com/help/help_spam_16.htm?ip=111.58.181.219&hostid=smtp10&time=1589444132
点进去看,是“退信代码说明”
解决办法:把图第49行的收件人改回真实收件人邮箱(上面的已改,原来的代码是pw.println("to:" + "管理员 <xxxxxx@qq.com>");实现的就是效果图)就可以了。
测试139邮箱时,一直报550 2f015ebe0b3f97a-4e9fd Mail rejected,ta没有给授权码,就是使用的登录密码,我尝试的所有办法都无法发邮件(无论是否伪造)
解决办法:暂无,劝君慎用139,或者有解决的踢我一脚谢谢
测试sina邮箱,sina邮箱是要将mail from和from进行匹配的,也就是无法通过这个方法进行伪造,有知道怎么做的也可以提醒我谢谢。
解决办法:我无。
测试126邮箱,给qq邮箱发邮件,第一次可以伪造(显示代发,并且有一段特殊信息回显),之后就是显示真实的邮箱地址。
目前就测试了这几个邮箱服务商,总的来说就qq、163和126可以伪造发信人,这几个邮箱开启SMTP服务的话短信是自己发的短信费是自己掏的,所以写这篇文章是含有成本在里面的(含金量杠杠的🐕)。
启示
收到邮件注意一下邮件内容,奇怪的发信人奇怪的邮箱注意查看信头,信头中的Sender一般即为真实发信人,使用一些比较知名的邮箱服务平台等,小平台的邮箱甚至某些有名的平台如某浪的邮箱可能还不会显示由……代发,比如说我测试过的临时邮箱查看伪造的邮件就没有显示真实邮件地址,这得注意信头的Sender了。
拓展阅读
1.SMTP协议详解
2.廖雪峰Python-电子邮件-SMTP发送邮件
总结
以上是生活随笔为你收集整理的Java实现伪造邮件发信人的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。