记一次C/S架构的渗透测试
概述
目标站点是http://www.example.com,官网提供了api使用文档,但是对其测试后没有发现漏洞,目录、端口扫描等都未发现可利用的点。后发现官网提供了客户端下载,遂对其进行一番测试。
信息收集
先抓了下客户端的包,使用Fiddler和BurpSuite都抓不到,怀疑走的不是HTTP协议,用WireShark查看其确实用的是HTTP协议,但是数据包不好重放,这里最后使用了WSExplorer抓指定进程的包,成功抓取到通信的数据,抓到的数据如下,绿色的是请求包,红色的是响应包。

数据包又分为两部分,一个是请求行和请求头。

一个是请求正文。

拼接起来即可放到BurpSuite中进行数据包的重放

测试过程
可看到请求包经过了加密再传输,返回的响应包也经过了加密。但是加解密总归是在客户端进行的,所以可从分析客户端入手。
使用Exeinfo PE查壳,可得知使用的是.NET框架 C#开发的程序。

可以使用dnspy,针对.NET程序的****工具,对客户端的加解密进行分析。打开后发现类及方法的命名都是无规律的数字字母,代码做了混淆。

混淆了的代码不利用阅读分析,可使用De4Dot尝试反混淆,支持很多种混淆加密工具混淆过的源码。
de4dot-x64.exe origin.exe
即可得到反混淆后的程序 origin-cleaned.exe

将反混淆后的程序拖入dnspy查看,可看到基本已还原,提高了可读性。

因为其通信采用的是HTTP协议,又发现有个类名为HttpHelper,跟进分析,代码不多看到一个Post函数,疑似为对数据加密并发起Post请求的方法,如图。
调用了MM.Encrypt()对请求的参数进行加密,跟进方法,发现其中关键的加密函数应该就是MM类下的test05函数。

下断点,验证程序是否调用此函数进行加密并传输,我在明文及密文处下了断点。

F5启动程序,输入账号密码test123456,登录。

程序在断点处停了下来,明文中包含我输入的账号test123456和md5加密过的密码。
放行,得到经过加密的内容,可确定就是调用了此处的加密函数。

后又证实响应包解密调用的是MM类下的test06函数,请求包加密函数test05及响应包解密函数test06都是调用Dll中对应的函数。
此处加解密调用的是两套方法,不能用解密函数去解密请求包加密后的数据。为了方便测试,以及快速加解密,将其加解密函数扣出来,同样调用Dll里的函数,编译成一个独立的程序,这样也不用分析算法。
这里我使用的是SharpDevelop编译的,使用Visual Studio总是会报错…
public static string decryptResponse(string cipher){
byte[] bytes = Encoding.UTF8.GetBytes(cipher);
byte[] array = new byte[bytes.Length + 128];
int count = Program.test06(ref bytes[0], ref array[0]);
string text = Encoding.UTF8.GetString(array, 0, count);
return text;
}
public static string encryptRequest(string plain){
byte[] bytes = Encoding.UTF8.GetBytes(plain);
int num = bytes.Length * 2 + 128;
if(num<32){
num = 64;
}
byte[] array = new byte[num];
int num2 = 0;
num2 = test05(ref bytes[0], ref array[0]);
string result = Encoding.UTF8.GetString(array, 0, num2);
return result;
}
加密
解密

再用Python的Flask框架在本地写一个代理转发程序,方便在BurpSuite中进行重放测试。
流程如下:
- 本地发送明文数据包到代理
- 代理接收到请求包
- 调用程序对请求包进行加密
- 将加密后的数据包转发给服务器
- 调用程序对服务器返回的内容解密
- 返回给明文数据到本地
from flask import request, Flask
from urllib.parse import quote
import requests
import os
headers = {
'User-Agent': 'Mozilla',
'Content-Type': 'application/x-www-form-urlencoded',
'Accept-Encoding': 'gzip, deflate',
}
app = Flask('example')
@app.route('/example', methods=['POST'])
def proxy():
form = request.form
request_plain = ''
for key in form:
request_plain += '&{}={}'.format(key, form[key])
response_plain = test(request_plain)
return response_plain
def encrypt(filename):
encrypt_cmd = 'crypto.exe -encrypt {}'.format(filename) #要加密的内容 从文件读取
result = os.popen(encrypt_cmd) # 执行exe
request_cipher = quote(result.read()) #加密后的内容 经过一次url编码把 + 号 转成 %2B 服务端才能识别
return request_cipher
def decrypt(filename):
decrypt_cmd = 'crypto.exe -decrypt {}'.format(filename) #要解密的内容 从文件读取
result = os.popen(decrypt_cmd) # 执行exe
response_plain = result.read() # 读取解密后的内容
return response_plain
def test(request_plain):
url = 'http://example.com/api/'
plain_txt = 'plain.txt'
with open(plain_txt, 'w') as f1:
f1.writelines(request_plain) # 存放明文到plain.txt
request_cipher = encrypt(plain_txt) # 加密明文
response = requests.post(url=url, data=request_cipher, headers=headers) #发送请求
cipher_txt = 'cipher.txt'
with open(cipher_txt, 'w') as f2:
f2.writelines(response.text) #存放密文到cipher.txt
response_plain = decrypt(cipher_txt) # 解密密文
return response_plain
if __name__ == '__main__':
app.run(host='0.0.0.0', port=9999, debug=True)
这里每次请求的接口都是一样的,改变的只是请求体中的参数。在CodeService中有所有接口的明文,全部提取出来。
即可正常的在BurpSuite中进行测试~
最后成功在一个接口中发现SQL注入。


智能推荐
springboot1.4.1整合logback 遇到的问题
springboot1.4.1整合logback 遇到的问题 项目使用了springboot1.4.1整合logback,然而设置的过期时间15 并没有生效, 2GB达到2G自动删除也没有生效,仅仅实现了按大小分割。 经过查看pom 父工程内的源码发现是默认的logback版本是1.1.7,而过期时间配置是在logback 1.1.8以后才支持的。 不得不说这是springboot1.4.1 的b...
记一次C/S架构的渗透测试
概述 目标站点是http://www.example.com,官网提供了api使用文档,但是对其测试后没有发现漏洞,目录、端口扫描等都未发现可利用的点。后发现官网提供了客户端下载,遂对其进行一番测试。 信息收集 先抓了下客户端的包,使用Fiddler和BurpSuite都抓不到,怀疑走的不是HTTP协议,用WireShark查看其确实用的是HTTP协议,但是数据包不好重放,这里最后使用了WSExp...
Linux:结合Securecrt进行文件上传(lrzsz)P2
1、安装rzsz软件 2、点击Scurecrt的option——X/Y/Z配置上传和下载目录 3、首先在Linux里切换到一个目录,然后用rz命令,文件就会上传到钙Linux的目录下 只要敲rz即可,然后在弹出的对话框里选择需要上传的文件即可 4、下载文件用sz 下载单个文件:在当前目录下有该文件 sz filename 下载...
SQL 提示作为 布局 生存工具指南
下面是一些展示AdventureWorks中表现最好的销售人员并列出他们的经理的结构化查询语言代码。 它产生以下结果。 所以,代码是有效的,但它是丑陋的。 如果我需要理解和改进代码,我首先需要把它变成可读的形式。 我有结构化查询语言提示,所以我可以按下计算机的ctrl按键键 踢你自己),它会应用默认的内置代码样式,并对此进行修复。 不,不是,因为我相信你仍然不喜欢它的格式。 没有两个开发人员能够就...
Vue+Springboot解决数据传输时参数格式不匹配问题
前端:使用的是ant design vue ,端口号为8000 后端:使用的是springboot框架开发,端口号为8080 需求:已经解决跨域问题,前端发送登录的信息给后台,后台接收不到 样例: 前端: 后台: 请求的数据格式为json格式,后台参数类型不匹配 解决方案 第一种: 修改后端,参数类型: 第二种方式: 在前端vue框架中加入qs插件,qs 是一个增加了一些安全性的查询字符串解析和序...
猜你喜欢
Flex布局做出自适应页面--语法和案例
本文发布在: github项目地址:https://github.com/tenadolanter/flex-layout-demo SegmentFault地址:https://segmentfault.com/a/1190000012916949/ CSDN地址:http://blog.csdn.net/qq_34648000/article/details/79115294 博客园地址:ht...
Java - 基于 Apache POI 创建 Excel 文件
基于 Apache POI 创建 Excel 文件 准备 新建 Maven Project,引入依赖: 创建行和列 设置列宽 设置列宽(第 19 行): 注意:其他行的首列的宽度是受第一行、第一列的影响而变宽,并非我们设置的。 设置字体颜色 设置字体颜色(第 25 ~ 31 行): 设置网页超链接 设置网页超链接(第 18、27 ~ 29 行): 参考 java操作excel常用的两种方式...
python基础-质数判断及优化
文章目录 一、问题描述 二、代码 三、问题2优化 四、数学补充 一、问题描述 质数判断条件: 质数是只能被1和它自身整除的数,1不是质数也不是合数。 二、代码 问题1代码 问题2代码 三、问题2优化 优化方案: 模块,通过模块可以对Python进行扩展 引入一个time模块,来统计程序执行的时间 time()函数可以用来获取当前的时间,返回的单位是秒 获取程序开始的时间,以运行时间来衡量优化结果。...
部署jenkins+svn持续集成
部署环境:CentOS7+jdk8 svn版本是windows,jenkins是linux 然后下载jenkins的yum源文件,获取jenkins的下载** 输入本机ip+端口,然后在这个web界面显示的路径里把**复制出来,下一步后选择推荐插件安装,后面需要用的插件可以再安装,等待安装完成后,第一次登陆不需要密码,可以设置登陆用户。 然后配置全局设置 如果你是yum安装得git,按照我得写,如...
7 パズル 反向BFS
题目 题意:7数码问题。在2×4的棋盘上,摆有7个棋子,每个棋子上标有1至7的某一数字,不同棋子上标的数字不相同。棋盘还有一个空格(用0表示),与空格相邻(上下左右)的棋子可以移到空格中,该棋子原先位置成为空格。给出一个初始 (保证可以转移到最终状态),找出一种从初始状态转变成给定最终状态的移动棋子步数最少的移动步骤。 输入:多组输入,每组8个数,表示初始状态前四个数为第一行从左到右,...
