Pwnable.kr 提示之 md5-calculator 篇

前前言

本人的个人博客网址:www.QmSharing.space,所有的文章都可以在里面找到,欢迎各位大佬前来参观并留下宝贵的建议,大家一起学习一起成长 :-)

难度分析

本题属于综合题, 是有一定难度的, 但利用的漏洞我们在之前的题目中基本都见到过, 所以也不算特别的难. 这题唯一一个之前涉及不多的就是 canary 技术, 不过它也并不是很难理解, 后面我会大概介绍一下. 这题总体是特别有意思的一道题, 难度与乐趣具备, 很值得你花点时间去钻研一下.

基本检查

  • file
hash: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=89ebf47881a82f5a991199ae381f8284a46e0500, not stripped

基本的动态链接的32位程序, 和之前大多数题目一样.

  • checksec
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

嗯... 也是有 canary 和栈段不可执行保护, 看起来"好像"又不能进行栈溢出了. 其他没什么值得注意的地方了.

遇到的问题

可能有些人会遇到和我一样的问题, 就是在直接执行 hash 程序时, 出现以下报错:

./hash: error while loading shared libraries: libcrypto.so.1.0.0: cannot open shared object file: No such file or directory

这种类型的报错我之前见过的不少, 本质原因就是程序在进行外部链接时找不到所需的库, 导致程序无法执行, 那么问题就是这个 libcrypto.so.1.0.0 是什么库来的.

我大概 apt search 了一下, 就是下面这个东西:

libssl1.0.0/xenial-updates,xenial-security,now 1.0.2g-1ubuntu4.14 amd64 [installed]
  Secure Sockets Layer toolkit - shared libraries

应该是个 SSL 的工具库, 但是可以看到我好像已经装了(不知道你们是不是), 怎么会报错呢? 其实问题也很简单, 你运行的这个程序是32位的, 而你安装的却是64位的动态库, 能运行才怪呢对吧. 因此, 你需要安装 32 位的 ssl 库:

sudo apt install libssl1.0.0:i386

然后你再运行程序应该就不会有问题了.

分析

进入到 Rookiss 这个级别, 已经基本不给你源码进行分析了, 所以是考察你的逆向能力. 这里我就稍微贴一下一些关键位置的逆向伪代码, 其余的你就自己逆向后进行分析吧.

int __cdecl main(int argc, const char **argv, const char **envp)
{
  // 前面省略变量定义和缓冲区设定
  puts("- Welcome to the free MD5 calculating service -");
  v3 = time(0); // 用当前时间做随机数的种子, 这里稍微留意一下哈
  srand(v3);
  v6 = my_hash(); // 这个是生成验证码(captcha)的逻辑
  printf("Are you human? input captcha : %d\n", v6);
  __isoc99_scanf("%d", &v5);
  if ( v6 != v5 ) // 输错验证直接结束
  {
    puts("wrong captcha!");
    exit(0);
  }
  puts("Welcome! you are authenticated.");
  puts("Encode your data with BASE64 then paste me!");
  process_hash(); // 这里就是将输入进行 BASE64 解码后再生成 MD5
  puts("Thank you for using our service.");
  system("echo `date` >> log"); // 这里就简单的将指令 date 的结果附加到 log 后面, 但我觉得这就是为了提供 system 函数给你用
  return 0;
}

整个程序逻辑很简单, 就是把你的输入转换成 MD5, 展示后把当前系统时间写入到 log. 继续研究, 我当时选择先看 process_hash 函数:

unsigned int process_hash()
{
  // 省略 v0-v4 的变量定义
  int v5; // [esp-20Ch] [ebp-20Ch] 
  unsigned int v6; // [esp-Ch] [ebp-Ch] 这个是 canary

  v6 = __readgsdword(0x14u); // 写入 canary 值
  memset(&v5, 0, 0x200u);
  while ( getchar() != 10 )
    ;
  memset(g_buf, 0, sizeof(g_buf)); // 初始化 g_buf
  fgets(g_buf, 1024, stdin); // 从标准输入读取1024字节的值

  memset(&v5, 0, 0x200u);
  v1 = Base64Decode(g_buf, &v5, v0); // 将输入进行 BASE64 解码, 结果写入到 v5, v1是解码长度
  v3 = calc_md5(&v5, v1, v2); // 利用 v5 的值进行 MD5 生成, 结果赋值给 v3
  printf("MD5(data) : %s\n", v3);
  free(v3);
  return __readgsdword(0x14u) ^ v6; // 这里就是检测 canary 值是否被改变, 改变则证明出现了栈溢出
}

这里不管你用什么方法(输入大量数据或直接分析代码), 你会发现 1024 字节的 BASE64 值理论上解码能得到 (1024*3/4=768)字节的数据, 但你看清楚, 这个 v5 仅仅分配了 512(0x200) 字节给它, 那么这里必然存在了栈溢出, 即 v5 就是注入点. 但讽刺的是, 这个函数被 canary 保护着, 这和我们之前做过的题目好像有点不同啊. 那么我觉得, 这题应该就是要我们进行某种操作来绕过 canary 值了, 如果你看到这里还是不知道什么是 canary 的话, 你应该马上停止阅读, 并打开 canary 原理先进行学习后, 再往下阅读.

绕过 canary 有不少, 但是鉴于本题的情况, 覆盖 canary 或者劫持 got 的方法应该是不太好实现的, 因此我觉得这很大可能是一个要泄漏 canary 值的题目, 因为如果你知道了 canary 值, 那么在整个程序的运行周期内, 这个值都不会改变, 你就可以在注入时在它应该存在的地方把它插入, 让程序以为自己运行并没有出错, 但实际我们已经进行了栈溢出攻击了.

但是, 哪里有办法让我们泄漏出这个 canary 值呢? 因为不知道 canary 的情况下, 我们也不可能改变程序的走向, 而且 Base64 解码和 MD5 生成逻辑中也没什么可疑的地方(可以说我并不想去看那里的代码 (* ̄ω ̄)). 然后我就去翻翻 my_hash 函数, 嗯... 发现了这样一个有趣的地方:

int my_hash()
{
  signed int i; // [esp-38h] [ebp-38h]
  // 省略 v2 到 v9 的定义, 我这里的变量计数是从 v2 开始的, 我也不知道为什么, 你们知道就好
  unsigned int v10; // [esp-Ch] [ebp-Ch] 这个是 canary

  v10 = __readgsdword(0x14u);
  for ( i = 0; i <= 7; ++i )
    *(&v2 + i) = rand(); // 为 v2-v9 分别赋值随机数
  return v6 - v8 + v9 + v10 + v4 - v5 + v3 + v7; // 返回 captcha, 嗯... v10 怎么在里面
}

可以看到, 这个返回值的计算中, 有把 canary 算进去了. 这... 岂不是我知道了其它7个值, 我就知道 canary 是什么了吗? 但是其它七个值是随机数啊, 怎么可能破解呢? 我当初在这里也卡了一段时间, 但是, 如果你还记得之前那到 random 的题目, 你就应该知道, 随机数生成算法生成的并不是真正的随机数, 只是根据一个种子进行的计算出伪随机数, 如果你有同样种子, 你就能生成一模一样的随机数了.

这里我感觉应该是本题最难的地方之一了, 你除了需要知道随机数并不是真正随机的这个原理外, 你还要知道程序运行时系统的时间戳是多少. 但这里题目当时有给我们提示, 说这个程序执行的服务器和网站的服务器是同一个. 那么这样就好办了, 我可以在执行程序的时候, 立刻向 Pwnable.kr 网站发一个数据包, 根据结果返回的世界来判断程序当时执行的时间(其实还有一个方法, 就是先通过之前一些题目的提供的账号, ssh 到服务器, 然后在执行程序时, 顺便获得 date +%s 指令的值, 这个值与程序执行的时间基本是一致的). 提示到这里, 本题最难的地方应该已经解决了, 剩下的就是普通的栈溢出利用了, 如何重定向以执行 system 函数, 我相信大家都懂了, 如果大家有什么问题, 欢迎大家在下方留言, 大家一起交流一下 : )

答案

解答步骤和 Writeup 可以在我的 Github 中找到: md5-calculator writeup

参考链接

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容

  • 0x01 Start checksec 的时候可以看到程序没有打开任何的安全保护措施,然后查看IDA下的汇编代码,...
    Nevv阅读 1,665评论 0 2
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,084评论 1 32
  • 201. M-Q型显影液组合是()。 (2.0 分) A. 米吐尔与菲尼酮的组合 B. 对苯二酚和菲尼酮的组合 C...
    我们村我最帅阅读 3,306评论 0 4
  • 我认识这位新邻居,是在一次下楼。她腆着大肚子在电梯里,向我点头致意,作为回应,我关切地问:“几个月了?”女人爱笑,...
    汪葆夫阅读 805评论 1 11
  • 第14只鸟 1 大学的时候,我因为吃了太多的烧烤,导致身体不堪重负,生活也受到了严重的打击,我发誓以后再也不吃烧烤...
    李思维的好奇心阅读 1,492评论 1 7