Oracle内部的核心包体、函数都是被加密过的。因为必须要知道spacemanager内部的核心算法是如何
实现的,必须要破解下。这个文件是说明如何解密了。
不过还有一个大名鼎鼎的工具,是直接出结果的:
当然,收费的,200美元。。。今天找了个中国有个人破解了,刚才问他,200块,砍到100,便不能再
砍了。
终于跟位大牛要到这个oracle内部加密算法的pft说明文档,见附件的pft文件。再帖下itpub的
itisamos写的文章:
在ORACLE9I下的UNWRAP,老外研究得比较彻底了,由于涉及到语法构成分析,比较麻烦,
这里就不多说了,只讲讲在10到11G下怎样搞。在这个版本的ORACLE下,UNWRAP的理论
依据都来源于"Theoraclehacker'shandbook"byDavidLitchfield
在书中介绍了WRAP后的代码是BASE64编码的,也就是说如果我们要UNWRAP,首先就要进
行BASE64的解码;其次,书中也告诉我们,解码后的每个字节需要根据一个替换表进行单独的替换;
替换后的字符串需要按LZ算法进行解压;最终可以得到源码的明文。是不是挺简单的?如果书上说的是
正确的,进行UNWRAP唯一的问题就是这个替换表了。要得这个替换表,那么我们可以做这样一个假设:
既然我们通过SQL可以这样对某过程做DBMS_加密可以得到密文,如下所示:
lectdbms_('createprocedurea')fromdual;
那么对这部份密文的正文部份进行BASE64解码的值与未加密正文('procedurea')直接进行L
Z压缩后的值必然是一一对应的,且两个串的长度也是相等的。这是一个重大的前提!通过这种假设,肯
定就能得到替换表,替换表是按字节来计算的,所以应该有二个列,其中一列代表BASE64解码后的
字节值(十六进制00到FF),另一列代表替换列(另外提醒一个问题,BASE64列不能出现重复
值,哈哈,可以想像得到,如果有重复值就完了)。我的意思就是对密文进行BASE64解码后,将对
应的密文的正文部份按字节替换成替换表中预先算出来的字节,最后直接按LZ算法进行解压,替换表正
确的情况下,明文就应该出来了。
这里需要解释4个问题,密文的正文部份是什么?未加密正文为什么要用'procedurea'而不加上'Create'
部份?LZ算法压缩在ORACLE中怎么办?BASE64编码与解码在ORACLE中怎么办?
BASE64编码地球人都知道,在ORACLE中有现存的工具包进行编码和解码,我们将用到BAS
E64的解码,具体包是:_64_decode。用的时候还需要另一个过程来将字符串转换
为RAW格式:__to_raw。LZ压缩很常见,不过懂得内部算法的人很少,ORACLE
中也有现存的工具包,我这里用的是老外的一个JAVA包。在使用这个LZ工具包时,涉及到一个压缩
级别参数,这个等级参数不一样,压缩得到的字符串完全一不样。有人可能要问,这样搞岂不是没法得到
替换表了吗?是的,但也不完全正确。因为可供选择的等级参数有限,俺们还能从0等级开始一个一个进
行测试,
看到底哪个参数是ORACLE系统用的来WRAP的。嘿嘿,ORACLE用的是“9”等级。创建过
程或包时如果没有CREATE部份,ORACLE肯定要报错;同样DBMS_也不能缺少这
个“create”,否则就要报错。但对于过程或包的SOURCE,查阅系统视图DBA_SOURCE的TEX
T列就知道了,肯定没有CREATE这一句。
说到密文的正文部份,首先要看下面的例子:
SQL>lectdbms_('createprocedurea')fromdual;
createprocedureawrapped
a000000
354
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
c38
8BgMHdmA3Qg9IbJmntlZoZQoHwcwg5nnm7+fMr2ywFxakaamb40d1Q=
这里要解释一下,加密后的代码中354与DB的版本有关,abcd后的7与创建的对象类型有关,也就是
7为存储过程,另外的c38有其他意义,这里就不多说了。从8BgMH开始,BASE64解码后的前二
十个字节是SHA1-HASH值(前面那本书说的哈),所以解码后的第二十一个字节开始就是正文了。
为了下一节的实践活动,嘿嘿,我们先把JAVA包创建好,用以进行LZ压缩与解压,如下所示(全部用
SYS用户来做):
createorreplacejavasourcenamedUNWRAPPER
as
.*;
.*;
publicclassUNWRAPPER
{
publicstaticStringInflate(byte[]src)
{
try
{
ByteArrayInputStreambis=newByteArrayInputStream(src);
InflaterInputStreamiis=newInflaterInputStream(bis);
StringBuffersb=newStringBuffer();
for(intc=();c!=-1;c=())
{
((char)c);
}
ng();
}catch(Exceptione)
{
}
returnnull;
}
publicstaticbyte[]Deflate(Stringsrc,intquality)
{
try
{
byte[]tmp=newbyte[()+100];
Deflaterdefl=newDeflater(quality);
ut(es("UTF-8"));
();
intcnt=e(tmp);
byte[]res=newbyte[cnt];
for(inti=0;i
res=tmp;
returnres;
}catch(Exceptione)
{
}
returnnull;
}
}
/
alterjavasourceUNWRAPPERcompile
/
然后用包把JAVA声明进来:
createorreplacepackageamosunwrapper
is
functiondeflate(srcinvarchar2)
returnraw;
functiondeflate(srcinvarchar2,qualityinnumber)
returnraw;
functioninflate(srcinraw)
returnvarchar2;
end;
/
createorreplacepackagebodyamosunwrapper
is
functiondeflate(srcinvarchar2)
returnraw
is
begin
returndeflate(src,6);
end;
functiondeflate(srcinvarchar2,qualityinnumber)
returnraw
aslanguagejava
name'e(,int)returnbyte[]';
functioninflate(srcinraw)
returnvarchar2
aslanguagejava
name'e(byte[])';
end;
/
创建好了工具,我们先来看看下面的SQL:
withsrcAS(lect'PACKAGEa'txtfromdual),
wrapas(,dbms_('create'||)wrapfromsrc),
substas(lect
substr(utl_64_decode(utl__to_raw(rtrim(substr(,instr(,
chr(10),1,20)+1),chr(10)))),41)x,
e(||chr(0),9)d
fromwrap)
lectsubstr(x,r*2-1,2)c_ba64,
substr(d,r*2-1,2)c_translatecode
fromsubst,(lectrownumrfromdualconnectbyrownum<=(lectlength(x)/2
fromsubst));
结果如下:
C_BASE64C_TRANSLATECODE
3078
83DA
990B
B870
F574
33F6
9F76
F574
BF77
5C55
5A48
9164
A600
A600
CB0E
C4B7
E102
486E
通过对结果的排序,没有出现同一个BASE64编码对应不同的十六进制的情况,因此我们知道了可以
用这个SQL为基础,通过用不同的SOURCE串来产生替换表的内容。
根据上面的SQL俺就可以写首先建一个表来存储替换表的内容,然后写一段PLSQL块来生成替换表的内容:
SQL>connectsys/XXXX@xxxxassysdba;
SQL>NSLATE
(
C_BASE64DECODEVARCHAR2(2)NOTNULL,
C_LZDEFLATECODEVARCHAR2(2)NULL
)
/
declare
nCntinteger;
nLoopinteger;
nSLoopinteger;
nCharmaxinteger;
nCharmininteger;
vCharVarchar2(3);
cursorgetcharis
withsrcAS(lect'PACKAGE'||vChartxtfromdual),
wrapas(,dbms_('create'||)wrapfromsrc),
substas(lect
substr(utl_64_decode(utl__to_raw(rtrim(substr(,instr(,
chr(10),1,20)+1),chr(10)))),41)x,
e(||chr(0),9)d
fromwrap)
lectsubstr(x,r*2-1,2)xr,
substr(d,r*2-1,2)dr
fromsubst,(lectrownumrfromdualconnectbyrownum<=(lectlength(x)/2
fromsubst));
begin
nCharmax:=97;
nCharmin:=122;
FornLoopIn97..122Loop
FornSloopIn0..99Loop
vChar:=chr(nLoop)||to_char(nSloop);
ForabcIngetcharLoop
SelectCount(*)nslateWHEREc_ba64decode=;
IfnCnt<1Then
nslateVALUES(,);
Commit;
El
SelectCount(*)nslateWHEREc_ba64decode=
c_lzdeflatecode=;
IfnCnt<1Then
DBMS__LINE('wrongorginalchar:'||vchar||'hexba64:'||);
EndIf;
EndIf;
EndLoop;
EndLoop;
EndLoop;
end;
运行上面这段SQL大概会产生1百多条记录,还未达到00-FF总共256条记录的要求,建议替换
lect'PACKAGE'||vChartxtfromdual中的PACKAGE关健字为procedure或者function类似的,
继续运行直到
替换表中有不重复的256条记录为止。
有了替换表的内容,还有前面的JAVA工具包和ORACLE工具包,已经无限接近终点了!
俺将在后面写一段程序来验证unwrap的威力,矛头嘛就直接指向ORACLE自身的包了。
继续未完的测试哈.废话少说先看代码
trveroutputon;
Declare
vWrappedtextVarchar2(32767);
vCharVarchar2(2);
vRepcharVarchar2(2);
vLZinflatestrVarchar2(32767);
nLenInteger;
nLoopInteger;
nCntInteger;
Begin
lectsubstr(utl_64_decode(utl__to_raw(rtrim(substr(TEXT,instr(TEXT,
chr(10),1,20)+1),chr(10)))),41)x
IntovWrappedtext
fromDBA_SOURCE
Whereowner='SYS'
AndName='DBMS_MONITOR'
AndType='PACKAGEBODY';
--DBMS__LINE(vWrappedtext);
nLen:=Length(vWrappedtext)/2-1;
vLZinflatestr:='';
FornLoopIn0..nLenLoop
vChar:=Substrb(vWrappedtext,nLoop*2+1,2);
SelectCount(*)NSLATEWhereC_BASE64DECODE=vChar;
IfnCnt<>1Then
DBMS__LINE('SUBSTATIONTABLEWARNING:Countnotfind
followingchar--'||vChar);
Return;
El
SelectC_NSLATEWhere
C_BASE64DECODE=vChar;
EndIf;
vLZinflatestr:=vLZinflatestr||vRepchar;
--DBMS__LINE(vLZinflatestr);
EndLoop;
--DBMS__LINE(vLZinflatestr);
DBMS__LINE(e(vLZinflatestr));
End;
大家可以看看这个程序的输出是什么?ORACLE的系统包没有秘密可言了,当然其他的用了WR
AP的应用存储过程与包也对大家没有秘密了.
NSLATE的内容,由于牵涉到各方面的因素,我这里就不公开了.相信诸位大大,精通PLS
QL,可以通过对代码的分析,得到替换表的内容;本身不太懂SQL的人,得到了这个替换表的内容,
我相信也不是什么好事情!
精通PLSQL的人可以发现这个贴子的破解程序只能针对较小的存储过程或包,这是由于多方面的因素,
当然我贪图方便是最大的原因.大大们可以根据这个思路,扩展这个程序,将其改造为适应SOURCE
长度超过一行,输出长度也大于4000的应用程序来方便大家使用.
注:后面论坛另一位大神OO将上面的sql优化了下,当然这源码取自amis论坛的成果一部分:
trveroutputon;
Declare
vWrappedtextVarchar2(32767);
vCharVarchar2(2);
vRepcharVarchar2(2);
vLZinflatestrVarchar2(32767);
nLenInteger;
nLoopInteger;
nCntInteger;
typevartabistableofvarchar2(2)indexbyvarchar2(2);
mytblvartab;
cursorgetcharislectC_BASE64DECODExr,C_nslate;
Begin
nslate表内容存到字符数组
mytbl():=;
endloop;
lectsubstr(utl_64_decode(utl__to_raw(rtrim(substr(TEXT,instr(TEXT,
chr(10),1,20)+1),chr(10)))),41)x
IntovWrappedtext
fromDBA_SOURCE
Whereowner='SYS'
AndName='DBMS_OUTPUT'
AndType='PACKAGEBODY';
--DBMS__LINE(vWrappedtext);
nLen:=Length(vWrappedtext)/2-1;
vLZinflatestr:='';
FornLoopIn0..nLenLoop
vChar:=Substrb(vWrappedtext,nLoop*2+1,2);
/*
SelectCount(*)NSLATEWhereC_BASE64DECODE=vChar;
IfnCnt<>1Then
DBMS__LINE('SUBSTATIONTABLEWARNING:Countnotfind
followingchar--'||vChar);
Return;
El
SelectC_NSLATEWhere
C_BASE64DECODE=vChar;
EndIf;
*/
vLZinflatestr:=vLZinflatestr||mytbl(vChar);--从字符数组匹配
--DBMS__LINE(vLZinflatestr);
EndLoop;
--DBMS__LINE(vLZinflatestr);
DBMS__LINE(e(vLZinflatestr));
End;
/
源码一块帖在附件上了。下面再说下加密的算法:
大家都知道oracle的很多系统包是没法看它的源码的,oracle就是将自己的源码用wrap加密了,所以看
不到。为了保护自己辛苦写下的代码,我们自己也可以用该工具加密自己写的过程、函数、包、包体。只
是wrap加密是不可逆的过程,所以大家在加密了自己代码的同时也必须保存好源码。下面做个wrap的小
测试,我也像oracle那样只加密包体,不加密包说明,过程、函数的加密和这类似。
1、创建包说明、包体文件
包说明:d:pkg_wrap_
createorreplacepackagepkg_wrap_testis
--测试过程,将输入的数字以字符格式输出
proceduretest1(iinnumber);
ENDpkg_wrap_test;
包体:d:pkgbd_wrap_
createorreplacepackagebodypkg_wrap_testis
--测试过程,将输入的数字以字符格式输出
proceduretest1(iinnumber)as
begin
dbms__line('输入参数是'||to_char(i));
end;
ENDpkg_wrap_test;
2、创建包说明、加密包体
SQL>createorreplacepackagepkg_wrap_test
2is
3--测试过程,将输入的数字以字符格式输出
4proceduretest_wrap(iinnumber);
5
6ENDpkg_wrap_test;
7/
程序包已创建。
SQL>$wrapiname=d:pkgbd_wrap_me=d:pkgbd_wrap_
PL/SQLWrapper:Relea10.2.0.1.0-Productionon星期四11月2016:05:462008
Copyright(c)1993,2004,htsrerved.
Processingd:pkgbd_wrap_:pkgbd_wrap_
3、执行创建包体的加密文件
SQL>@d:pkgbd_wrap_;
程序包体已创建。
4、检测是否加密成功,可以通过pl/sqldeveloper工具来检查,也可以用ur_resource视图来检查。
pl/sqldeveloper工具看的结果是:
/*Sourceiswrapped*/
而ur_resource视图的结果如下:
SQL>lectname,textfromur_sourcewheretype='PACKAGEBODY'and
name='PKG_WRAP_TEST';
PKG_WRAP_TESTpackagebodypkg_wrap_testwrapped
a000000
354
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
b
9feb
CxYp585Q8j6W0BCKuJNCkFzupjkwg5m49TOf9b9cuJu/9MMWhdzQlpbyVuO
WoWLRzKV0iwlp
plGpyqoX6pxQyuoCL7GPyM6lysamsq5EriREnWkPSbHKLkSAyOZJ6r+uJMo7Do
8GXf12uyyr
0y+rUVvbCCJBP+Kr/LBBbjDtKWgmnbBKCtV3dxZGzsbaElc53jAnJ6MdMr6SvlT
H+70CpiC/
S7IIypjYiKYahpb6
5、验证包的可用性
SQL>trveroutputon
SQL>execpkg_wrap__wrap(1);
输入参数是1
PL/SQL过程已成功完成。
小测试完成
不过。。这仍然麻烦,有没有一个直接转换的工具呢?itpub的另一个lfree给了一个绝杀工具,hellodba
写的用写的:
直接破解结果,不算是sys用户还是spacemanager,谁用谁知道。。不过这工具大家自己留着用就行了。
不要触犯别的公司的版权。如果破解后的SQL代码,也不要流传出去,毕竟,加密的sql都是最核心的算
法,是一个工具的灵魂所在,要尊重别人的劳动成果。
nwrap_
本文发布于:2022-11-26 13:39:12,感谢您对本站的认可!
本文链接:http://www.wtabcd.cn/fanwen/fan/90/25403.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |