OracleTNS协议分析——1、系列开篇:⽅法论及基础知识
前⾔
Oracle 客户端与服务端采⽤TNS作为其数据交换协议。TNS全称Transparent Network Substrate,是与Oracle数据库服务器通讯的专有协议,该协议为Oracle内部协议,不向外界公开,在此之前,已经有⼀些反向⼯程的实践对各个版本的TNS进⾏解析,⽐如wireshark就有专门的TNS分析⼯具,中⽂的协议解析可参见本系列基础介绍中关于TNS包基础格式,及连接包等均沿⽤wireshark提供的格式。本系列重点分析TNS 314下的客户端与服务端之间的通讯,通过抓包分析,查看在不同客户端,不同服务端情况下传输⽅式的不同,尝试还原其协议细节,实现对协议中⼀些关键内容的解析,如登录⽤户名,协议版本,oracle版本,sql命令,同时给出⽰例LUA代码。为了分析不同客户端架构,本系列使⽤了两类客户端32位与64位客户端进⾏测试,同时重点使⽤了多个⼚商的不同客户端(Navicat、PLSQL、SQLPlus)同时也兼顾分析了OJDBC Thin Client的情况。服务端采⽤11g和12c两个版本。本⽂主要分析连接建⽴,⾝份验证、命令传输和返回、以及错误信息返回的过程。
⽅法及⼯具
主要采⽤wireshark对客户端与Oracle间的通讯进⾏抓包分析。
客户端:服务端
Navicat Premium 15 64bitOracle 11g 64bit Linux
oracle登录命令Navicat Premius 12 32bit Oracle 12c 64bit windows
PLSQL 11.2 64bit
SQLPlus 11.2 64bit
OJDBC8(Thin Client)
分析过程中关于包类型定义等参考wireshark的tns 解析器代码。
代码⽰例说明
代码⽰例⽤lua写成,可以在openresty15 64bit window或linux版本下运⾏
其中从socket流中解码⽤到了string.unpack 和pack ⽅法是纯lua开源实现,是对c语⾔ lua 扩展lpack 的纯lua模拟
系列⽬录
协议介绍
Transparent Network Substrate顾名思义是对传输层协议⽆关,根据Oracle的介绍:TNS底层⽀持TCP,SSL TP,SDP,named pipeline 等协议。在OSI七层协议体系中,TNS属于会话层协议
详细的介绍可参考
Oracle版本与TNS协议版本对应关系
Oracle 版本TNS版本
11gr2 12c tns314
10g313
9i312
X311
8i310
不同driver的差异
Oracle Client调⽤服务端,最终实现模式主要是 OCI和ThinDriver。
1. OCI是C 语⾔的lib,和平台相关,有linux和windows 版本;
2. ThinDriver是纯Java的包,与平台⽆关;
很多⼈反映反编译Java代码看到的情况和⽤plsql等⼯具调⽤实现不同,⼤概率是此原因,但⽆论Navicat,SQLPlus,PLSQL都⾛的OCI。
相应JDBC有两种
1. JDBC OCI Driver ⾛OCI调⽤,
2. JDBC Thin Driver⾛纯Java实现
ThinDriver的实现与OCI的实现从抓包上看,在连接建⽴和认证过程差距不⼤,但Data包差距很⼤,⽆论Endian模式,还是具体数据类型封装格式都有较⼤差异,在ThinDriver的实现中,很少未见出现Piggy Command的情况,所有⾮0或⼤于⼀位的byte或者int变量都会严格前序长度字段。
不同客户端实现的差异
相同位数(都是64位或者都是32位)的不同客户端的实现在抓包分析时也不太相同,⼤概表现有两个
⽅⾯,⼀个是流程上的不同,⼀个是数据上的不同,我们以执⾏select语句为例,PLSQL和Navicat在流程上稍有差别,下图是Navicat Premium15 执⾏的流程
1-------
Data Piggyback(11) Cursor Close All(69)
注意此处也有可能是 03 5e
----->具体语句
2<-----Data DescribeInfo(10) 17-------返回列
3-------Data UOCIFun(03) ExecuteARow(04)----->
4<-----Data ReturnStatus(04)-------
5-------Data UOCIFun(03) FetchARow(05)----->获取其他值
6<-----Data RowTransferHeader(06) 01-------返回值
⽽PLSQL中没有中间3和4的部分。
数据上的不同有的时候是⼀些数据长度,有的时候是⼀些设置位上的差异,⽐如对于select 的Piggycommand(pagekage type 0x6 DataId=0x11 CallID=0x69)
这个包内容在Sqlplus,plsql,navicat上不仅内容,长度也就有差异
语句Plsql Sqlplus Navicat
Select fe ff ff ff ff ff ff ff
01 00 00 00
04 00 00 00
fe ff ff ff ff ff ff ff
01 00 00 00 00 00 00 00
05 00 00 00
当没有输⼊;05会变03
fe ff ff ff ff ff ff ff
01 00 00 00
05 00 00 00
不同客户端位数间差异
32位客户端和64位客户端也有不同,⽐如32位客户端中所有0xfe ff ff ff ff ff ff ff 全部以其补码01代替。但64bit 的ThinClient也有此情况,所以很难说这些现象是否完全由位数造成,这会导致许多协议中许多部分的长度根据位数不同有⼀定区别。⽂中凡协议均会标注出不同客户端位数下的长度,若未单独标注,则说明⼆者⽆不同,例如Buddle execute Command命令格式:
32bit64bit
序列号11
Piggy command9 or 1316 or 20
Buddle execute command 035e变长变长
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论