https://q.qlogo.cn/headimg_dl?dst_uin=46113931&spec=640&img_type=jpg

Tupler's Blog~

[从零开始的免杀生活]01.ShellCode存储与执行

0x00.前言 上篇内容讲到shellcode的基础知识,这篇文章来讲解一下一些基础的申请内存已经修改保护属性的代码 0x01.内存的申请 在winapi中 R3层面上 有几种申请内存的API 例如 VirtualAlloc HeapAlloc GlobalAlloc 其中 VirtualAlloc 是真向操作系统申请一块虚拟内存,而HeapAlloc 则是向已有的堆内存区域分配一块,可能有人会说那malloc 和new 呢这些都能 申请内存。 实际上malloc函数在win上 底层调用的即为 HeapAlloc 而new则是一个运算符 实际为 malloc+构造函数 本质上在win还是 HeapAlloc 还有一些NT函数 可以逃过杀软的函数检测 例如 NtAllocateVirtualMemory NtCreateSection VirtualAlloc 微软官方函数定义 LPVOID VirtualAlloc( [in, optional] LPVOID lpAddress, //起始地址 [in] SIZE_T dwSize, //分配的大小 [in] DWORD flAllocationType, //申请的类型 [in] DWORD flProtect //申请的保护权限 ); C++代码实现 0 1 2 3 4 5 6 7 8 #include <iostream> #include <windows.h> int main(){ LPVOID testbuffer =VirtualAlloc(NULL,0x1024,MEM_COMMIT|MEM_REVERSE,PAGE_EXECUTE_READWRITE); return 0; } HeapAlloc 微软官方函数定义

[从零开始的免杀生活]00.序

0x00.了解杀软 国内杀毒厂商 360 火绒 金山毒霸 腾讯电脑管家 国外杀毒厂商 BD Windows Defender 小红伞 0x01. 了解静态杀毒原理 杀毒引擎包含几种查杀方式 基于yara规则 基于启发式引擎 基于混乱程度san值检测 0x03.了解Shellcode GPT解答: 0 Shellcode是一种用于利用计算机程序漏洞的恶意代码,通常是用汇编语言编写的,用于执行特定任务,如破解系统安全、执行恶意软件、获取系统权限等。Shellcode通常很小,因为它必须适合在漏洞中注入或植入恶意软件中,因此它需要非常紧凑和高效。 这个解释应该用在pwn中 呃呃,我们主要就是把我们的恶意代码编写成shellcode后可以更容易的混淆 然后再内存中动态的加载,这样基于字符串,iat检测的杀软就无从下手了 0x04.了解特征码 什么是特征码呢?特征码就是在一个程序中独特的代码 例如你这个程序中加了个版权信息 powered by tupler 这串text的ascii码就可以被当做是特征码,当你这个软件为恶意程序时 上传的样本经过人员分析或者是沙箱分析将该程序判为黑时就会将此特征码放入数据库中,当下次这个杀软再检测到这串特征时就会将该程序识别为恶意程序, PS: 杀软不是一定会完整的把一整串字符串当做特征,可能会取其中一部分,也可能不是将字符串,可能是某处完整的代码,例如 //此处为伪代码,参数未填写 CreateFile(xxxxxxx) CopyFile(xxxxxx) ShellExecute(xxxxx) 当这三个函数同时存在时并顺序为当前顺序就会很容易被杀软特征 0x05.一般免杀做法基于Shellcode混淆与执行 通过加密shellcode存储在堆栈中 在内存中进行解密并设置内存可执行权限 执行shellcode 以上是一般普通的混淆免杀做法,因为该类样本十分的多,所以该免杀效果对于一些将某些函数定为特征的杀软并不是很好~ 0x06.特定杀软喜欢杀的地方 我们知道一个程序执行肯定有自己的一套算法,杀软也一样,不同的杀软对于查杀的侧重点不一样,静态来说 火绒: 字符串 iat导入函数 而且会有个微型沙箱进行运行后对模拟的沙箱内存进行yara匹配shellcode 360: 资源信息 签名信息 字符串 壳的特征 敏感函数调用 DEFENDER:比较均衡 主要是查敏感函数调用 以及 shellcode ,就我测试来看 普通的加密方式似乎对defender无用

谷歌上钓鱼电报软件中的Lolbins分析

2023.7.20发布 0x00.前言 最近在谷歌上发现一个msi安装文件 发现里面用的Shellcode loader是一个有签名的文件 于是乎就想着分析一波是什么情况 0x01.查壳 发现upx直接脱了 upx -d或者 esp定律 0x01.静态分析 观察.dat的文件发现是zip 但是需要密码 因为会加载同目录的.dat文件我们直接搜索字符串.dat 跟进去看看 发现一些提示文字 Failed to extract project file (2) to me 这边应该是解压的 交叉引用看看 根据上下文 分析出99B2328D3FDF4E9E98559B4414F7ACB9 为解压密码 解压出来有5个文件 其中_TUProj.dat包含着lua加载shellcode的代码 0x03.再利用 我们将其中的shellcode改成信息框的shellcode 并用注释符号保持文件原来的大小 成功~ 因为有数字签名所以基本不杀 8.1更新 可以用TrueUpdate这个软件进行编辑~

【CTFSHWO_月饼杯_re】re

re re1._西北望乡 64 位 无壳 因为比较简单就 直接看汇编 逆出来 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 _arr={11377526307,11291274669,10667335421,12105207237,12005384512,10853488462,12005544354,10651566902,5399147315,11333307}; char c[]="mm"; //输入的flag int x[]; int key[5]; key[0]=c[3]; key[1]=c[6]; key[2]=c[13]; key[3]=c[36]; key[4]=13; for(int i=0;i<5;i++){ int temp1=1; for(int j=0;j<5-i;++j){ key[4-i]*=temp1; temp1=key[4-i]; } key[i]=temp1; } for(int i=0;i<9;i++){ temp3=0; for(int j=0;j<5;j++){ key[j]=c[i*5+j]*key[j] +temp3; temp3=key[j]; } if(temp3!=arr[i]){ break; } } 程序流程 先将temp输入的值 取了4个放入a数组中 最后一位为13 第一个for循环为 key[i]**(i+1) 将自身进行次方 第二个for循环进行将输入的flag进行分成9组 然后和上面的key进行 相乘然后将 五个字符乘完的结果相加 最后与arr数组进行对比 解密流程 由于flag由"flag{“开头 可以爆破的到key 然后再用key继续爆破后续 内容

[ak赛]EasyDSE

0x00.查壳 无壳 64位 0x01.IDA看 没加花 直接F5 方便看 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 int __cdecl main(int argc, const char **argv, const char **envp) { char C[34]; // [rsp+20h] [rbp-60h] BYREF int key_pre[64]; // [rsp+50h] [rbp-30h] BYREF int m[128]; // [rsp+150h] [rbp+D0h] BYREF int dest[16][48]; // [rsp+350h] [rbp+2D0h] BYREF int i; // [rsp+F5Ch] [rbp+EDCh] // m是输入的STR的二进制 // _main(); while ( 1 ) { while ( getstr(m) ) // m=bin(hex(str)) ; getkey(key_pre); // key_pre=bin(hex(str)) exchangeIP(key, key_pre, PC_1, 56); //根据表PC_1进行置换 获得key数据 getroundkey(dest[0], key); //根据key进行一系列运算获取dest_KEY exchangeIP(mint, m, IP_first, 64); // 根据表将m的前64项置换成mint encode(mint, dest); //加密mint 即为加密前半部分m exchangeIP(m, mint, IP_last, 64); //将加密完的前半部分数据 根据ip_LAST表置换 exchangeIP(mint, &m[64], IP_first, 64); // 加密后半部分 跟前面类似 encode(mint, dest); exchangeIP(&m[64], mint, IP_last, 64); for ( i = 0; i <= 127; i += 4 ) C[i / 4] = hex_re(&m[i]); C[32] = 0; puts(C); if ( !