游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4170|回复: 0

提升本版人气:编程让你映射1521端口,在外网连接Oracle,

[复制链接]

2

主题

13

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2006-1-7 11:05:00 | 显示全部楼层 |阅读模式
做游戏, 乍么可能不跟数据库打交道喃?

(如果你用oracle.odac并有什么VPN之类的话,其实就无需此文了)
(转帖,请注明原创作者: 成都.lck 谢谢)

说明:  此文仅作技术讨论、学习为目的,请自行遵守相关法律,本文作者不承担责任后果.

环境:
       局域网内网地址192.168.2.18上安装了oracle9,TNS端口1521,路由器虚拟服务转发1521端到此地址。想到这样的话,就可以SOHO了.

状态:  (如果你知道oracle的1521端实际作用可跳过)
       外网安了oracle客户端和odac,odac使用net方式,连接成功,并可取出数据。但是ora客户端连管理器的连接测试都通不过,发现连接测试时所连接的地址并非外网地址,变成了192.168.2.18(端口不是1521).
       在内网中用PLSQLDeveloper连接后,发现登陆后的实际操作并非是连接1521端口,且有时会变换新端口

试手开始:
       准备了Indy的MappedTCP环境, 过程如下:
       1.client发送请求数据, 中间包含了"(HOST=xxxxx.xxxx.xxx)(PORT=4414)",其中HOST为ora连接管理器中配置的主机名,端口同样. 另外后面还有一个HOSP=当前机器的机器名
       2.ora每次的命令封包, 头两个字节为Word(16位), 代表此次封包的总长度(注意也包含了Word自身), 第五个字节在第一次连接时为byte(1), 此后知道应该是命令号, 命令号的长度不清楚, sorry。命令号后的字节不清楚用途,但有时候是记录此次封包内下一段的字节长度(同样包含长度Word自身).
       3.服务端收到后,1521端返回了命令号为byte(5)的命令,数据的确包含了新分配给客户端连接的端口和IP,OK了,改数据
      
修改思想:  

       1.在TIdMappedTCP基础上继承, 假设出口地址为4444, Mapped地址当然为192.168.2.18:1521,
       2.Client发命令byte(1)时,保存客户端请求的地址,等会儿要返回给客户端的.
       3.Server返命令byte(5)时"(HOST=192.168.2.18)(PORT=1031)",把HOST换为刚才保存的地址(也就是说叫客户端再连此IP的程序), 端口1031怎么办喃?  当然是保存起来,由Mapped程序连接, 客户端又连哪儿? 这样: 再内置个MappedTCP服务,Mapped到5号命令返回的Port, 出口地址嘛正好设个4447端.  所以还得把封包中PORT换为4447.
      
       贴个修改包长度的代码:
      //changedPackage为已经换了HOST和PORT的string
      //注意了哈!!! ora封包大小虽为word, 但与delphi中的word相比,
      //其高位和低位正好是相反的, 得转换一下
      //
      type
        psWord = ^tsWord;
        tsWord = packed record
           b1 : byte;
           b2 : byte;
        end;
      var
        ppp : PChar;
      begin
        wSize := Length(changedPackage);
        ppp := @LParm[1];
        
        //反转delphi的word
        psWord(@wSize2).b2 := psWord(@wSize).b1;
        psWord(@wSize2).b1 := psWord(@wSize).b2;
        //写新的大小
        Move(wSize2, ppp^, 2);
         
        //5号命令中子长度, 正好是第8位开始
        Inc(ppp, 8);
        //读旧的大小再-10
        move(ppp^, wSize2, 2);
        //写新的子长度, -10是把总长度占的两个字节算进去了的
        wSize := wSize-10;
        psWord(@wSize2).b2 := psWord(@wSize).b1;
        psWord(@wSize2).b1 := psWord(@wSize).b2;
        Move(wSize2, ppp^, 2);
         
       4.最后,被保存的1031端口怎么办?
         可以把端口地址放到一个队列中,当客户端连接到4447端口,POP出一个端口和缓存的HOST, 作内置IdMappedTCP的MappedHost和MappedPort,  可以将BackMapped.OnConnect := BackConnect, 并在BackConnect中POP出缓存的Port, 因为:

       procedure TIdMappedPortThread.OutboundConnect;
       Begin
         FOutboundClient := TIdTCPClient.Create(NIL);
         with TIdMappedPortTCP(Connection.Server) do begin
         try
            with TIdTcpClient(FOutboundClient) do begin
              Port := MappedPort;
              Host := MappedHost;
            end;//with
            DoLocalClientConnect(SELF); //这里执行OnConnect事件, 下面就会Connect了哈

            TIdTcpClient(FOutboundClient).Connect(FConnectTimeOut);
            DoOutboundClientConnect(SELF);
         except
          on E: Exception do begin
            DoOutboundClientConnect(SELF,E);
            Connection.Disconnect;
          end;
         end;//trye
         end;//with
       End;


巧功告成:
     此程序可以放到可以访问192.168.2.18地址的任意机器上, 程序只监听4444和4447两个端口, 因此,你可以到路由器中设置转发4444/4447两个端口(4444相当于1521端口, 1521端口本身只是作监听端口转发,不作登陆/SQL数据传送滴), 从此便可以远程外网连接ORA了,爽吧,加好密,小心被攻击。

     多看看Indy的TIdMappedFTP对你有帮助, 此思想等于是用4447这个不变应了ora的万变端口. 但ORA有加密封包的功能, 加密后, 就得想办法解密了哈,我想还是可行滴! (odac就做到了的)

[em3] [em3] [em3] [em3]
幺儿乖乖爸爸爱
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-23 03:47

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表