zoukankan      html  css  js  c++  java
  • 堆栈里的秘密行动:劫持执行流

    前情回顾

    线程老哥执行memcpy越界访问溢出,堆栈里的一众对象难逃噩运。

    详情参见:堆栈里的悄悄话——智能指针

    神秘的0xCC

    “去吧,为了首领的伟大理想出发”


    我是一段二进制代码shellcode,0xCC大人精心创造了我,一同诞生的还有一个HTML表单文件小P,我就栖身在小P的身上,随着一个POST请求,我们朝着目标奔去。

    很快我们就抵达目的地,这是一个Linux帝国,无数的数据包在这里来来往往。

    “这里可真热闹”

    “嘘,先别说话,马上要经过防火墙,藏好了,可别被发现了”,小P一把捂住了我的嘴。

    说完我们就来到了防火墙面前,当差的守卫查看了我们的源IP和端口,又看了目的IP和目的端口,接着瞟了一眼负载数据,当他望向我这边时,我紧张的大气都不敢出一声,把头深深的埋着。

    守卫凶神恶煞的问到:“你是去80端口的?这里面装的是什么?”

    “回大人的话,这里面是个HTML表单,这单业务比较急,还望大爷行个方便”,小P一边说一边悄悄给守卫的衣袖里塞了一些银两。

    “走吧,放行!”,总算等来了守卫的这句话。

    通过了安检,我俩被安排到了一个队列等待,一会儿,一个自称是Apache公司的线程大哥把我们取走了。

    栈溢出 & Stack Cannary

    线程大哥把我俩放到了一片陌生的区域。

    “你等我一下,我去打听下情况”,小P叮嘱完我后,和隔壁一个对象聊了起来。

    “我打听清楚了,这里是进程的堆区,你可还记得主人交代的任务吗?”,小P问我。

    “当然记得,我是shellcode,我要获得执行机会,潜伏起来,和主人取得联系,等待下一步指示”

    “嗯,很好,一会我会找机会让你获得执行机会,先等等”“你要怎么办到啊?”,我有点好奇。

    “你看到那个线程的栈没?”,小P一边说一边给我指。顺着小P指的方向望去,我看到了他口中所说的栈,线程大哥正在旁边忙碌,一会push,一会儿pop。

    “我看到了,你猜你是想用栈溢出攻击覆盖返回地址,劫持指令寄存器,让我获得执行机会吧?”,我转头看着小P。

    “小子,知道的不少嘛!不过你只回答对了一半,咱这次没法覆盖返回地址来获得执行机会”

    “哦,这却是为何”

    小P又指向了线程栈,“你看,返回地址前面有个8字节数字,那个叫Stack Cannary,是Linux帝国抵御栈溢出攻击的手段”

    “不就是8个字节的数字,有什么可怕的?”,我不屑一顾。

    “可不要小瞧了它,当栈溢出数据被修改后,函数return时,在从栈中取出返回地址之前会检查它有没有被修改,一旦被发现修改过,进程就会终止,咱们的计划不就泡汤了吗?”

    “这程序员还挺聪明的嘛!居然还做了检查”

    “这可不是程序员做的,这是GCC编译器干的,只要编译的时候添加了-fstack-protector标记就会自动添加,对原来的程序代码是透明的”

    听着小P的话,我陷入了沉思。

    C++虚函数表

    “如此一来,那岂不是不能使用栈溢出了?”

    “也不尽然。直接覆盖返回地址是基本不太可能了,过不了函数返回时的检查。但可以在它做检查之前就动手,抢先一步劫持执行流程,就没有机会做检查了。”,说完小P朝我眨了眨眼睛。

    还有这种操作,我还是第一次听说,“不覆盖返回地址怎么能劫持到执行流程呢?你打算怎么做?”

    “嘘!线程大哥来了!”我一下趴着不敢动弹,余光中瞥见线程大哥取出了隔壁对象的前面8个字节后就离开了。

     

    “好险,差点被发现,你呀,说话别那么大声,计划败露那就全完了,知道吗!”,小P把我训了一顿。

    “好啦,我知道了。我刚才问你的问题你还没回答我呢”,这一次我压低了音量。

    “你猜刚刚线程大哥过来读取的是什么?”小P神秘地说。

    “不是取的隔壁对象的内容吗?你也看到了啊还问我”

    “这我当然知道,我是问你那内容是什么?”

    “这我怎么知道,我又不知道那是个什么对象”

    小P用手臂把我的头挽在胸前,在我耳边轻轻说到:“他读取的应该是对象的虚函数表指针,你看线程大哥读完内容后,又去这内容指向的地方了,你再看那里有一个表格,表格里每一项都是一个函数的地址”我按他说的看过去,果如他所言,只见线程大哥读取了表格中的一项后转身就去执行那里的代码了。

    “你饶了半天,还没告诉我你打算怎么让我获得执行机会呢”,我又一次提出了我的疑问。

    “你别着急啊,这秘诀就在这虚函数表指针上。你再看看线程栈,瞧见没有,那里也有一个对象,咱只要把它的虚函数表指针覆盖,待会儿线程大哥调用它的方法时,来读取的地址,我就安排成你的地址,就能让你有机会执行了”
    我脑子飞速运转想象了一下这幅画面:

    “果然是妙招!不过你怎么知道对象的虚函数表指针在哪里呢?”,我向小P提出了疑问。

    “虚表指针一般都是在对象的头部,也就是最前面8个字节”

    “所有对象都是吗?”小P摇摇头,“那倒也不是,有些对象所属的类根本没有虚函数,那也就没有虚函数表,虚表指针更是无从谈起了。不过这个对象是有的,主人在创造我们时已经都提前研究好了。咱们只需静待时机,按计划行事即可。”

    DNS隐蔽通信

    “快醒醒,该我们上了”,小P把我叫醒,不知过了多少时间, 我竟然睡着了。

    只见线程大哥执行了memcpy,把我和小P一起复制到了栈里。


    我昏沉的脑袋一下子清醒了过来,下意识的看了一下之前那对象,现在他就在我上面不远处,已经被小P的身体覆盖掉了,再仔细一看这对象的前8个字节,指向的函数表就在我的头顶,而表中每一项都指向了我所在的地址,0xCC大人果然安排的天衣无缝。

    果不出乎所料,按照周密的计划,我终于等来了执行的机会,潜伏这么久,总算是可以活动活动了。


    “你在干嘛?”,小P大声喝住了我。

    “按照计划,我在和0xCC大人联系啊”

    “你就这样直接建立网络连接吗?一会儿防火墙就会发现了”,小P面色凝重。

    我有点不解,“那要怎么办?我怎么和大人联系上?”

    “临行前大人叮嘱我了,用DNS请求把数据带出去,把数据编码后作为请求的域名,分多片发出去”


    按照小P的策略,我把通信内容先进行了一次加密,然后再使用base64编码后,拆成了三段,准备用三个DNS请求给发出去。

    “等一下,你不能使用0xCC大人的IP作为目的IP地址,会被防火墙发现的,就使用这里默认的DNS服务器地址就好了”,小P又一次喝止了我。

    “使用这里默认的DNS服务器地址,那大人怎么能收到消息呢?”,我有点纳闷。


    “放心,路由器那里已经安排好了!”


    未完待续·······

    彩蛋

    “咦,DNS数据包发送失败了!”

    “应该是没有权限,快翻一下大人给你准备的Linux提权指南”

    欲知后事如何,请关注后续精彩......

    往期热门文章

    堆栈里的悄悄话——智能指针

    路由器里的广告秘密

    内核地址空间大冒险2:中断与异常

    一个DNS数据包的惊险之旅

    DDoS攻击:无限战争

    一条SQL注入引出的惊天大案

    内核地址空间大冒险:系统调用

    一个HTTP数据包的奇幻之旅

    远去的传说:安全软件群雄混战史

    默认浏览器争霸传奇

    我是一个流氓软件线程

    我是一个杀毒软件线程

  • 相关阅读:
    大数相乘
    分层打印二叉树
    sharepoint 编辑页面时应该注意的一些地方
    sharepoint2007在创建Web应用程序时的问题
    asp.net页面编码问题
    “ ”在IE和FF下显示不一致问题
    DataReader为数据源时的数据获取时的数据获取问题
    sharepoint个人视图修改问题
    母板页图片使用相对路径显示问题
    Web Part Templates for Microsoft Visual Studio .NET下载地址
  • 原文地址:https://www.cnblogs.com/xuanyuan/p/12293934.html
Copyright © 2011-2022 走看看