Предисловие наверное будет лишним и поэтому сразу к теме.
На днях мне понадобился скрипт установки на lua который будет не легко обнаружить и изменить (секретность видите ли).
Почитав немного литературы, я решил сделать его чем-то похожим на полиморфный вирус с одним отличием: он не вредит компьютеру.
И собственно это дало старт моему эксперименту.
Суть идеи:
В предустановочном скрипте находится исходный код установщика который в добавок зашифрован, записывается в файл (который сам под рандомным именем) и в последствии выполняется.
Первая наша проблема — это как сделать так чтобы блоки из которых состоит установщик не повторялись и записывались все.
Первая версия кода проверки на повторы была ужасна до невозможности и таки ошибалась. Для теста был создан код:
Примечание к коду: m — переменная какой блок должен записыватся. В первой версии это был m = math.random(1,5). f — файл установщика.
Но к сожалению в файле мы видели как несколько раз повторяется simple fri…
Первая версия защиты от повторения была большая:
Примечание: s и j — переменные которые хранили номер цикла. Только первая использовалась для защиты от повтора, а j глобальный цикл. i — одномерный массив.
Но и это меня не особо спасало. По непонятным причинам он пропускал код. Может я криворукий, а может что-то еще…
После некоторых мучений я обратился к знакомому. Он java программист, но довольно сильно мне помог с защитой от повторения.
Мы выбросили код защиты от повторения и вместо math.random(1, 5) сделали функцию gen().
Она выглядит изящно и работает даже лучше чем надо.
Но казалось бы… это было только треть всей беды.
Дальше вопрос встал о защите исходного кода. Даже если использовать luac, то есть шанс того что файл вскроют и посмотрят потроха. Даже шифрование не особо поможет. И мне на помощь пришло два отличных API — socket.http и base64. А также нам поможет сервис pastebin.
Обращаемся к API pastebin'а. Нам нужна регистрация? Ну вы её получите. Идём в API Doc. Там мы видим наш dev-key. Но он нам не особо-то и нужен.
Крутим в самый низ и видим: 13. Getting paste raw output
Всё просто, достаточно сделать простой запрос HTTP — pastebin.com/raw.php?i=<номер>.
Ответ консоли:
Оказывается всё просто до невозможности. Ну тогда не останавливаемся. Прикручиваем декодер base64 (я взял его, но была возможность использовать md5).
Ответ:
Идеально. Можно легко встроить в код.
И третьей нашей проблемой служил возврат информации на pastebin (точнее отчёт о установке).
Как этот код писался рассказывать не буду, но покажу и объясню его.
Объясняю:
Это наши переменные, плюс загрузка модуля luacurl.
Создаём новый потом cURL.
Опции. URL, POST запрос ли это, данные POST запроса.
Отправка данных и закрытие cURL.
Консоль ответила много и не по теме:
На этом пока всё. Сейчас я борюсь с выводом cURL. Спасибо вам, если вы прочитали данную статью.
p.S: Знающих людей прошу написать какая из опций cURL отвечает за скрытие вывода.
p.S.S: Конструктивная критика, а особенно прямые указания на ошибки приветствуются.
На днях мне понадобился скрипт установки на lua который будет не легко обнаружить и изменить (секретность видите ли).
Почитав немного литературы, я решил сделать его чем-то похожим на полиморфный вирус с одним отличием: он не вредит компьютеру.
И собственно это дало старт моему эксперименту.
Суть идеи:
В предустановочном скрипте находится исходный код установщика который в добавок зашифрован, записывается в файл (который сам под рандомным именем) и в последствии выполняется.
Первая наша проблема — это как сделать так чтобы блоки из которых состоит установщик не повторялись и записывались все.
Первая версия кода проверки на повторы была ужасна до невозможности и таки ошибалась. Для теста был создан код:
if m == 1 then f:write("simple one\n")
elseif m == 2 then f:write("simple two\n")
elseif m == 3 then f:write("simple fri\n")
elseif m == 4 then f:write("simple four\n")
elseif m == 5 then f:write("simple five\n")
end
Примечание к коду: m — переменная какой блок должен записыватся. В первой версии это был m = math.random(1,5). f — файл установщика.
Но к сожалению в файле мы видели как несколько раз повторяется simple fri…
Первая версия защиты от повторения была большая:
if m ~= i[s] and s ~= 5 then
s = s + 1
else if s == 5 and m ~=i[s] then
s = 1
i[j] = m
j = j + 1
break
else
m = math.random(1,5)
end
Примечание: s и j — переменные которые хранили номер цикла. Только первая использовалась для защиты от повтора, а j глобальный цикл. i — одномерный массив.
Но и это меня не особо спасало. По непонятным причинам он пропускал код. Может я криворукий, а может что-то еще…
После некоторых мучений я обратился к знакомому. Он java программист, но довольно сильно мне помог с защитой от повторения.
Мы выбросили код защиты от повторения и вместо math.random(1, 5) сделали функцию gen().
Она выглядит изящно и работает даже лучше чем надо.
function gen()
x = math.random(1,5)
while(i[x]) do
x = math.random(1,5)
end
i[x] = true;
return x;
end
Но казалось бы… это было только треть всей беды.
Дальше вопрос встал о защите исходного кода. Даже если использовать luac, то есть шанс того что файл вскроют и посмотрят потроха. Даже шифрование не особо поможет. И мне на помощь пришло два отличных API — socket.http и base64. А также нам поможет сервис pastebin.
Обращаемся к API pastebin'а. Нам нужна регистрация? Ну вы её получите. Идём в API Doc. Там мы видим наш dev-key. Но он нам не особо-то и нужен.
Крутим в самый низ и видим: 13. Getting paste raw output
Всё просто, достаточно сделать простой запрос HTTP — pastebin.com/raw.php?i=<номер>.
local http = require("socket.http")
a = http.request("http://pastebin.com/raw.php?i=PqQCL2sr")
print(a)
Ответ консоли:
C:\Users\Nameless\Desktop\lua_lab>lua test.lua
Это тестовая паста. Nameless.
C:\Users\Nameless\Desktop\lua_lab>
Оказывается всё просто до невозможности. Ну тогда не останавливаемся. Прикручиваем декодер base64 (я взял его, но была возможность использовать md5).
local http = require("socket.http")
require("base64")
a = base64.decode(http.request("http://pastebin.com/raw.php?i=8ZWDwKZ5"))
print(a)
Ответ:
C:\Users\Nameless\Desktop\lua_lab>lua test.lua
This test hash. Nameless
C:\Users\Nameless\Desktop\lua_lab>
Идеально. Можно легко встроить в код.
И третьей нашей проблемой служил возврат информации на pastebin (точнее отчёт о установке).
Как этот код писался рассказывать не буду, но покажу и объясню его.
local cURL = require("luacurl")
local api_key = <здесь мой dev-key>
local api_paste = "testapi"
c = cURL.new()
c:setopt(curl.OPT_URL, "http://pastebin.com/api/api_post.php")
c:setopt(curl.OPT_POST, true)
c:setopt(curl.OPT_POSTFIELDS, "api_option=paste&api_dev_key="..api_key.."&api_paste_code="..api_paste.."&api_paste_private=0&api_paste_format=php")
c:setopt(curl.OPT_TRANSFERTEXT, true)
c:setopt(curl.OPT_VERBOSE, true)
c:setopt(curl.OPT_NOBODY, false)
c:perform()
c:close()
Объясняю:
local cURL = require(«luacurl»)
local api_… ...ste = «testapi»
Это наши переменные, плюс загрузка модуля luacurl.
c = cURL.new()
Создаём новый потом cURL.
c:setopt(curl.OPT_URL, «pastebin.com/api/api_post.php»)
c:setopt(curl.OPT_POST, true)
c:setopt(curl.OPT_POSTFIELDS, «api_option=paste&api_dev_key=»..api_key.."&api_paste_code="..api_paste.."&api_paste_private=0&api_paste_format=php")
c:setopt(curl.OPT_TRANSFERTEXT, true)
c:setopt(curl.OPT_VERBOSE, true)
c:setopt(curl.OPT_NOBODY, false)
Опции. URL, POST запрос ли это, данные POST запроса.
c:perform()
c:close()
Отправка данных и закрытие cURL.
Консоль ответила много и не по теме:
C:\Users\Nameless\Desktop\lua_lab>lua test2.lua
* About to connect() to pastebin.com port 80
* Trying 66.252.2.46… * connected
* Connected to pastebin.com (66.252.2.46) port 80
> POST /api/api_post.php HTTP/1.1
Host: pastebin.com
Accept: */*
Content-Length: 125
Content-Type: application/x-www-form-urlencoded
api_option=paste&api_dev_key=<мой dev-key>&api_paste_code=tes
tapi&api_paste_private=0&api_paste_format=php< HTTP/1.1 200 OK
< Server: nginx
< Date: Sun, 07 Apr 2013 10:00:11 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: close
< Vary: Accept-Encoding
< X-Powered-By: PHP/5.4.8
pastebin.com/Kq8UtQrq* Closing connection #0
C:\Users\Nameless\Desktop\lua_lab>
На этом пока всё. Сейчас я борюсь с выводом cURL. Спасибо вам, если вы прочитали данную статью.
p.S: Знающих людей прошу написать какая из опций cURL отвечает за скрытие вывода.
p.S.S: Конструктивная критика, а особенно прямые указания на ошибки приветствуются.