主讲师: 范文庆
- cl
clang ---> .c/.cpp->.exe/PE 编译链接
gcc
PROGRAM FILE->LLVM->bin 下的clang放入环境变量
- 编写C
保存
#include<stdio.h> #include<stdlib.h> int main() { printf("hello"); }
- 进入.c目录
- clang hw.c
可以得到可执行文件 - winhex打开一个.exe和对应的.c文件
ctrl+F 可以搜索hello
h: ASCII 0x68对应winhex
0x20-0x7E 才有对应字符
.c 只有小于20的,是换行符
- python加入环境变量
- 进入.py
- pyhon a.py
没有变成a.exe,但必须在python.exe下运行 python.exe 读取a.py,分析指令,调用库执行,突破CPU只能执行二进制的局限,不需要编译 - vscode debug 选择pythonfile或者sdd congrifion
- 打开网页小游戏
- 产看源代码,script,.js
-
进入目录
-
clang hw.c
-
会有一个a.exe
-
clang -c hw.c 多出一个hw.o
.c->(编译)->.o->(链接,多个链接拼接成一个文件)->.exe这是原生应用程序 hufive app
python等必须有原生应用程序的解释器
特点:直接,性能好,开发难(用.c/cpp)
- 硬件->OS->原生APP,浏览器
浏览器:1. http client网络
2. 解析,显示 3. 脚本执行器,交互,数据,动态效果
- 打开wireshark,开始抓包
- 访问网页,停止抓包
- 过滤器输入http
- 下载lxml import lxml etree
- head字段:伪装成浏览器
- xpath:通过路径定位元素
html/body/div/fext()(函数,获取文本) //div[class='a'](属性) 选好演出名称:右键->copy->xpath tr/td[1]:所用表格的第一例
- 设置公钥
- 右击git.bash.,然后输入
ssh-keygen -t rsa -b 4096
一直回车 存储在(C:\Users\18801.ssh\id_rsa.pub) - github->settings->ssh,new ssh
- 右击git.bash.,然后输入
python -m pip install lxml
网上搜索python使用国内源,加快下载速度python -m pip install -r requestments.txt
直接下载所有包
写一个requestments.txt包含所有需要的库
- 下载chromedriver,放在py同一目录
- py->selenium->chromedriver->chrome
用户登录,信息提交,且能呈现给其他人 论坛,bbs,社区,微博 ##作业: 有跨站脚本的漏洞的程序,没有脚本过滤,然后利用 ID,名称,时间 2. 写python爬虫,自动提交和验证网页有这样的漏洞(自己提交,看一下结果中有没有脚本)
存储型的xss
UserA----(.JS)>
---- Sever
UserB-----(.js,执行)>
前端会解释script标签
对用户的提交
危险:造成数据泄露,写入数据库
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
int main(int argc,char** argv)
//char** : 字符串数组
//argc:输入参数个数 argv:输入参数的值
//程序本身也要占一个
//eg: git clone http://.....
//argc=3,argv[1]=clone
{
char y[10];
if(argc>1)
{
strcpy(y,argv[1]);
}
}
//改进
strcpy_s(y,strlen(x),x) ❌
strcpy_s(y,10,x) ✔
会造成写入越界 bufffer is too small
属性中的:启用C++异常,基本运行检查,安全检查防止了崩溃
安全漏洞都是由于当年设计机制不规范
- CVE
- CNNVD
- CNVD
- 启动httpd netstart -l(查看端口:80) 127.0.0.1 \a html
- 客户端作用: 取内容 渲染 执行动态脚本
- GET,POST
httpd,阿帕奇,Django(MVT,MVC)
- MVT
m:数据模型,数据库的表结构
v:视图 T:页面模板
动态网页的htnl是由程序生成的(cgi)
写一些简单的动态脚本,php在nginx(做一个乘法器in:1 out:2)
详细:
-
静态的html站点的建立 抓包其抓包HTTP整个响应过程
-
apache等建立一个动态的执行过程,php,可以根据用户请求动态生成,调用数据库
-
Diango快速构建一个web应用,按照mvt 渲染 {{变量名}}
主体框架是静态的,内容是动态的
https://docs.djangoproject.com/en/2.2/intro/ ORM
文件所处位置
D:\YearJunior1\SoftwareProjectSecurityDevelopmentLifecycle\EXP1
#define _CRT_SECURE_NO_WARNINGS
//没有这一行代码会错误,因为strcpy是不安全的,这个不让报错
// CRT:C RUN TIME
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int sub(char* x)
{
char y[10];
strcpy(y, x); //❌
return 0;
}
int main(int argc, char** argv)
{
if (argc > 1)
sub(argv[1]);
printf("exit");
}
- sub函数调用strcpy
- debug运行状态
- 下断点在strcpy,开始调试
- 转到反汇编,去掉显示符号名,上面三个都勾上
- 调试-》窗口-》内存(输入eip),寄存器
EIP 指令指针寄存器
- F10,EIP,EAX都改变 eax就是x的地址,ecx是y 内存-》eax “9”-》“0x39” 00字符串结束
- F10再执行一步
栈:函数调用这样的问题 - 输入esp
- F10,停在call处在的位置,F11进入函数
ESP: 19FE34 ->-4->19FE30->-4->19FE2C->-4->19FE28(call指令也入栈了一个数据,call指令的下一条地址)
局部变量也位于栈中
- main函数调用sub
- mian中加一个断点
- 执行完call strcpy
- return后,去到了39393939地址(这个是用户输入的,而不是程序员自己写的)sub下一条指令的地址被破坏
如果此时进入到的地址是黑客写的代码的地址,那么就会造成安全漏洞 - add esp 8回退
- 总结
重复上课的内容,写实验报告,md,放在github上,将链接给学委
- git
- github
- pro git
- markdown->可对比,版本化管理,格式,格式简洁
- 原生应用程序 .exe(windows) .c/.cpp/.elf(linux) 和web(网络)应用程序
- 程序执行过程通过程序(debuger)调试器进行观察
- debuger
vs自带的/windebuger gdb
两代流派 vc和 gnu
vc: cl.exe,link.exe,sok
gnu: gcc(编译器),libc - 断点/单步执行/反汇编/内存/查看寄存器
- 与malloc和free函数有关,多次malloc,多次不定时free
- 无法预估需要多大的内存
- 实验
#include<stdlib.h>
#include<string.h>
#include<stdio.h>
void hack()
{
printf("hacker!");
}
int main(int argc,char** argv)
//char** : 字符串数组
//argc:输入参数个数 argv:输入参数的值
//程序本身也要占一个
//eg: git clone http://.....
//argc=3,argv[1]=clone
{
char y[10];
if(argc>1)
{
strcpy(y,argv[1]);
}
}
需要补笔记
-
exe->API->Textout GDI->控件 屏幕取词:重载了textout
-
线程与进程
(windows/linux核心编程/深入理解计算机系统 intel programming)- createthread函数,创建函数
3. main->主线程
4.
5.
6. 从CreateThread函数基本参数解释中下载例子
7. 实例函数在这里
将3改为10
8. 执行
总体是一种随机性,但是多运行几次,会发现小的在上 9. 修改
10. 修改
11. 重新编译运行
每个线程都sleep了1000但是总体时间只用了1032,所以相当于所有线程都是同时执行 12.
最后tick count时间为一万多 -
进程 createprocess msdn example里面的代码copy下来
cd D:\YearJunior1\SoftwareProjectSecurityDevelopmentLifecycle\EXP3\Debug
EXP3.exe
EXP3.exe "EXP3.exe notepad.exe"
- processExplore
ctrl+ E:打开.exe
ctrl+s, 拖符号pdb 符号文件,
ctrl+p源文件所在的文件夹
bu .exe名字!main g
关掉
- 换64位的windeug ctrl+ E:打开cal.exe(c->windows->system32)
.symfix C:\symbols .sympath
bu calc!wWinMain g
调试器监控运行,下断点,
- 在SetWindowsTextW处下断点 function
打开计算器->F6(attach to process)->找到计算器.exe
2. bu user32!SetWindowsTextW
.symfix C:\symbols
.sympath
x kernel32!WriteFile*
bu kernel32!WriteFile
bu kernel32!WriteFileEX
bl
g
保存记事本
未完待续……
指令 作用
.symfix 指定本地缓存目录
.sympath 设置符号路径,包括本地缓存和远程符号服务器
.reload 重新加载模板
x 查看模块符号
bu 下断点
bl 列出断点
g 继续执行程序
k 查看调用堆栈
lm 列出当前进程加载的模块
u: 查看后续的n条指令
上下键:翻页
esc:清空所有内容
n: 查看进制
上次失败原因:记事本调用的不是kernel32里面的WriteFile而是kernelbase里面的,可以用processmonitor查看
PPT中 format 改为 formats
n
查看几进制n 10
修改为10进制
as demo 5+1(这是一个表达式,不会算)
as /x demo 5+1 (会计算)
# 固定别名
r $.u0 = 5+1
.echo $u0
${} 展开
- 不退出调试器,重新执行
- 调试
- windebug打开windows下面的记事本
- 下断点
bu kernelbase!writefile ".echo hello;g" bl g
3. 记事本弹出,随便输,然后保存,会输出hello
4. 将命令写到记事本中
5. 引入脚本文件bu kernelbase!writefile "$><C:\\Users\\18801\\Desktop\\c.txt" g
- 脚本实例
.foreach (value {dd 61000 L4}) { as /x ${/v:myAlias} value + 1 .block{.echo value myAlias} } //foreach: 每行执行 //dd: 查看内存内容 6100:地址 L4后面四个地址的内容 //value: 每次查看的内容赋值给value //{ //echo value //} //ad myAlias
- 实验
- 脚本c.txt
as /mu content poi(esp+0n24) # poi /mu 是字符串 .block{.if($scmp("${content}","123456")==0){ezu poi(esp+0n24) "hacked";}.else{.echo content}} # ezu 改值 u:unicode g
- 下断点
bu kernelbase!writefile "$><C:\\Users\\18801\\Desktop\\c.txt" g
- 原理
存放在D:\YearJunior1\SoftwareProjectSecurityDevelopmentLifecycle\Snapshot
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
// Forward declarations:
BOOL GetProcessList();
BOOL ListProcessModules(DWORD dwPID);
BOOL ListProcessThreads(DWORD dwOwnerPID);
void printError(TCHAR* msg);
int main(void)
{
GetProcessList();
return 0;
}
BOOL GetProcessList()
{
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
DWORD dwPriorityClass;
// Take a snapshot of all processes in the system.
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //得到快照句柄,系统对象可被操作的对象ID,文件窗口,进程,现场
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
printError(TEXT("CreateToolhelp32Snapshot (of processes)"));
return(FALSE);
}
// Set the size of the structure before using it.
pe32.dwSize = sizeof(PROCESSENTRY32);
// Retrieve information about the first process,
// and exit if unsuccessful
if (!Process32First(hProcessSnap, &pe32)) //进程结果放在pe32中
{
printError(TEXT("Process32First")); // show cause of failure
CloseHandle(hProcessSnap); // clean the snapshot object
return(FALSE);
}
// Now walk the snapshot of processes, and
// display information about each process in turn
do
{
_tprintf(TEXT("\n\n====================================================="));
_tprintf(TEXT("\nPROCESS NAME: %s"), pe32.szExeFile);
_tprintf(TEXT("\n-------------------------------------------------------"));
// Retrieve the priority class.
dwPriorityClass = 0;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
if (hProcess == NULL)
printError(TEXT("OpenProcess"));
else
{
dwPriorityClass = GetPriorityClass(hProcess);
if (!dwPriorityClass)
printError(TEXT("GetPriorityClass"));
CloseHandle(hProcess);
}
_tprintf(TEXT("\n Process ID = 0x%08X"), pe32.th32ProcessID);
_tprintf(TEXT("\n Thread count = %d"), pe32.cntThreads);
_tprintf(TEXT("\n Parent process ID = 0x%08X"), pe32.th32ParentProcessID);
_tprintf(TEXT("\n Priority base = %d"), pe32.pcPriClassBase);
if (dwPriorityClass)
_tprintf(TEXT("\n Priority class = %d"), dwPriorityClass);
// List the modules and threads associated with this process
ListProcessModules(pe32.th32ProcessID); //遍历一个进程的模块
ListProcessThreads(pe32.th32ProcessID); //遍历一个进程的所有线程
} while (Process32Next(hProcessSnap, &pe32)); //遍历完返回0,没遍历完返回1
CloseHandle(hProcessSnap);
return(TRUE);
}
BOOL ListProcessModules(DWORD dwPID)
{
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 me32;
// Take a snapshot of all modules in the specified process.
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);
if (hModuleSnap == INVALID_HANDLE_VALUE)
{
printError(TEXT("CreateToolhelp32Snapshot (of modules)"));
return(FALSE);
}
// Set the size of the structure before using it.
me32.dwSize = sizeof(MODULEENTRY32);
// Retrieve information about the first module,
// and exit if unsuccessful
if (!Module32First(hModuleSnap, &me32))
{
printError(TEXT("Module32First")); // show cause of failure
CloseHandle(hModuleSnap); // clean the snapshot object
return(FALSE);
}
// Now walk the module list of the process,
// and display information about each module
do
{
_tprintf(TEXT("\n\n MODULE NAME: %s"), me32.szModule);
_tprintf(TEXT("\n Executable = %s"), me32.szExePath);
_tprintf(TEXT("\n Process ID = 0x%08X"), me32.th32ProcessID);
_tprintf(TEXT("\n Ref count (g) = 0x%04X"), me32.GlblcntUsage);
_tprintf(TEXT("\n Ref count (p) = 0x%04X"), me32.ProccntUsage);
_tprintf(TEXT("\n Base address = 0x%08X"), (DWORD)me32.modBaseAddr);
_tprintf(TEXT("\n Base size = %d"), me32.modBaseSize);
} while (Module32Next(hModuleSnap, &me32));
CloseHandle(hModuleSnap);
return(TRUE);
}
BOOL ListProcessThreads(DWORD dwOwnerPID)
{
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
THREADENTRY32 te32;
// Take a snapshot of all running threads
hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hThreadSnap == INVALID_HANDLE_VALUE)
return(FALSE);
// Fill in the size of the structure before using it.
te32.dwSize = sizeof(THREADENTRY32);
// Retrieve information about the first thread,
// and exit if unsuccessful
if (!Thread32First(hThreadSnap, &te32))
{
printError(TEXT("Thread32First")); // show cause of failure
CloseHandle(hThreadSnap); // clean the snapshot object
return(FALSE);
}
// Now walk the thread list of the system,
// and display information about each thread
// associated with the specified process
do
{
if (te32.th32OwnerProcessID == dwOwnerPID)
{
_tprintf(TEXT("\n\n THREAD ID = 0x%08X"), te32.th32ThreadID);
_tprintf(TEXT("\n Base priority = %d"), te32.tpBasePri);
_tprintf(TEXT("\n Delta priority = %d"), te32.tpDeltaPri);
_tprintf(TEXT("\n"));
}
} while (Thread32Next(hThreadSnap, &te32));
CloseHandle(hThreadSnap);
return(TRUE);
}
void printError(TCHAR* msg)
{
DWORD eNum;
TCHAR sysMsg[256];
TCHAR* p;
eNum = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, eNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
sysMsg, 256, NULL);
// Trim the end of the line and terminate it with a null
p = sysMsg;
while ((*p > 31) || (*p == 9))
++p;
do { *p-- = 0; } while ((p >= sysMsg) &&
((*p == '.') || (*p < 33)));
// Display the message
_tprintf(TEXT("\n WARNING: %s failed with error %d (%s)"), msg, eNum, sysMsg);
}
.cpp改为.c文件,就可以运行成功
- 输出结果与任务栏管理器差不多
- cmd中输入
tasklist
,系统显示输出的进程,程序查看的与cmd中的输出是一样的v
- 每个模块第一个一定是exe,且有且仅有一个exe,下面跟着.dll
- 可以用开发者工具
dumbing \imports
,多个API会共用同一个dll
- 链接是把若干个程序的组成部分拼接到一起
D:\YearJunior1\SoftwareProjectSecurityDevelopmentLifecycle\EXP4
a.c
int main()
{
sub();
}
b.c
//修改前
int sub()
{
return 0;
}
//修改后
#include<Windows.h>
int sub()
{
MessageBox(0, "msg", 0, 0);
return 0;
}
-
切换到a.c,b.c所在目录
-
链接
link a.obj b.obj /out:hehe.exe
- 静态链接是指源代码在可执行程序内部,在同一文件里面,相对位置不变。动态链接是指代码不在exe内,需要运行时去寻找,相对位置是改变的
- 为什么要动态链接
- 静态链接越要编译好的机器指令在exe中放一份,例如print会被复制很多个,可执行文件会非常大,会有空间的浪费
- 当代码出现问题,要进行升级时,需要将所有调用这个函数的代码都升级一遍。如果单独放在一个文件中就只需要改这一个文件
- 开发一个基础平台,不用开发源代码,用可以让更多人调用。起到了闭源系统同样能开放的功能
- 没有动态链接,操作系统会异常臃肿和庞大,不宜升级和更新。能保证基础代码只有一个拷贝就可以。新编写的代码只是基础代码的增量。
- Process Explorer
- Dependency Walker
- 综合使用今天使用的模块遍历,结合三个工具dumpbin,Process Explorer,Dependency Walker结合分析比较
D:\YearJunior1\SoftwareProjectSecurityDevelopmentLifecycle\EXP4\Base
base.c
#include<Windows.h>
int intnal_function()
{
}
int lib_function(char * msg)
{
MessageBoxA(0, "message from base lib", msg, MB_OK);
}
exp.def
LIBRARY baselib
EXPORTS
lib_function
- 转到源代码目录
D:\YearJunior1\SoftwareProjectSecurityDevelopmentLifecycle\EXP4\Base\Base
link base.obj User32.lib /dll /def:exp.def
- 得到dll文件,还有一个.lib文件
- 验证dll成功
- 此时执行不能成功,改一下几个属性
D:\YearJunior1\SoftwareProjectSecurityDevelopmentLifecycle\EXP4\APP
- 调运dll文件
app.cpp
int main()
{
lib_function("call a dll");
}
- 把base.lib,dll,.h复制过来或者加入到include的头文件中去
- 转到当前目录
cl.exe /c app.c
link app.obj D:\YearJunior1\SoftwareProjectSecurityDevelopmentLifecycle\EXP4\Base\Base\base.lib /out:app.exe
dumpbin /imports app.exe
- .exe->dll有两种方式:①load time 会在加载时加入lib,并且会有imports table;②run time:通过指针进行调用
- 会编写dll。把.c文件编译为obj文件,把obj文件和lib文件链接为新的dll和lib文件。注意使用def文件定义导出函数。
- 编写一个exe,调用第一步生成的dll文件中的导出函数。方法是(1)link是,将第一步生成的lib文件作为输入文件。(2)保证dll文件和exe文件在同一个目录,或者dll文件在系统目录。
- 第二步调用方式称为load time 特点是exe文件导入表中会出先需要调用的dll文件名及函数名,并且在link 生成exe是,需明确输入lib文件。还有一种调用方式称为 run time。参考上面的链接,使用run time的方式,调用dll的导出函数。包括系统API和第一步自行生成的dll,都要能成功调用。 参考资料
- 提示
link /dll /def:xxx.def
link xxx.lib /out:app.exe
dumpbin /exports xxx.dll
dumpbin /imports xxx.exe
- 在./EXP/base1中加入下列代码
- 新建
D:\YearJunior1\SoftwareProjectSecurityDevelopmentLifecycle\EXP5\loader
#include <Windows.h>
// 数据类型,函数指针类型
typedef int (WINAPI* MY_PROC)(char*);
int main()
{
HMODULE hBaselib = LoadLibraryA("baselib.dll");
if (hBaselib == NULL)
return 0;
MY_PROC func = (MY_PROC)GetProcAddress(
hBaselib, "lib_function");
func("run time load");
}
- 流程图
- DLL劫持
- 加载dll,如果当前目录下有,就加载;如果没有,就去系统文件夹下查找
- hacker在当前目录下放一个kernel32.dll,然后这个kernel32.dll会再去load系统下的kernel32.dll
#include <stdio.h>
#include <Windows.h>
#include <tlhelp32.h>
#include "fheaders.h"
DWORD demoCreateRemoteThreadW(PCWSTR pszLibFile, DWORD dwProcessId)
{
// Calculate the number of bytes needed for the DLL's pathname
DWORD dwSize = (lstrlenW(pszLibFile) + 1) * sizeof(wchar_t);
// Get process handle passing in the process ID
//PROCESS_VM_WRITE, //对内存进行写入
HANDLE hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION |
PROCESS_CREATE_THREAD |
PROCESS_VM_OPERATION |
PROCESS_VM_WRITE,
FALSE, dwProcessId);
if (hProcess == NULL)
{
wprintf(TEXT("[-] Error: Could not open process for PID (%d).\n"), dwProcessId);
return(1);
}
// Allocate space in the remote process for the pathname
// 给这段进程分配一个内存
// VirtualAlloc给别的进程分配内存
LPVOID pszLibFileRemote = (PWSTR)VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
if (pszLibFileRemote == NULL)
{
wprintf(TEXT("[-] Error: Could not allocate memory inside PID (%d).\n"), dwProcessId);
return(1);
}
// Copy the DLL's pathname to the remote process address space
DWORD n = WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID)pszLibFile, dwSize, NULL);
if (n == 0)
{
wprintf(TEXT("[-] Error: Could not write any bytes into the PID [%d] address space.\n"), dwProcessId);
return(1);
}
// Get the real address of LoadLibraryW in Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
if (pfnThreadRtn == NULL)
{
wprintf(TEXT("[-] Error: Could not find LoadLibraryA function inside kernel32.dll library.\n"));
return(1);
}
// Create a remote thread that calls LoadLibraryW(DLLPathname)
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, pfnThreadRtn, pszLibFileRemote, 0, NULL);
if (hThread == NULL)
{
wprintf(TEXT("[-] Error: Could not create the Remote Thread.\n"));
return(1);
}
else
wprintf(TEXT("[+] Success: DLL injected via CreateRemoteThread().\n"));
// Wait for the remote thread to terminate
WaitForSingleObject(hThread, INFINITE);
// Free the remote memory that contained the DLL's pathname and close Handles
if (pszLibFileRemote != NULL)
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
return(0);
}
- 查文档,研究远程线程方式注入dll的实例代码的实现原理。
- 运行实例代码,向一个目标程序(比如notepad.exe)注入一个我们自行编写的dll,加载运行
- 整合进程遍历的程序,使得攻击程序可以自己遍历进程得到目标程序的pid。
- 下载执行
- 恶意软件
- 授课内容:dll 注入+API hook技术实现对软件行为的篡改,是实现文件或者进程隐藏,外挂等的基础技术。
- 重点内容IAT hook 是API hook的一种,API hook是通过修改函数的地址从而达到篡改程序行为的一种技术。
- IAT : 导入地址表
- hook技术通常与注入技术配合使用。
- 可以解析PE 文件的工具: dumpbin /headers 、 PE explorer
D:\YearJunior1\SoftwareProjectSecurityDevelopmentLifecycle\EXP5\loader
- 开发者工具解析loader.exe
cd D:\YearJunior1\SoftwareProjectSecurityDevelopmentLifecycle\EXP5\loader\Debug
d:
dumpbin /headers loader.exe
时间戳就是1970年到现在的时间
5. PE Exproer解析
- 解构文件来找到系统文件所在的地方。信箱是没有加锁,谁都可以进行读和写
- 修改了这个地址,到时候运行的时候一call,就运行到了一个假的地址,就被劫持
- IAT hook原理就是替换IAT表中原本村的真实的系统地址,导致调用的时候调用了一个假的地址
- git clone https://github.com/tinysec/iathook.git
- 将readme.md复制为main.c,不是代码的部分删掉
- 开发者工具,转到目录D:\YearJunior1\SoftwareProjectSecurityDevelopmentLifecycle\EXP5\IAT\iathook
cl /c IATHook.c
,cl /c main.c
link main.obj IATHook.obj user32.lib /out:IAT.exe
6. IAT.exe
运行一下
7. 新建一个工程D:\YearJunior1\SoftwareProjectSecurityDevelopmentLifecycle\EXP5\Hook
wmain ,iathook,下断点,和中间的MEssageBoxA中间也下断点。执行到message,会发现这个位置改变
线程注入技术和IATHook综合应用(记事本,dir,计算器)
- hook writefile,自己调用writefile(首先create WRItefilr),使得每次写文件haha->hehe
- 把hook writefile 写为dll通过今天下午的实例代码,把他注入到notepad类似进程中,进行hook
- 试验一下hook是否成功
- 同样原理可以改 find firstfile和 nextfile,注入cmd,输入dir,只要输出hacker.exe就将磨掉
- 让系统的进程,Pass Maneger,tasklist遍历不到hacker.exe这样的进程
- 计算器 setwindowstext,不改输出,但是记录计算器的输出,实现屏幕取词。
- 接管其他进程,比如键盘输入,微信进程文本框输入