前不久我参加的Defcon Qualification CTF十分有趣,想将这次挑战赛中我用时最长的一个关卡细节分析分享给各位。

这一关是位PWNABLE目录下的“Twentyfiveseventy”,通常来说这个目录下的关卡应该是通过一个漏洞利用来获取通关flag。下载这个文件[文件可在文后下载]之后,使用IDA-Pro打开,然后分析这个程序是做什么的,以及可能存在的一些BUG。通过逆向工程,我渐渐意识到这个程序中似乎用到了SNMP协议,最后看到挑战名指向RFC 2570才最终确认为SNMP V3版本。

通过对程序进行反汇编分析,了解到实际上程序在启动时就将挑战赛的flag加载进了内存之中。这使我更加确信常用的手法已经无法解决这个问题了。

进一步分析显示,只要通过正确验证以及加密的SNMP V3 GET包收到正确的OID请求,那么程序就会返回flag的值。
我第一个念头就是想着先找一个开源的SNMP V3程序,来创建一个这样的数据包。然而我注意到挑战赛中是在TCP中实现的SNMP而不是传统的UDP。这也意味着我挖出的大部分库都需要转换为TCP,恍惚记得年前我在Java环境中执行过SNMP V3库,对于这个挑战或许有帮助哦。

这一挑战看起来似乎需要进行大量的编程,即便是我已经拥有了执行库。再次检测之前的反汇编,分析看是否有明显的BUG跳出。从我所观察到的情况来看,程序实现SNMPV3采用MD5作为散列值,DES_CBC进行加密。

下图显示了SNMPV3的整体结构

挑战赛中的该二进制程序实际上有一个很严格的解析器,检测字段长度,值等。这些检测通常发送SNMP报告并填充一个新的SNMP GET内容就能够通过。SNMP报告是一个大多数字段值都为空的包。接着SNMP服务端将发回一个SNMP响应包。这其中的字段有Engine Id, Engine Time,和Engine Boots.

为了通过解析器,协议中仍然有些字段需要我们仔细确定。在程序数据部分中我发现了username, engine id,以及目标OID。他们分别为 “lbs”, “0x80007a6903deadbeefcafe”, “1.3.6.1.2.1.1.5.0.0.0” 。剩下的key字段需要构造一个合适的包,审查的设置加密key的函数,key实际上是随机产生的。engine time设置seed并返回客户端,作为一个增加的测试完整性,engine boots的值是由第一个随机生成的数字获得,可以用来验证随机数生成算法是否正确。

将engine time本地化,应该能够生成相同的随机加密key。由于我的库是在Java中执行,我需要执行一些JNA代码来使用本机的libc随机函数确保算法一致

interface CLibrary extends Library { 
CLibrary INSTANCE = (CLibrary) Native.loadLibrary(“libc”, CLibrary.class); 
void srand(int an_int); 
int rand();
}
public static byte[] get_auth_key( long passedSeed, long engineBoots ){ 
byte[] retKey = new byte[32];

 //Seed it 
 CLibrary.INSTANCE.srand((int)passedSeed); 
 //Throw away one 
 long tempNum = CLibrary.INSTANCE.rand(); 
 long bootTest = (( tempNum >> 32 ) >> 25) + (( tempNum) & 0x7F )   
 - (( tempNum >> 32 ) >> 25); 
 if(engineBoots == bootTest){   
 //Create the encryption key   
 for( int i = 0; i < 32; i++){     
 long retVal = CLibrary.INSTANCE.rand();     
 retKey[i] = (byte) ((retVal % 94) + 32);   
 } 
 }
 return retKey;
 }

接下来我们就要寻找突破身份验证的方法,我的一位队友发现了突破困境的方法。解析器仅仅是拷贝并验证md5的字节数,它的长度值在包中是指定。另外允许用户设置长度,这意味着有1/256的机会,与第一个字节匹配。

最后将所有信息综合,我打开Java SNMP客户端,经过十几次尝试最终获得flag。q@)$asllqkw4h5】

下载链接

链接:http://pan.baidu.com/s/1dD0aXA5 密码:rvvn

*参考来源securifera,译者/鸢尾 转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)

源链接

Hacking more

...