Oracle TNS 协议分析——一、系列开篇:方法论及基础知识

前言

Oracle 客户端与服务端采用TNS做为其数据交换协议。TNS全称Transparent Network Substrate,是与Oracle数据库服务器通信的专有协议,该协议为Oracle内部协议,不向外界公开,在此以前,已经有一些反向工程的实践对各个版本的TNS进行解析,好比wireshark就有专门的TNS分析工具,中文的协议解析可参见《ORACLE协议分析》本系列基础介绍中关于TNS包基础格式,及链接包等均沿用wireshark提供的格式。本系列重点分析TNS 314下的客户端与服务端之间的通信,经过抓包分析,查看在不一样客户端,不一样服务端状况下传输方式的不一样,尝试还原其协议细节,实现对协议中一些关键内容的解析,如登陆用户名,协议版本,oracle版本,sql命令,同时给出示例LUA代码。为了分析不一样客户端架构,本系列使用了两类客户端32位与64位客户端进行测试,同时重点使用了多个厂商的不一样客户端(Navicat、PLSQL、SQLPlus)同时也兼顾分析了OJDBC Thin Client的状况。服务端采用11g和12c两个版本。本文主要分析链接创建,身份验证、命令传输和返回、以及错误信息返回的过程。html

方法及工具

主要采用wireshark对客户端与Oracle间的通信进行抓包分析。linux

客户端:sql

服务端数据库

Navicat Premium 15 64bitwindows

Oracle 11g 64bit Linux服务器

Navicat Premius 12 32bit架构

Oracle 12c 64bit windowsoracle

PLSQL 11.2 64bitsocket

 

SQLPlus 11.2 64bit工具

 

OJDBC8(Thin Client)

 

分析过程当中关于包类型定义等参考wireshark的tns 解析器代码。

代码示例说明

代码示例用lua写成,能够在openresty15 64bit window或linux版本下运行

其中从socket流中解码用到了string.unpack 和pack 方法是纯lua开源实现,是对c语言 lua 扩展lpack 的纯lua模拟

系列目录

1、方法论与基础知识

2、基础包结构

3、链接认证流程与包分析

4、SQL执行流程与包分析

5、错误返回

协议介绍

Transparent Network Substrate顾名思义是对传输层协议无关,根据Oracle的介绍:TNS底层支持TCP,SSL TP,SDP,named pipeline等协议。在OSI七层协议体系中,TNS属于会话层协议

详细的介绍可参考

https://docs.oracle.com/cd/B28359_01/network.111/b28316/architecture.htm#NETAG004

 

Oracle版本与TNS协议版本对应关系

Oracle 版本

TNS版本

11gr2 12c

tns314

10g

313

9i

312

X

311

8i

310

 

不一样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命令格式:

 

32bit

64bit

 

序列号

1

1

 

Piggy command

9 or 13

16 or 20

 

Buddle execute command 035e

变长

变长

相关文章
相关标签/搜索