CVE exploit

CVE-2024-23897 : Data Leak Vulnerability

Kortsec1 2024. 2. 13. 02:26

 

요약

Jenkins-CLI의 인자속 '@' 문자가 존재하면 해당 경로의 파일을 읽어들이는 버그이다. 해당 버그는 권한 설정 中 "Allow anonymous read access"와 같이 비인가 사용자에게 읽기 권한을 부여하는 상황에서 발생한다. 이러한 버그는 Jenkins 서버의 중요한 파일들을 읽어올 수 있게하며, 심각한 피해로 이어질 수 있다. 해당 취약점은 Jenkins versions 2.442 와 LTS 2.426.3. 버전부로 조치되었다.

 

취약점 상세

Jenkins는 다양한 방식의 인증방식을 제공한다. "Anyone can do anything", "Legacy mode", "Logged-in users can do anything" 등 아래 그림을 참고하자. "Logged-in users can do anything" 과 같은 경우, 선택 시 "Allow anonymous read access" 옵션을 추가로 선택할 수 있다.

multiple ways of authorization

또한, 다른 사용자의 계정 생성을 가능하게 하는 옵션도 존재한다. 이러한 경우 다른 모든 사람들에게 최소한 read-only 권한을 주는 것과 다름없다.

allow users to sign up

공식 문서에 의하면, read-only 권한을 획득한 사용자는 다음과 같은 접근이 가능하다.

  • Access the basic Jenkins API and the API of any object they have access to.
  • Access the people directory listing user accounts and known committer identities of anyone involved in visible projects.
  • List and view all agents configured in Jenkins and access their summary pages.

 

 

이어, Jenkins-CLI 는 사용자에게 built-in command line interface를 제공한다. 해당 CLI에서는 Jenkins Git 의 hudson/cli 디렉터리에 있는 커스텀 명령들을 수행할 수 있다. 

jenkins-cli.jar를 이용한 명령 수행

CLI 명령 수행 시, Jenkins는 아래 expandAtFiles로 이어지는 args4j의 parseArgument를 이용한다.

private String[] expandAtFiles(String args[]) throws CmdLineException {
    List<String> result = new ArrayList<String>();
    for (String arg : args) {
        if (arg.startsWith("@")) {
            File file = new File(arg.substring(1));
            if (!file.exists())
                throw new CmdLineException(this,Messages.NO_SUCH_FILE,file.getPath());
            try {
                result.addAll(readAllLines(file));
            } catch (IOException ex) {
                throw new CmdLineException(this, "Failed to parse "+file,ex);
            }
        } else {
            result.add(arg);
        }
    }
    return result.toArray(new String[result.size()]);
}

 

expandAtFiles 함수는 인자가 '@'문자로 시작된다면, 해당 경로의 파일을 읽어들여 각 line을 새로운 인자로 반환한다. 이는 공격자가 인자를 관리할 수만 있다면 임의의 서버 파일속 내용을 전부 확인 할 수 있게 된다는 뜻이기도 하다. 그에대한 예시는 아래에서 살펴보도록 하자.

expandAtFiles 함수의 과정

 

이러한 공격은 connect-node 명령으로 접근이 가능하다. 아래 코드에서 확인할 수 있듯 해당 명령은 문자열로 이루어진 배열(노드)을 인자로 받아, 각각의 연결을 시도한다. 중요한 점은 각 연결이 실패할 경우 error 메세지가 생성되는데 이 때 메세지에는 연결에 실패한 node의 이름을 포함한다.

public class ConnectNodeCommand extends CLICommand {

    @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
    @Argument(metaVar = "NAME", usage = "Agent name, or empty string for built-in node; comma-separated list is supported", required = true, multiValued = true)
    private List<String> nodes;

    @Option(name = "-f", usage = "Cancel any currently pending connect operation and retry from scratch")
    public boolean force = false;

    private static final Logger LOGGER = Logger.getLogger(ConnectNodeCommand.class.getName());

    @Override
    public String getShortDescription() {
        return Messages.ConnectNodeCommand_ShortDescription();
    }

    @Override
    protected int run() throws Exception {
        boolean errorOccurred = false;
        final HashSet<String> hs = new HashSet<>(nodes);

        for (String node_s : hs) {
            try {
                Computer computer = Computer.resolveForCLI(node_s);
                computer.cliConnect(force);
            } catch (Exception e) {
                if (hs.size() == 1) {
                    throw e;
                }
                final String errorMsg = node_s + ": " + e.getMessage();
                stderr.println(errorMsg);
                errorOccurred = true;
                continue;
            }
        }
        if (errorOccurred) {
            throw new AbortException(CLI_LISTPARAM_SUMMARY_ERROR_TEXT);
        }
        return 0;
    }
}

 

connect-node 명령을 정상적으로 수행하기 위해선 기본적으로 cliConnect 메서드에서 검증하는 CONNECT 권한이 있어야 한다. 하지만 권한 검증 이전에 resolveForCLI 함수에서 예외가 발생하기 때문에 현재로선 권한을 고려할 필요가 없게된다. 위 코드를 보면 알 수 있는 사실이다.

connect-node 명령의 수행 결과

 

이러한 CVE-2024-23897 취약점은 SSH keys, /et/passwd, /etc/shadow, Project secrets and credentials 등 수많은 민감한 파일에 접근을 허용한다. 아래 사진은 공격자가 서버 파일을 읽어들인 예시 상황이다.

exploit_CVE-2024-23897

 

참고