题目:小明拿到了XXX数据中心的口令后,为了确保口令被更改后仍能登陆数据中心,他从一位小伙伴那拿到了一个后门程序植入进了服务器。这个后门程序没有任何说明,但是小明迅速找到了使用方法。后门程序:http://bctf.cn/files/downloads/backdoor_844d899c6320ac74a471e3c0db5e902e
telnet地址:218.2.197.250:1337
关于这一题,down来所给的后门程序后,我的第一个习惯是用winhex看看,然后发现了文件头部神奇的字符串"ELF",大概知道这是一个Linux下的elf文件吧。于是乎,根据telnet地址,telnet之后,服务器发来大堆没用数据,然后就是提示我输入,如下
第一个反应就是这里会不会有缓冲区溢出问题。于是,我随便输了长长的一串东西,没有任何事。
接下来,带着之前的现象与疑问,我用IDA开始分析这个只有10k的所谓后门程序,然后找到了提示输入的这个字符串所在的位置
除了那段提示输入的字符串外,貌似还混入了其他不相干的字符串,先不管这些,直接找到了引用这段字符串的位置
(PS:因为分析完才写的这边博文,故以上变量已经被我进行了替换,各位可自行将其脑补回初始状态)
是不是看到了我们熟悉的printf,但是最重要的还是scanf这个函数,故我认定这段程序在我们对提示之时进行的输入肯定存在缓冲区溢出的问题。但是,从分析中可以知道输入缓冲区貌似没有在该函数段里定义,而是从外部传进来的。于是,先暂时浏览这个函数,而是找出调用这个函数的地方。于是来到了下图
可以看到输入缓冲区是定义在调用函数里的,只不过该缓冲区在被传入我们发生输入的那个函数里时,似乎还被传进了一个叫做sub_8048D92的函数里(在这之前我们的输入缓冲区是没有出现过的),于是我又点击去看来一下,突然有种被坑的感觉……
好吧,看样子我们的缓冲区地址并没有在这里面被处理,于是跳出来这里,继续回到刚刚scanf那。
说实话,这段代码在我看来由于没有对我们的input产生任何影响,因此我也就暂时将其认为无用的吧,然后继续往下看
到这里开始到重点了
是不是有熟悉的感觉了?这里实际上就是取我们输入的第一个字符与'N'或者'n'进行比较,如果与之相等则会跳到该函数尾部的一个return上,则对应于telnent上的情况就是我们的链接断开。但是如果不是这两个字符大头的话呢?我们继续往下看
嘿嘿,到这里貌似开始进入重点了,首先是之前我们看到某个字符串的地址在这里用来赋给了一个变量,然后就是将两个字符串的长度都存进了相应变量里,这里我已经予以标出。接下来就开始进入一套循环了
可以看到,当满足循环条件,即变量index<input_len时,将执行右边的代码,而右边的这块代码我分析出来的结果就是一个对输入进行加密的代码段,加密手段是与之前我们见到过的那段字符串按照如下规律进行加密:
input[index]= input[index]^salt[index%salt_len]
(为什么是这么加密的这里我就不分析了,有兴趣的朋友可以自己尝试看看)
当输入被简单加密后,将会进入左边的代码端,是不是看到熟悉的memcmp,参与比较的一个地址就是我们的已经经过加密的输入,另一个地址,如果细心的朋友看到了会觉得眼熟。没错,这就是出现在之前坑了我么的那个函数段里出现的地址(其实也不坑了),而这个地址里的数据是被初始化过的,我们根据之前的记录,分析出我们的输入将会和一下10个字符进行逐一比较:n0b4ckd00r(6eh 30h 62h 34h 63h 6bh 64h 30h 30h 72h)。
如果比较通过了我们会开始下面这段代码,而不通过则会直接return 1.
如果比较通过,我们发现了很重要的一步,就是call eax这里,因为这个eax的值来自的正是input[10]的值。
至此,如何利用telnet输入来造成缓冲区溢出,进而拿到控制权的轮廓就已经明晰了,于是我们来整理一下这个过程
向服务器发出构造过的数据->内部通过异或加密->加解后的前10个数据是否与内部的某个数组的值相等,相等的话则取我们输入缓冲区的第十一个元素的地址作为被call的对象……
因此将这段可以被利用的汇编还原成C后,大概就是这样的
int func(char *input){ int index; char * salt; int inputlen; int saltlen; void (*leak)(); printf("\nReplay?(y/n)"); fflush(stdout); scanf("%s",input); if(input[0]-'n'!=0 && input[0]!='N'){ salt = ""; inputlen = strlen(input); saltlen = strlen(salt); index = 0; while(index
不过,我们在还原的C语言中貌似与之前的汇编的不符合呀。确实是这样的,之前我说过的那段没有涉及到我们输入的函数,我个人估计可能是主办方加的花指令。
至此,由于掌握到了构造输入的规律,关于小明是如何快速掌握使用方法的问题就算解决了~!
(PS:本人第一次写与逆向有关的分析,如有错误或者遗漏,希望大神们可以给小弟指出,小弟在此谢过啦)
(PS:因为一直没拿到shellcode,所以以为是不是过程有错,今天看到有别的参赛童鞋也发了类似的文章~~)