반응형
ClamAV, 알약, V3, Avast 모두 web shell을 찾지는 못하였다..
그래서, 그냥 직접 만들자. 그러면 기본적인 부분은 찾을 수 있겠다 싶어서 직접 만들어서 찾아보도록 했다.
그런데 대략 300만개 이미지 파일을 검사를 하는데에 시간이 오래걸리긴 했지만...
5개가 검출되었고, php 코드가 숨겨져있었다.
기본적인 소스코드는 아래와 같다.
import java.io.*;
/**
* ImageFileInWebShellChecker : 파라미터로 받은 경로를 기반으로 이미지 파일을 찾고 이미지 속에 웹쉘이 존재하는지 체크하는 클래스
*
* @author mitw
* @version 1.0
*/
public class ImageFileInWebShellChecker {
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Usage: java RecursiveCodeSecurityChecker <directory_path>");
System.exit(1);
}
try {
String directoryPath = args[0];
checkFilesInDirectory(new File(directoryPath));
} catch (Exception e) {
e.printStackTrace();
}
}
private static void checkFilesInDirectory(File directory) throws IOException {
if (directory.isDirectory()) {
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
// 하위 디렉토리 탐색
checkFilesInDirectory(file);
} else {
// 파일 검사
checkFile(file);
}
}
}
}
}
private static void checkFile(File file) throws IOException {
System.out.println("Checking: " + file.getAbsolutePath());
if(! isImageFile(file)) {
if (file.getName().toLowerCase(Locale.ROOT).contains("png")
|| file.getName().toLowerCase(Locale.ROOT).contains("jpg")
|| file.getName().toLowerCase(Locale.ROOT).contains("gif")
|| file.getName().toLowerCase(Locale.ROOT).contains("jpeg")
|| file.getName().toLowerCase(Locale.ROOT).contains("bmp")
|| file.getName().toLowerCase(Locale.ROOT).contains("tiff")
|| file.getName().toLowerCase(Locale.ROOT).contains("tif")
|| file.getName().toLowerCase(Locale.ROOT).contains("jfif")
) {
System.out.println(">>>> danger image file. There is a risk web shell or broken file !!! ");
} else {
System.out.println(">>>> No image file ... ");
}
} else {
if(containsWebShell(file)) {
System.out.println(">>>> danger image file. There is a risk web shell !!! ");
} else {
System.out.println(">>>> not danger image file. ");
}
}
}
private static boolean isImageFile(File file) throws IOException {
try (FileInputStream inputStream = new FileInputStream(file)) {
byte[] header = new byte[8];
inputStream.read(header);
return isImageType(header);
}
}
//jpeg, png, gif, bmp, tiff, jfif 헤더 체크
private static boolean isImageType(byte[] header) {
return (header[0] == (byte) 0xFF && header[1] == (byte) 0xD8 && header[2] == (byte) 0xFF)
|| (header[0] == (byte) 0x89 && header[1] == (byte) 0x50 && header[2] == (byte) 0x4E && header[3] == (byte) 0x47)
|| (header[0] == (byte) 0x47 && header[1] == (byte) 0x49 && header[2] == (byte) 0x46)
|| (header[0] == (byte) 0x42 && header[1] == (byte) 0x4D)
|| (header[0] == (byte) 0x4D && header[1] == (byte) 0x4D) || (header[0] == (byte) 0x49 && header[1] == (byte) 0x49)
|| (header[0] == (byte) 0x4A && header[1] == (byte) 0x46 && header[2] == (byte) 0x49 && header[3] == (byte) 0x46);
}
private static boolean containsWebShell(File file) throws IOException {
try (FileInputStream inputStream = new FileInputStream(file)) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
String content = new String(buffer, 0, bytesRead);
// PHP 코드 패턴 검사
if (content.contains("<?php")) {
System.out.println(">>> PHP");
System.out.println(">>> " + content);
return true;
}
// JSP 코드 패턴 검사
if (content.contains("<%@ ") || content.contains("<jsp:")) {
System.out.println(">>> JSP");
System.out.println(">>> " + content);
return true;
}
// JAVASCRIPT 코드 패턴 검사
if (content.contains("eval(") || content.contains("<script")) {
System.out.println(">>> script");
System.out.println(">>> " + content);
return true;
}
// JSP 코드 패턴 검사
if (content.contains("ASP.NET")) {
System.out.println(">>> ASP.NET");
System.out.println(">>> " + content);
return true;
}
}
}
return false;
}
}
위 내용을 가지고 intellij 로 jar를 만들어서 실행을 하였다.
아래와 같이 jar를 만들어서 실행하면 된다.
java -jar ./ImageFileInWebShellChecker.jar <path>
ex> java -jar ./ImageFileInWebShellChecker.jar C:\Users\Kks\Pictures\image
아래는 테스트성 검사를 진행한 부분이다.
C:\work>java -jar ./ImageFileInWebShellChecker.jar C:\Users\Kks\Pictures\image
Checking: C:\Users\Kks\Pictures\image\0b6936bec8ee32bf3e381e9000e1ded6--black-letter-letter-k.jpg
>>>> not danger image file.
Checking: C:\Users\Kks\Pictures\image\musiciocom.jpg
>>>> not danger image file.
Checking: C:\Users\Kks\Pictures\image\sx.jpg
>>>> not danger image file.
서버에서 검출된 내용의 경우, 실무에서 사용한 부분이라서 보안을 위해 공개를 하지 않겠음.
'Server' 카테고리의 다른 글
GitLab CI/CD 설정 (Gitlab Runners) (0) | 2024.07.18 |
---|---|
ca-certificates를 설치하였지만, update-ca-certificates command not found 가 발생하는 경우.. (1) | 2024.07.17 |
ClamAV - linux / unix 기반의 오픈 소스 Anti Virus (1) | 2023.11.14 |
git/svn 저장소에서 git clone / svn checkout 할 경우 특정파일이 받아지지 않는 경우 (feat. 파일명이 혹시 한글인가?) (0) | 2023.10.04 |
netlify 무료 웹 호스팅 / 네트리파이 (0) | 2022.01.06 |
댓글