Деобфускация в Python с использованием преобразованной функции JS
Мне нужно было преобразовать следующую функцию в python для деобфускации текста, извлеченного во время просмотра веб-страниц:
function obfuscateText(coded, key) {
// Email obfuscator script 2.1 by Tim Williams, University of Arizona
// Random encryption key feature by Andrew Moulden, Site Engineering Ltd
// This code is freeware provided these four comment lines remain intact
// A wizard to generate this code is at http://www.jottings.com/obfuscator/
shift = coded.length
link = ""
for (i = 0; i < coded.length; i++) {
if (key.indexOf(coded.charAt(i)) == -1) {
ltr = coded.charAt(i)
link += (ltr)
}
else {
ltr = (key.indexOf(coded.charAt(i)) - shift + key.length) % key.length
link += (key.charAt(ltr))
}
}
document.write("<a href='mailto:" + link + "'>" + link + "</a>")
} """
вот мой преобразованный эквивалент Python:
def obfuscateText(coded,key):
shift = len(coded)
link = ""
for i in range(0,len(coded)):
inkey=key.index(coded[i]) if coded[i] in key else None
if ( not inkey):
ltr = coded[i]
link += ltr
else:
ltr = (key.index(coded[i]) - shift + len(key)) % len(key)
link += key[ltr]
return link
print obfuscateText ("uw # 287u ## Guw # 287Xw8Iwu! # W7L #", "WXYVZabUcdTefgShiRjklQmnoPpqOrstNuvMwxyLz01K23J456I789H. @ G! # $ F% - {A = E) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
actionattraction$comcastWnet
но я получаю немного неправильный вывод вместо actionattraction@comcast.net, который я получаю выше. Также много раз приведенный выше код дает случайные символы для одной и той же HTML-страницы,
Целевая html-страница имеет функцию obfuscateText в JS с кодом и ключом, я извлекаю сигнатуру функции в obsfunc и выполняю ее на лету:
email=eval(obsfunc)
который хранит электронную почту в указанной выше переменной, но проблема в том, что она работает большую часть времени, но не работает в определенные моменты. Я твердо убежден, что проблема заключается в аргументах, передаваемых в функцию python, они могут нуждаться в экранировании или преобразовании, поскольку оно содержит специальные персонажи? Я попытался передать необработанные аргументы и различные типы преобразования типа repr(), но проблема не исчезла.
Некоторые примеры для actionattraction@comcast.net, неправильно вычисленные и правильно вычисленные с использованием одной и той же функции python(первая строка - электронная почта):
@ation@ttr@ationVaoma@st!nct
obfuscateText("KMd%Y@Kdd8KMd%Y@IMY!MKcdJ@*d", "utvsrwqxpyonzm0l1k2ji3h4g5fe6d7c8b9aZ.Y@X!WV#U$T%S&RQ'P*O+NM-L/K=J?IH^G_F`ED{C|B}A~")
}ction}ttr}ction@comc}st.net
obfuscateText("}ARGML}RRP}ARGMLjAMKA}QRiLCR", "}|{`_^?=/-+*'&%$#!@.9876543210zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA~")
actionattraction@comcast.net
obfuscateText("DEWLRQDWWUDEWLRQoERPEDVWnQHW", "%&$#!@.'9876*54321+0zyxw-vutsr/qponm=lkjih?gfed^cbaZY_XWVUT`SRQPO{NMLKJ|IHGFE}DCBA~")
2 ответа
Я переписал деобфускатор:
def deobfuscate_text(coded, key):
offset = (len(key) - len(coded)) % len(key)
shifted_key = key[offset:] + key[:offset]
lookup = dict(zip(key, shifted_key))
return "".join(lookup.get(ch, ch) for ch in coded)
и проверил это как
tests = [
("KMd%Y@Kdd8KMd%Y@IMY!MKcdJ@*d", "utvsrwqxpyonzm0l1k2ji3h4g5fe6d7c8b9aZ.Y@X!WV#U$T%S&RQ'P*O+NM-L/K=J?IH^G_F`ED{C|B}A~"),
("}ARGML}RRP}ARGMLjAMKA}QRiLCR", "}|{`_^?=/-+*'&%$#!@.9876543210zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA~"),
("DEWLRQDWWUDEWLRQoERPEDVWnQHW", "%&$#!@.'9876*54321+0zyxw-vutsr/qponm=lkjih?gfed^cbaZY_XWVUT`SRQPO{NMLKJ|IHGFE}DCBA~"),
("ZUhq4uh@e4Om.04O", "ksYSozqUyFOx9uKvQa2P4lEBhMRGC8g6jZXiDwV5eJcAp7rIHL31bnTWmN0dft")
]
for coded,key in tests:
print(deobfuscate_text(coded, key))
который дает
actionattraction@comcast.net
actionattraction@comcast.net
actionattraction@comcast.net
anybody@home.com
Обратите внимание, что все три ключевые строки содержат &
; заменив его &
устраняет проблему Предположительно в какой-то момент javascript был ошибочно экранирован html-кодом; В Python есть модуль, который будет кодировать специальные символы html, например:
# Python 2.x:
import HTMLParser
html_parser = HTMLParser.HTMLParser()
unescaped = html_parser.unescape(my_string)
# Python 3.x:
import html.parser
html_parser = html.parser.HTMLParser()
unescaped = html_parser.unescape(my_string)
Прежде всего, index
не возвращается None
, но выдает исключение. В вашем случае W появляется вместо точки, потому что возвращаемый индекс 0
, а также not inkey
(что также неправильно) ошибочно полагает, что в ключе отсутствует символ.
Во-вторых, наличие &
предполагает, что вам действительно может понадобиться найти и декодировать HTML-объекты.
Наконец, я бы рекомендовал переписать его как
len0 = len(code)
len1 = len(key)
link = ''
for ch in code:
try:
ch = key[(key.index(ch) - len0 + len1) % len1]
except ValueError: pass
link += ch
return link