免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 963 | 回复: 0

[文本处理] 文本求助-代码混淆的异或加持 [复制链接]

论坛徽章:
18
辰龙
日期:2014-05-21 21:01:4115-16赛季CBA联赛之深圳
日期:2016-12-23 13:51:3815-16赛季CBA联赛之北控
日期:2016-11-28 18:26:3815-16赛季CBA联赛之佛山
日期:2016-11-03 11:18:5815-16赛季CBA联赛之辽宁
日期:2016-07-10 16:09:4115-16赛季CBA联赛之江苏
日期:2016-02-20 23:09:202015亚冠之塔什干棉农
日期:2015-08-17 19:49:492015年亚洲杯之日本
日期:2015-04-30 01:24:342015年亚洲杯之约旦
日期:2015-04-01 00:37:182015年亚洲杯之沙特阿拉伯
日期:2015-03-02 15:55:40处女座
日期:2014-05-25 10:34:0020周年集字徽章-年
日期:2023-04-23 11:17:52
发表于 2017-01-11 11:40 |显示全部楼层
本帖最后由 bikkuri 于 2017-01-12 00:15 编辑

一年前jason680大神展示了一段让人眼花缭乱的代码混淆处理后的脚本。
http://bbs.chinaunix.net/thread-4190380-2-1.html
这一大段脚本看起来让人眼晕,但是仔细研究一下,其实要反混淆还是挺简单的。
[box@iZ94mso98zxZ:~]$ cat obf.txt
awk 'function _0000O(){_000O0=0;_000OO=_000O0*_000OO+1;_00O00=FNR;_00O0O=_00OO0;_00OOO=NR;_0O000=NF;_0O00O=_0O000+_000O0*_000OO;_="";_0O0O0=_00O00;_0O0OO=_00OOO;_0OO00=_000O0;_0OO0O=length;_0OOO0=_000OO;}function _0OOOO(_O0000, _0OO0O){return(substr($_000O0,_O0000, _0OO0O));}{_0000O()}_0O0O0==_0O0OO{for(_00O0O=_000OO+_000O0; _00O0O<_0OO0O;_00O0O+=_000OO){_O000O[_0OOOO(_000O0+_000OO,_00O0O)]=1;}_O00O0[$_000OO] = _000OO;next;}function _O00OO(_O0O00, _00O0O){if(_O0O00>_0OO0O)return(_000OO);for(_00O0O=_000OO+_0OO00;_00O0O+_O0O00+_0OO00<=_0OO0O+_000O0+1;_00O0O+=_00O0O*_000O0+_000OO){if(_O00O0[_0OOOO(_O0O00+_000O0,_00O0O+_O0O0O)])if(_O00OO(_O0O00+_O0O0O*_O0OO0+_00O0O+_0OO00*_O0OO0))return(_0OOO0);if(_O000O[_0OOOO(_O0O00+_0OO00,_00O0O+_000O0)])continue;return(_000O0);}return(_O0O0O);}_O00OO(_000OO*_000OO)' b.txt a.txt
[box@iZ94mso98zxZ:~]$ cat obf.txt |grep -oE '_\w{5}'|sort|uniq
_0000O
_000O0
_000OO
_00O00
_00O0O
_00OO0
_00OOO
_0O000
_0O00O
_0O0O0
_0O0OO
_0OO00
_0OO0O
_0OOO0
_0OOOO
_O0000
_O000O
_O00O0
_O00OO
_O0O00
_O0O0O
_O0OO0
[box@iZ94mso98zxZ:~]$
可以看到这里的代码混淆处理只是把原来所有的变量名替换成了这22个由下划线_、数字0和大写字母O构成的变量名。
而且数字0和大写字母O的排列顺序,如果把大写字母O换成数字1,就正好是二进制的00001-10111,即十进制的1-22。
我们可以先写一个将这样由下划线_、数字0和大写字母O构成的变量名转换为一个字母的函数obf2abc。
obf2abc(){
echo $((2#$(echo $1|sed 's/_//;s/O/1/g')+96))|awk '{printf("%c", $1)}'
}
然后用下面一条命令就可以完成所有混淆变量名到字母变量名的替换。
for string in $(cat obf.txt |grep -oE '_\w{5}'|sort|uniq); do var=$(obf2abc $string); sed -i "s/$string/$var/g" obf.txt;done
以下是执行的结果:
[box@iZ94mso98zxZ:~]$ for string in $(cat obf.txt |grep -oE '_\w{5}'|sort|uniq); do var=$(obf2abc $string); sed -i "s/$string/$var/g" obf.txt;done
[box@iZ94mso98zxZ:~]$ cat obf.txt
awk 'function a(){b=0;c=b*c+1;d=FNR;e=f;g=NR;h=NF;i=h+b*c;_="";j=d;k=g;l=b;m=length;n=c;}function o(p, m){return(substr($b,p, m));}{a()}j==k{for(e=c+b; e<m;e+=c){q[o(b+c,e)]=1;}r[$c] = c;next;}function s(t, e){if(t>m)return(c);for(e=c+l;e+t+l<=m+b+1;e+=e*b+c){if(r[o(t+b,e+u)])if(s(t+u*v+e+l*v))return(n);if(q[o(t+l,e+b)])continue;return(b);}return(u);}s(c*c)' b.txt a.txt
[box@iZ94mso98zxZ:~]$
变量名替换后的脚本在阅读上已经扫除了视觉上的障碍,通过对脚本的命令语法进行分析,可以进一步理解程序的算法逻辑。

前面看起来很复杂的程序,通过简单替换就可以反混淆,是因为混淆文本中的所有变量名都是静态的,混淆后的相同的变量名相对应的混淆前的变量名也必定相同。
因此,我想应该可以在这个基础上写一个函数,对所有的混淆变量名进行异或运算,这样生成的混淆变量名就不能通过简单的变量名替换的方式来破解了。
比如_0O00O XOR _OO0O0 = _O00OO
这样即使混淆文本中出现了相同的混淆变量名,它们可能代表不同的原变量名,因此是不能用替换的方法替换成同一个变量名的。
加一个异或函数在技术上很容易做到,但是可以大幅提高破解的难度。

我的想法是取服务器第一块网卡的MAC地址的最后三个字节为初始密钥组:
MAC=$(ifconfig eth0|grep -oEm1 '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}')
例如:
[root@abox:~]# ifconfig eth0|grep -oEm1 '([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}'
F0:B4:29:12:D2:FA
[root@abox:~]#
则初始密钥组的三个字节为12、D2和FA。
由初始密钥组key0=12D2FA和几个常数a="0x123456";b="0xABCD";c="0x800000"进行以下运算得到第一轮的密钥组:
key(n+1)=(key(n)*a+b)%c
即key1=(12D2FA*123456+ABCD)%800000=4253C9
0x42=01000010
0x53=01010011
0xC9=11001001
由于原混淆文本中的混淆变量只用了5位,因此将密钥长度截短为5位,即对0x20(或者二进制的100000)取模即可:
K1=0x42%0x20=0x2 =00010=_000O0
K2=0x53%0x20=0x13=10011=_O00OO
K3=0xC9%0x20=0x9 =01001=_0O00O
然后用这三个密钥对原混淆文本中的前三个混淆变量按以下顺序进行异或运算:
(T=Target;K=Key;O=Origin)
T1=O1 XOR K2
T2=O2 XOR K3
T3=O3 XOR K1
对原混淆文本中awk 'function _0000O(){_000O0=0;_000OO=部分出现的前三个变量_0000O、_000O0、_000OO分别进行处理:
T1=_0000O XOR _O00OO = 1 XOR 13 = 12 = 10010 = _O00O0
T2=_000O0 XOR _0O00O = 2 XOR 9  = B  = 01011 = _0O0OO
T3=_000OO XOR _000O0 = 3 XOR 2  = 1  = 00001 = _0000O
即异或加持后度混淆文本将变成awk 'function _O00O0(){_0O0OO=0;_0000O=

然后再用key1=4253C9求出key2=(4253C9*123456+ABCD)%800000=6FA553;
然后再用key2=6FA553得到下一组密钥为:
K1=0x6F%0x20=0xF =01111=_0OOOO
K2=0xA5%0x20=0x5 =00101=_00O0O
K3=0x53%0x20=0x13=10011=_O00OO
再对原混淆文本中的下三个变量_000O0*_000OO+1;_00O00=FNR;中的_000O0、_000OO、_00O00分别进行处理:
T1=_000O0 XOR _00O0O = 2 XOR 5 = 7  = 00111 = _00OOO
T2=_000OO XOR _O00OO = 3 XOR 13= 10 = 10000 = _O0000
T3=_00O00 XOR _0OOOO = 4 XOR F = B  = 01011 = _0O0OO
...

按此处理直到混淆文本结束。可以看出异或加持后的第2个变量名和第6个变量名都是_0O0OO,但是实际上原来的变量名并不相同,一个是_000O0而另一个是_00O00,因此显然不能用替换法处理异或加持后的混淆文本。
处理得到的代码混淆异或加持脚本是不能直接执行的,而必须先用同样的异或加持函数对其再次处理一次即可还原成之前可以执行的混淆脚本。

希望有能力的大神能帮忙写这个异或加持函数。
当然我自己也在慢慢地摸索着尝试写。
希望大家互相切磋,共同进步。
谢谢。



您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP