PiotrDabkowski / Js2Py

JavaScript to Python Translator & JavaScript interpreter written in 100% pure Python🚀 Try it online:
http://piter.io/projects/js2py
MIT License
2.46k stars 260 forks source link

something in strings is broken in py2.7 #154

Open emf opened 5 years ago

emf commented 5 years ago

I'm trying to use js2py to decode some malicious javascript to extract the obfuscated urls. NB: DO NOT CLICK ANY LINKS IN THIS ISSUE WRITEUP! THEY LEAD TO MALWARE!

using jsc on my mac: I get the following correct behavior from this partial chunk of malicious code:

>>> var _0x19d7=['IsKVw4F/NsOQFMOmw69RZVvDgsKIdmkzd8KnwqrDvmfDqsOiwpENwp7CjMOMQWwXwokuCsKSwofCnQ==','woV5BwgAwrLCnsOB','IMKcw50PGFI=','wrLCsMOJw4Y=','wpnDoH4JIQVPa8KZOF1mdMO4UMKW','P8O2R8O9','YMKzfcKVw5I=','MsODEATCrsKMVV8=','EWHDtsO1w5/CvRAfCMO5','B8KhUcKjw4U=','BMK6w5wOBVDCkcOfW0XDqi/Dig==','wrJawrfDvgIUwrjClMOSAH4gd8KJLMKsO0sCIcOXw47Cn8OXMcK/IMKsfsOlwox8e8K5bS7CskPCk8OSYwHDiUNcw6TDn0IfXsOdwrTDrynClWQ5wqM5IS3CmMOVPMKzS8OLwp/ClsK/KcK6OEvDpMKEf8OzIcOrUMOaTzPCn3PCn8ObYU3CkR/DjRklHFgww7bDvyzDm2ZqwrwYX8KgE8OCDAjCulfDp0tcw59uw4JpezrCpsKdRMK9Ni0aw4DCu8OEw5fCmsO1w5MCRMO+wpd/wqvDsWYYwobDlUbCqBd0axhbwpgELxvClwY3w6TCoMKgw5PDvw==','wr95IFwhwq7CgMOWw4IMwo8jQj5GwqjCncKNTMOqZMOdw77Do8Kc','RcO0w5jCqFnCnlsMWUfCghQd','MMOZDQ==','JsOcb8OVF8OiGsKXw5oiwrnCmcKDcA==','KGHCmMOu','NHTCk8Ok','wq3DsWsuJBM=','QAQYw5rChXnDsMOsDFwiw5vDtysPwoMIw6Jvw50iFMK2w6QbeMOPcMK5w5fDvkLDhVrDtg==','O8Kdw4sMHxrDisOef1rDuG3DjsK8YcKwcMOVw6BIw47Dtid8wpJtwrrCpxUWwoUkwpPCoF1MAMOd','P3jCqB7DncKdw67CoDTDlDLCtwUgwo7Cj8OuPA/Co8Kuw6fDqcOqA8KPwqV/wpE1DGTCp8OMWAoEw6U7W8K6w5nCuyYZRw=='];(function(_0xb479be,_0x4bb6ab){var _0x44c2ed=function(_0x39774b){while(--_0x39774b){_0xb479be['push'](_0xb479be['shift']());}};_0x44c2ed(++_0x4bb6ab);}(_0x19d7,0x101));var _0x3cbf=function(_0x21ed76,_0x59de99){_0x21ed76=_0x21ed76-0x0;var _0x4a239d=_0x19d7[_0x21ed76];if(_0x3cbf['liuyfM']===undefined){(function(){var _0x4ea7e5=function(){var _0x314341;try{_0x314341=Function('return\x20(function()\x20'+'{}.constructor(\x22return\x20this\x22)(\x20)'+');')();}catch(_0x498a25){_0x314341=window;}return _0x314341;};var _0x779cdb=_0x4ea7e5();var _0x81ec19='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';_0x779cdb['atob']||(_0x779cdb['atob']=function(_0x280cfd){var _0x5705ac=String(_0x280cfd)['replace'](/=+$/,'');for(var _0x292a2a=0x0,_0x1421cb,_0x15042b,_0x3d97d1=0x0,_0x20c894='';_0x15042b=_0x5705ac['charAt'](_0x3d97d1++);~_0x15042b&&(_0x1421cb=_0x292a2a%0x4?_0x1421cb*0x40+_0x15042b:_0x15042b,_0x292a2a++%0x4)?_0x20c894+=String['fromCharCode'](0xff&_0x1421cb>>(-0x2*_0x292a2a&0x6)):0x0){_0x15042b=_0x81ec19['indexOf'](_0x15042b);}return _0x20c894;});}());var _0x43b867=function(_0x3cc60d,_0x59de99){var _0x1ebbc1=[],_0x2fe90e=0x0,_0x5a62e2,_0x1cb486='',_0x26701f='';_0x3cc60d=atob(_0x3cc60d);for(var _0x4f46ac=0x0,_0x1e1c80=_0x3cc60d['length'];_0x4f46ac<_0x1e1c80;_0x4f46ac++){_0x26701f+='%'+('00'+_0x3cc60d['charCodeAt'](_0x4f46ac)['toString'](0x10))['slice'](-0x2);}_0x3cc60d=decodeURIComponent(_0x26701f);for(var _0x280ac9=0x0;_0x280ac9<0x100;_0x280ac9++){_0x1ebbc1[_0x280ac9]=_0x280ac9;}for(_0x280ac9=0x0;_0x280ac9<0x100;_0x280ac9++){_0x2fe90e=(_0x2fe90e+_0x1ebbc1[_0x280ac9]+_0x59de99['charCodeAt'](_0x280ac9%_0x59de99['length']))%0x100;_0x5a62e2=_0x1ebbc1[_0x280ac9];_0x1ebbc1[_0x280ac9]=_0x1ebbc1[_0x2fe90e];_0x1ebbc1[_0x2fe90e]=_0x5a62e2;}_0x280ac9=0x0;_0x2fe90e=0x0;for(var _0x47d260=0x0;_0x47d260<_0x3cc60d['length'];_0x47d260++){_0x280ac9=(_0x280ac9+0x1)%0x100;_0x2fe90e=(_0x2fe90e+_0x1ebbc1[_0x280ac9])%0x100;_0x5a62e2=_0x1ebbc1[_0x280ac9];_0x1ebbc1[_0x280ac9]=_0x1ebbc1[_0x2fe90e];_0x1ebbc1[_0x2fe90e]=_0x5a62e2;_0x1cb486+=String['fromCharCode'](_0x3cc60d['charCodeAt'](_0x47d260)^_0x1ebbc1[(_0x1ebbc1[_0x280ac9]+_0x1ebbc1[_0x2fe90e])%0x100]);}return _0x1cb486;};_0x3cbf['XLazRo']=_0x43b867;_0x3cbf['vydnSF']={};_0x3cbf['liuyfM']=!![];}var _0x5a89ae=_0x3cbf['vydnSF'][_0x21ed76];if(_0x5a89ae===undefined){if(_0x3cbf['Rfjvcp']===undefined){_0x3cbf['Rfjvcp']=!![];}_0x4a239d=_0x3cbf['XLazRo'](_0x4a239d,_0x59de99);_0x3cbf['vydnSF'][_0x21ed76]=_0x4a239d;}else{_0x4a239d=_0x5a89ae;}return _0x4a239d;};
undefined
>>> _0x3cbf('0x4','e&wG')
hxxp://denmaytre.vn/wp-content/W_e/
>>> _0x3cbf('0x5','Z1v%')
hxxps://www.hive.world/wp-admin/xa_A3/
>>> _0x3cbf('0x6','4$Fj')
hxxp://hellodocumentary.com/wp-includes/As_yb/
>>> _0x3cbf('0x7','$X@l')
hxxp://fisioklinik.es/ovpek54jsd/Ie_2/
>>>

(i have defanged the links with hxxp. that really is http)

However, in js2py (as of commit 7a3a1ffc6c153e4ea867988d12725f92d133ffc4), i get the following dramatically incorrect behavior.

>>> import js2py
>>> partial = '''var _0x19d7=['IsKVw4F/NsOQFMOmw69RZVvDgsKIdmkzd8KnwqrDvmfDqsOiwpENwp7CjMOMQWwXwokuCsKSwofCnQ==','woV5BwgAwrLCnsOB','IMKcw50PGFI=','wrLCsMOJw4Y=','wpnDoH4JIQVPa8KZOF1mdMO4UMKW','P8O2R8O9','YMKzfcKVw5I=','MsODEATCrsKMVV8=','EWHDtsO1w5/CvRAfCMO5','B8KhUcKjw4U=','BMK6w5wOBVDCkcOfW0XDqi/Dig==','wrJawrfDvgIUwrjClMOSAH4gd8KJLMKsO0sCIcOXw47Cn8OXMcK/IMKsfsOlwox8e8K5bS7CskPCk8OSYwHDiUNcw6TDn0IfXsOdwrTDrynClWQ5wqM5IS3CmMOVPMKzS8OLwp/ClsK/KcK6OEvDpMKEf8OzIcOrUMOaTzPCn3PCn8ObYU3CkR/DjRklHFgww7bDvyzDm2ZqwrwYX8KgE8OCDAjCulfDp0tcw59uw4JpezrCpsKdRMK9Ni0aw4DCu8OEw5fCmsO1w5MCRMO+wpd/wqvDsWYYwobDlUbCqBd0axhbwpgELxvClwY3w6TCoMKgw5PDvw==','wr95IFwhwq7CgMOWw4IMwo8jQj5GwqjCncKNTMOqZMOdw77Do8Kc','RcO0w5jCqFnCnlsMWUfCghQd','MMOZDQ==','JsOcb8OVF8OiGsKXw5oiwrnCmcKDcA==','KGHCmMOu','NHTCk8Ok','wq3DsWsuJBM=','QAQYw5rChXnDsMOsDFwiw5vDtysPwoMIw6Jvw50iFMK2w6QbeMOPcMK5w5fDvkLDhVrDtg==','O8Kdw4sMHxrDisOef1rDuG3DjsK8YcKwcMOVw6BIw47Dtid8wpJtwrrCpxUWwoUkwpPCoF1MAMOd','P3jCqB7DncKdw67CoDTDlDLCtwUgwo7Cj8OuPA/Co8Kuw6fDqcOqA8KPwqV/wpE1DGTCp8OMWAoEw6U7W8K6w5nCuyYZRw=='];(function(_0xb479be,_0x4bb6ab){var _0x44c2ed=function(_0x39774b){while(--_0x39774b){_0xb479be['push'](_0xb479be['shift']());}};_0x44c2ed(++_0x4bb6ab);}(_0x19d7,0x101));var _0x3cbf=function(_0x21ed76,_0x59de99){_0x21ed76=_0x21ed76-0x0;var _0x4a239d=_0x19d7[_0x21ed76];if(_0x3cbf['liuyfM']===undefined){(function(){var _0x4ea7e5=function(){var _0x314341;try{_0x314341=Function('return\x20(function()\x20'+'{}.constructor(\x22return\x20this\x22)(\x20)'+');')();}catch(_0x498a25){_0x314341=window;}return _0x314341;};var _0x779cdb=_0x4ea7e5();var _0x81ec19='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';_0x779cdb['atob']||(_0x779cdb['atob']=function(_0x280cfd){var _0x5705ac=String(_0x280cfd)['replace'](/=+$/,'');for(var _0x292a2a=0x0,_0x1421cb,_0x15042b,_0x3d97d1=0x0,_0x20c894='';_0x15042b=_0x5705ac['charAt'](_0x3d97d1++);~_0x15042b&&(_0x1421cb=_0x292a2a%0x4?_0x1421cb*0x40+_0x15042b:_0x15042b,_0x292a2a++%0x4)?_0x20c894+=String['fromCharCode'](0xff&_0x1421cb>>(-0x2*_0x292a2a&0x6)):0x0){_0x15042b=_0x81ec19['indexOf'](_0x15042b);}return _0x20c894;});}());var _0x43b867=function(_0x3cc60d,_0x59de99){var _0x1ebbc1=[],_0x2fe90e=0x0,_0x5a62e2,_0x1cb486='',_0x26701f='';_0x3cc60d=atob(_0x3cc60d);for(var _0x4f46ac=0x0,_0x1e1c80=_0x3cc60d['length'];_0x4f46ac<_0x1e1c80;_0x4f46ac++){_0x26701f+='%'+('00'+_0x3cc60d['charCodeAt'](_0x4f46ac)['toString'](0x10))['slice'](-0x2);}_0x3cc60d=decodeURIComponent(_0x26701f);for(var _0x280ac9=0x0;_0x280ac9<0x100;_0x280ac9++){_0x1ebbc1[_0x280ac9]=_0x280ac9;}for(_0x280ac9=0x0;_0x280ac9<0x100;_0x280ac9++){_0x2fe90e=(_0x2fe90e+_0x1ebbc1[_0x280ac9]+_0x59de99['charCodeAt'](_0x280ac9%_0x59de99['length']))%0x100;_0x5a62e2=_0x1ebbc1[_0x280ac9];_0x1ebbc1[_0x280ac9]=_0x1ebbc1[_0x2fe90e];_0x1ebbc1[_0x2fe90e]=_0x5a62e2;}_0x280ac9=0x0;_0x2fe90e=0x0;for(var _0x47d260=0x0;_0x47d260<_0x3cc60d['length'];_0x47d260++){_0x280ac9=(_0x280ac9+0x1)%0x100;_0x2fe90e=(_0x2fe90e+_0x1ebbc1[_0x280ac9])%0x100;_0x5a62e2=_0x1ebbc1[_0x280ac9];_0x1ebbc1[_0x280ac9]=_0x1ebbc1[_0x2fe90e];_0x1ebbc1[_0x2fe90e]=_0x5a62e2;_0x1cb486+=String['fromCharCode'](_0x3cc60d['charCodeAt'](_0x47d260)^_0x1ebbc1[(_0x1ebbc1[_0x280ac9]+_0x1ebbc1[_0x2fe90e])%0x100]);}return _0x1cb486;};_0x3cbf['XLazRo']=_0x43b867;_0x3cbf['vydnSF']={};_0x3cbf['liuyfM']=!![];}var _0x5a89ae=_0x3cbf['vydnSF'][_0x21ed76];if(_0x5a89ae===undefined){if(_0x3cbf['Rfjvcp']===undefined){_0x3cbf['Rfjvcp']=!![];}_0x4a239d=_0x3cbf['XLazRo'](_0x4a239d,_0x59de99);_0x3cbf['vydnSF'][_0x21ed76]=_0x4a239d;}else{_0x4a239d=_0x5a89ae;}return _0x4a239d;};'''
>>> context = js2py.EvalJs()
>>> context.eval(partial)
'function (_0x21ed76, _0x59de99) { [python code] }'
>>> context.eval("_0x3cbf('0x4','e&wG')")
u'htti%\x94Z\xf1\xaa\x82\x8c\x16\x82\x03_%\xbdW\xb6\xd9Z\xa6\x18\x8f\xb7\xb4\xd4\xd6J\x81\xc5\xd7,\xfc}<Pt\x11\xe2\xcd\xb1H\xb4G\xf5\xcc\xdb<p\xe1&'
>>> context.eval("_0x3cbf('0x5','Z1v%')")
u'h+"\xbf\xe7,\xfa\xeb\xcb\xa7L\xdd\xd9\x8f\xd4m3a\x01\xf8\x1e\xf3\xca\xbb\x92\x83N\x00\xd87(\x85(w%q\xf1`t\xd3G\x80\xf47r.\x1c\x14\x02e\xc1\xe8\xc5h+\x05\xa6'
>>> context.eval("_0x3cbf('0x6','4$Fj')")
u'ht\x1e\xc6\xf9q\\\n\xcc{\xf0\x1a\xc1{.n\xb1\x9b\xd6\xd2\xefW\x1e\x06\xef#fl\xe9\x87\x82\xcfgl\x93\xbc\xc9C\xe2w9%&\xfa\x04\xaa\x8c\xbb\xe9\xd9FnbH\x11;\xe4\xe8x$\xd4\xe9Nv\xd9\xaa\xac\x94\xa6Y'
>>> context.eval("_0x3cbf('0x7','$X@l')")
u'h# \xcc\x8d\x80\rC\x166\xcf\x92jKNb\x01\xdf\x0b\r\x05>\xec\xa7\x96\xaaR{R\xe8\xa1\x14e\xcd\xacow#\\`\x12#W\xc3U`\xce)\xa6\x1e\xfb\x05\xa0\xaf*\x10\xf9\x9d'

furthermore, note the difference in behavior here:

>>> context.eval("_0x3cbf('0x7','$X@l')")
u'h# \xcc\x8d\x80\rC\x166\xcf\x92jKNb\x01\xdf\x0b\r\x05>\xec\xa7\x96\xaaR{R\xe8\xa1\x14e\xcd\xacow#\\`\x12#W\xc3U`\xce)\xa6\x1e\xfb\x05\xa0\xaf*\x10\xf9\x9d'
>>> context.eval("console.log(_0x3cbf('0x7','$X@l'))")
'h# \xc3\x8c\xc2\x8d\xc2\x80\rC\x166\xc3\x8f\xc2\x92jKNb\x01\xc3\x9f\x0b\r\x05>\xc3\xac\xc2\xa7\xc2\x96\xc2\xaaR{R\xc3\xa8\xc2\xa1\x14e\xc3\x8d\xc2\xacow#\\`\x12#W\xc3\x83U`\xc3\x8e)\xc2\xa6\x1e\xc3\xbb\x05\xc2\xa0\xc2\xaf*\x10\xc3\xb9\xc2\x9d'

where the native string is unicode, but the console.log() string is not; and is different. This makes me suspect something ugly is happening with string encoding somewhere.

emf commented 5 years ago

Oh, and I must add that this is a python 2.7 bug. it seems to work okay in python3.