之前一直在学习wireshark,只是不懂网络,看了很多教程,但一直没看懂。觉得挺难。
这两天全部时间都在学习wireshark,总算是入门了。后期理解后,感想在于,还得是官方教程。看这个才是最佳学习方式。
wireshark,能抓一切包,如果没抓到,就要看看捕获过滤器和显示过滤器是否写对没。
TCP说明:
TCP,包含了flag,分成Syn(新建连接包),Fin(连接结束 包, 释放一个连接。 ),Push(将tcp尽快推送到http的 包 ),Urgent(紧急的 包 ),Reset(重置的 包 ),Ack(确认收到包)。另外还有两个,Seq number,Ack number,这两个的数字变化来记录包是否是完整的,有没有掉包现象。 Seq number 表示发送, Ack number 表示接收。所以看这个包是Syn包就知道是三次握手包。
一般Ack确认包的length为54个,如果带有Tcp Payload,如payload 为1440,则tcp总大小为1440+54=1494。 Tcp Payload会参与到Seq number,和Ack number的计算中。
1、Wireshark的数据包详情窗口,如果是用中括号[]括起来的,表示注释,在数据包中不占字节
2、在二进制窗口中,如“DD 3D”,表示两个字节,一个字节8位
3、TCP数据包中,seq表示这个包的序号,注意,这个序号不是按1递增的,而是按tcp包内数据字节长度加上,如包内数据是21字节,而当前IP1发到IP2的包的seq是10的话,那下个IP1发到IP2的包的seq就是10+21=31
4、注意我们分析tcp包时,要以一个会话做为一个完整对象,即通讯只发生在两个IP之间,两个固定的端口之间,如果端口变化了,那链接就不是同一条了,不同的链接之间的seq是没有关联的
5、tcp包分为包头的内容,tcp的包头长度是32字节,整个数据包的包头是66字节(不一定的),如果整个数据包是66字节的话,那内容长度就是0
6、每个tcp包都带有win、ack,这些是告诉对方,我还可以接收数据的滑动窗口是多少,如果A发到B的包的win为0,就是A告诉B说我现在滑动窗口为0了,饱了,你不要再发给我了,就说明A端环境有压力(如带宽满了等)
7、ack可以理解为应答。A发给B的ack是告诉B,我已收到你发的数据包,收到ack号这里了,你下次要发seq为ack号的给我
8、在网络不堵即滑动窗口一点都不堵的情况下,第一个包的ack号就是第二个包的seq号,如果堵了,由于是滑动窗口缓存处理队列,所以这个值会错开
9、如果A发到B连续几个包,seq号不变,ack号一直在变大,说明A一直在收B的数据,一直在给B应答
10、如果A发到B连续几个包,seq号一直变大,ack号一直没变,说明A一直在向B发数据,不用给B应答,而是在等B的应答
11、可以接收多个数据包后,一次性给一个应答,不用每个数据包一一对应给应答
12、发了一个包,很久没有收到应答后,会重发包,在Wireshark抓包工具提示“[TCP Retransmission]”,在数据包详情窗口点开可以看到是对哪个数据包的重传
13、“[TCP Dup ACK ?#?]”应答包的重传
14、如果出现这个错误“[TCP Previous segment not captured]”,说明乱序了,前一个包没有收到,收到后面的包了,这时也会重传包
————————————————
RSA数字签名算法主要可以分为MD系列和SHA系列两大类。
MD系列:MD2withRSA、MD5withRSA。
SHA系列:SHA1withRSA、SHA224withRSA、SHA256withRSA、SHA384withRSA、SHA512withRSA。
我们现在用的http协议是http2,https 是Tls v1.2。
Seq number和Ack number怎么计算的?
分两种情况,
1,如果包的flag就syc或是fin,seq number就是上一次发送时的包的seq+1,如果没有上一次发送,就从0开始。Ack number就是上一次接收时的包的seq+1,如果没有,也从0开始。上一次接收,可以从wireshark 序号后的向左或者向右箭头确认。
2,如果包是ack的包,则不加1。 Seq number 是上一次发送时seq number +tcp Payload length。 Ack number 是上一次接收时 Seq number + tcp Payload length。
注意,SYN/FIN的传输虽然没有data,但是会让下一次传输的packet seq增加一,但是,ACK的传输,不会让下一次的传输packet加一。
1、
- seq:client端第一次发送packet,即:first-way handshake。所以按照上面的准则,它的数据应该从第一个开始,也即是第0位开始,所以seq为0。
- ack:而server端之前并未发送过数据,所以期望的是server端回传时的packet的seq应该从第一个开始,即是第0位开始,所以ack为0。
2、
- seq:server端第一次发送packet,即:second-way handshake。所以,这个packet的seq为0。
- ack:由于在【1】中接收到的是client端的SYN数据包,且它的seq为1,所以client端会让它自己的seq增加1。由此可预计(expect),client端的下一次packet传输时,它的seq是1(0增加1)。所以,ACK为1。
3、
- seq:third-way handshake。上一次发送时为【1】,【1】中seq为0且为SYN数据包,所以这一次的seq为1(0增加1)。
- ack:上次接收到时为【2】,【2】中seq为0,且为SYN数据包(虽然在flag上同时设定为SYN/ACK,但只要flag是SYN,就会驱使seq加一),所以可预计,server端下一次seq为1(0增加1)。
4、
- seq:上一次发送时为【3】,【3】中seq为1且为ACK数据包,所以这一次的seq为1。
- ack:上次接收到时为【2】,【2】中seq为0,且为SYN数据包,所以可预计,server端下一次seq为1(0增加1)。
5、
- seq:上一次发送时为【2】,【2】中seq为0,且为SYN数据包,所以这一次的seq为1(0增加1)。
- ack:上一次接收时为【4】,【4】中的seq为1,数据包的长度为725,所以可以预计,下一次client端的seq为726(1+725)。
6、
- seq:上一次发送时为【5】,【5】中seq为1,但【5】为ACK数据包,所以数据长度为0且不会驱使seq加1,所以这一次的seq为1(1+0)。
- ack:上一次接收时为【4】,【4】中的seq为1,数据包的长度为725,所以可以预计,下一次client端的seq为726(1+725)。
7、
- seq:上一次发送时为【4】,【4】中seq为1,数据包长度为725,所以这一次的seq为726(1+725)。
- ack:上一次接收时为【6】,【6】中seq为1,且数据长度为1448,所以可以预计,下一次server端的seq为1449(1+1448)。
8、
- seq:上一次发送时为【6】,【6】中seq为1,数据包长度为1448,所以这一次的seq为1449(1+1448)。
- ack:上一次接收时为【7】,【7】中seq为726,数据包为ACK、即数据为0,所以可以预计,下一次client端的seq为726(726+0)。
9、
- seq:上一次发送时为【7】,【7】中seq为726,数据包为ACK、即长度为0, 所以这一次seq为726(726+0)。
- ack:上一次接收时为【8】,【8】中seq为1449,数据包长度为1448,所以可以预计,下一次server端的seq为2897(1449+1448)。
10、
- seq:上一次发送时为【8】,【8】中seq为1449,且数据包长度为1448,所以这一次seq为2897(1449+1448)。
- ack:上一次接收时为【9】,【9】中seq为726,数据包为ACK、即数据为0,所以可以预计,下一次client端的seq为726(726+0)。
剩下的7个packet可以留作练习题自己分析。可以看到的是,从【7】开始,client端这边就只负责做响应,发送ACK数据包,而并没有实际的数据发送到server端。所以,从【7】开始,所有的ACK数据包的seq都是相同的726,因为ACK不像SYN/FIN可以让seq增加,所以发送再多的ACK包都只能让seq原地踏步。
丢包验证
由此可以看到,无论对于client端还是server端,这一次刚收到的对方的packet的seq,一定要和最后一次发送时的packet的ack相等。
因为最后一次发送时的packet的ack,是对下一次接收的packet的seq做的预测。如果两者不等,则表明中途有数据包丢失了!
tsl及x509说明
ssl是tls的前任,因为ssl不安全,所有后面tls替换,现在所说的ssl其实等同于tls,使用的证书是x509。 Https证书格式遵循的是X.509标准。X.509是ITU-T标准化部门基于他们之前的ASN.1定义的一套证书标准。
X.509 是密码学里公钥证书的格式标准。 X.509 证书己应用在包括TLS/SSL(WWW万维网安全浏览的基石)在内的众多 Internet协议里.同时它也用在很多非在线应用场景里,比如电子签名服务。X.509证书里含有公钥、身份信息(比如网络主机名,组织的名称或个体名称等)和签名信息(可以是证书签发机构CA的签名,也可以是自签名)。对于一份经由可信的证书签发机构签名或者可以通过其它方式验证的证书,证书的拥有者就可以用证书及相应的私钥来创建安全的通信,对文档进行数字签名.
由于网络断开连接或客户端闲置时间过长,会话可能会故意终止。 会话结束后,必须通过新的握手或通过先前建立的称为会话ID的机密来重新建立会话,以允许恢复会话。
keylogfile.txt必须要实时更新,否则就解不开了。一旦断开,需要重新握手。 要解密HTTPS流量,需要得到加密密钥,加密密钥由主密钥、客户端随机数、服务器随机数生成。由上述握手过程可知,客户端随机数和服务器随机数在双方握手消息中传递,而主密钥(master_secret)则由预主密钥(pre_master_secret)结合两个随机数生成。预主密钥通过密码套件中的密钥交换算法进行交换(DH、RSA)。 详细如下 :
http://cn-sec.com/archives/508478.html (需翻墙)
tls加密位于tcp层之上,http层之下,那么tls又是如何能加密tcp中的payload的呢。【未解】,另外服务器的证书的签名和所有人公钥分别是什么作用我也未知。
tls未解密之前,只能看到tcp的数据外(端口,seq,ack等外),tls只能看到个版本和密文。是否使用的get方法,请求路径是什么,headers,body一律都被加密。
一旦解密后,http层才会出现。
追踪流的含义,不同端口之间的交互。比如为192.168.0.105:52414—>114.116.236.109:80之间的所有数据,统一为一个流。用stream index表示。不同的index值,即为不同的流。
超时重传
建立连接时:
如果发送方在发送一个SYN包后,在超时时间内没有收到确认包,则发送方会重新发送,称为超时重发。
默认Linux重试次数为5次,重试时间间隔由1s开始每次翻倍,即1s,2s,4s,8s,16s。如果经过1+2+4+8+16+32=63s后,仍没有收到确认包,则发送方认为接收方已掉线,会主动断开当前连接。
数据传输时:
为了网络整体的稳定,需要动态的根据往返时间设置数据包的超时时间。这里就不展开说具体算法过程了。
RTO(Retransmission Timeout)重传超时时间
RTT(Round-Trip Time)往返时间
看懂HTTPS、证书机构(CA)、证书、数字签名、私钥、公钥
TLS解密方法:
The master secret enables TLS decryption in Wireshark and can be supplied via the Key Log File. The pre-master secret is the result from the key exchange and can be converted to a master secret by Wireshark. This pre-master secret can be obtained when a RSA private key is provided and a RSA key exchange is in use.
Step-by-step instructions to decrypt TLS traffic from Chrome or Firefox in Wireshark:
- Close the browser completely (check your task manager just to be sure).
-
Set environment variable
SSLKEYLOGFILE
to the absolute path of a writable file. - Start the browser.
- Verify that the location from step 2 is created.
- In Wireshark, go to Edit -> Preferences -> Protocols -> TLS, and change the (Pre)-Master-Secret log filename preference to the path from step 2.
- Start the Wireshark capture.
- Open a website, for example https://www.wireshark.org/
-
Check that the decrypted data is visible. For example, using the
tls and (http or http2)
filter.
For Windows, an environment variable can be set globally as described in this walkthrough, but this is not recommended since it is easy to forget about and may be a security issue since it allows decryption of all your TLS traffic. A better way to set the environment variable is via a batch file. Create a file start-fx.cmd
with:
@echo off
set SSLKEYLOGFILE=%USERPROFILE%\Desktop\keylogfile.txt
start firefox/chrome.exe
For Linux, you open a terminal then start the browser with:
export SSLKEYLOGFILE=$HOME/Desktop/keylogfile.txt
firefox
For macos, you open a terminal then start the browser with:
export SSLKEYLOGFILE=$HOME/Desktop/keylogfile.txt
open -a firefox
Change the SSLKEYLOGFILE
path as needed, and replace firefox
with chrome
for Google Chrome. This mechanism currently (2019) does not work for Safari, Microsoft Edge, and others since their TLS libraries (Microsoft SChannel/Apple SecureTransport) do not support this mechanism. This mechanism works for applications other than web browsers as well, but it dependent on the TLS library used by the application.
https://gitlab.com/wireshark/wireshark/-/wikis/TLS
如果是app想要解密https,无法拿到keylogfile.txt,所以只能通过以下办法:
The easiest way to capture and decrypt TLS traffic on Android is to use “PCAP Remote”. The app act as Man-In-The-Middle by creating an local VPN connection and using its self-signed certificate. You can then download the unencrypted traffic as pcap file to open it in Wireshark for further analyzes.
Another way to see the unencrypted traffic is to use a TLS proxy like Burp or mitm. One of the advantages of those TLS proxys is, that you can see and manipulate the HTTP requests in the GUI in realtime. The big disadvantage is, that it is not really easy to add the needed self-signed certificate to the Android trusted certificate store. You will need to have root access to your phone to do so.
I think the only way to prevent that users are able to decrypt the TLS traffic and find the API endpoints of your app is, to implement HTTP public key pinning to it. Your app will then only accept the defined server certificate for TLS connections, which prevents MITM attacks.
How can I capture API endpoints sent to HTTPS from an Android App?
证书的基本理解:
HTTPS之TLS证书