Hiển thị PHP png

Trong PHP, imagecreatefrompng[] là một hàm sẵn có được sử dụng để tạo một hình ảnh mới từ tệp PNG hoặc URL. imagecreatefrompng[] trả về một định danh hình ảnh đại diện cho hình ảnh thu được từ tên tệp đã cho

cú pháp

resource imagecreatefrompng[string $filename]

Thông số

imagecreatefrompng[] chỉ nhận một tham số, $filename. Tham số này giữ tên của hình ảnh hoặc đường dẫn đến hình ảnh PNG

Giá trị trả về

imagecreatefrompng[] trả về mã định danh tài nguyên hình ảnh khi thành công và nó báo lỗi sai

Ví dụ 1 - Hiển thị hình ảnh PNG đã tải trong trình duyệt

đầu ra

Ví dụ 2 - Đã tải và lưu hình ảnh PNG trong đường dẫn ổ đĩa cục bộ

đầu ra

Giải thích - Trong ví dụ 2, hình ảnh png được tải từ đường dẫn cục bộ bằng cách sử dụng hàm imagecreatefrompng[]. Sau đó, chúng tôi đã chuyển đổi hình ảnh png thành hình ảnh gif và lưu nó vào ổ đĩa cục bộ bằng cách đưa ra đường dẫn để lưu hình ảnh gif

Các chức năng tải lên hình ảnh cực kỳ phổ biến trong các ứng dụng web. cho dù bạn muốn đặt ảnh hồ sơ của mình, minh họa một bài đăng trên blog hay cho cả thế giới thấy loại chim hải âu yêu thích của mình, ứng dụng hiện tại sẽ phải xử lý các hình ảnh do người dùng cung cấp

Tuy nhiên, cấu hình sai nhỏ của máy chủ bên dưới hoặc việc khai thác các lỗ hổng thứ cấp có thể cho phép kẻ tấn công đưa mã độc vào các tệp hình ảnh được tải lên thông qua các chức năng đó và buộc máy chủ thực thi nó. Điều này có thể đặc biệt nguy hiểm đối với các ứng dụng PHP và dẫn đến việc thực thi mã từ xa thông qua việc diễn giải mã PHP tùy ý

Vì lý do này, điều đặc biệt quan trọng khi pentest một ứng dụng PHP là phải có kiến ​​thức chính xác về các kỹ thuật khác nhau mà kẻ tấn công sử dụng để chuyển lậu các tải trọng PHP thông qua các tệp hình ảnh – ngay cả trong các tình huống phức tạp tiềm tàng

Đây là những gì bài viết này là tất cả về. Mặc dù nó không giới thiệu bất kỳ kỹ thuật đột phá mới nào, nhưng nó nhằm mục đích kiểm tra cụ thể, thông qua một nghiên cứu điển hình, các kỹ thuật buôn lậu tải trọng đã biết khác nhau mà kẻ tấn công có thể sử dụng để thực thi mã PHP tùy ý

 

0. Bối cảnh, ứng dụng dễ bị tổn thương và thiết lập phòng thí nghiệm

Phần này mô tả tình huống được xem xét. Chúng tôi đang đánh giá một ứng dụng PHP đơn giản được xây dựng bằng Symfony cho phép người dùng tải lên hình ảnh, sau đó lưu trữ những hình ảnh này trên hệ thống tệp để hiển thị chúng. Mã nguồn của ứng dụng này có thể được truy cập trong kho lưu trữ sau. https. //github. com/synacktiv/astrolock.

Đây là trang duy nhất của ứng dụng trông như thế nào [đừng bận tâm đến thiết kế có vấn đề]

Trang duy nhất của ứng dụng web

Như được hiển thị trong ảnh chụp màn hình ở trên, ứng dụng cho phép người dùng thêm bộ đồ không gian thông qua biểu mẫu ở phần trên cùng, sử dụng hình ảnh ở định dạng PNG. Bộ đồ sau đó sẽ được hiển thị ở phần dưới

Cấu trúc của ứng dụng khá đơn giản

  • # Create the 'suit' object and link it to the Symfony form
    $suit = new Suit[];
    $form = $this->createForm[SuitType::class, $suit];
    $form->handleRequest[$request];
    
    # The form is submitted and valid if the user defined a title, a description,
    # and uploaded a file with the PNG MIME type 
    if [$form->isSubmitted[] && $form->isValid[]] {
                
        # Get the file uploaded through the form
        $suitFile = $form->get['suit']->getData[];
    
        # Build a unique filename from original filename
        $originalFilename = $suitFile->getClientOriginalName[];
        $newFilename = uniqid[].'_'.$originalFilename;
    
        # Store the uploaded file with the unique filename on the webservers in the 
        # thumbnails directory, which is simply {web_root}/suits_thumbnails/
        try {
             $suitFile->move[
                 $this->getParameter['thumbnails_directory'],
                 $newFilename
            ];
            $suit->setSuitFilename[$newFilename];
         } catch [FileException $e] {
              return new Response["File exception"];
         }
    
         # Store the 'suit' object in the database to persist it
         $entityManager->persist[$suit];
         $entityManager->flush[];
         return $this->redirectToRoute['app_home_homepage'];
    }
    7 và
    # Create the 'suit' object and link it to the Symfony form
    $suit = new Suit[];
    $form = $this->createForm[SuitType::class, $suit];
    $form->handleRequest[$request];
    
    # The form is submitted and valid if the user defined a title, a description,
    # and uploaded a file with the PNG MIME type 
    if [$form->isSubmitted[] && $form->isValid[]] {
                
        # Get the file uploaded through the form
        $suitFile = $form->get['suit']->getData[];
    
        # Build a unique filename from original filename
        $originalFilename = $suitFile->getClientOriginalName[];
        $newFilename = uniqid[].'_'.$originalFilename;
    
        # Store the uploaded file with the unique filename on the webservers in the 
        # thumbnails directory, which is simply {web_root}/suits_thumbnails/
        try {
             $suitFile->move[
                 $this->getParameter['thumbnails_directory'],
                 $newFilename
            ];
            $suit->setSuitFilename[$newFilename];
         } catch [FileException $e] {
              return new Response["File exception"];
         }
    
         # Store the 'suit' object in the database to persist it
         $entityManager->persist[$suit];
         $entityManager->flush[];
         return $this->redirectToRoute['app_home_homepage'];
    }
    8 xử lý các đối tượng « suit » sẽ được lưu trữ trong cơ sở dữ liệu với tên, mô tả và tên tệp của hình ảnh được liên kết
  • # Create the 'suit' object and link it to the Symfony form
    $suit = new Suit[];
    $form = $this->createForm[SuitType::class, $suit];
    $form->handleRequest[$request];
    
    # The form is submitted and valid if the user defined a title, a description,
    # and uploaded a file with the PNG MIME type 
    if [$form->isSubmitted[] && $form->isValid[]] {
                
        # Get the file uploaded through the form
        $suitFile = $form->get['suit']->getData[];
    
        # Build a unique filename from original filename
        $originalFilename = $suitFile->getClientOriginalName[];
        $newFilename = uniqid[].'_'.$originalFilename;
    
        # Store the uploaded file with the unique filename on the webservers in the 
        # thumbnails directory, which is simply {web_root}/suits_thumbnails/
        try {
             $suitFile->move[
                 $this->getParameter['thumbnails_directory'],
                 $newFilename
            ];
            $suit->setSuitFilename[$newFilename];
         } catch [FileException $e] {
              return new Response["File exception"];
         }
    
         # Store the 'suit' object in the database to persist it
         $entityManager->persist[$suit];
         $entityManager->flush[];
         return $this->redirectToRoute['app_home_homepage'];
    }
    9 được sử dụng để xác định biểu mẫu cho phép người dùng tải lên các bộ quần áo
  • $ exiftool -comment="" nasa.png
    0 là bộ điều khiển chính của ứng dụng. Nó chủ yếu xác định bốn tuyến đường, sẽ được sử dụng để minh họa các tình huống khác nhau được xem xét trong bốn phần tiếp theo của bài viết này
    • $ exiftool -comment="" nasa.png
      1
    • $ exiftool -comment="" nasa.png
      2
    • $ exiftool -comment="" nasa.png
      3
    • $ exiftool -comment="" nasa.png
      4

Dưới đây là các điều kiện tiên quyết để chạy ứng dụng

  • Symfony [đã thử nghiệm với Symfony 6. 1] và PHP [thử nghiệm với PHP 8. 1]
  • Trình điều khiển SQLite3 PHP [php8. 1-sqlite3 cho hệ thống Debian]
  • PHP-GD [dành cho phần 2. và 3. của bài viết]
  • Tưởng tượng [cho phần 4. của bài viết]

Khi các yêu cầu được đáp ứng, hãy thực hiện các lệnh này để chạy ứng dụng cục bộ trên cổng 8000

$ git clone //github.com/synacktiv/astrolock
$ cd astrolock
$ composer install
$ php -S localhost:8000

 

1. Trở lại vấn đề cơ bản. tiêm đơn giản trong các tệp PNG

Phần đầu tiên này sẽ mô tả trường hợp đơn giản và cơ bản nhất của PHP payload injection trong ảnh PNG, dẫn đến việc thực thi mã PHP tùy ý. Để minh họa điều này, chúng tôi sẽ sử dụng tuyến đường

$ exiftool -comment="" nasa.png
1. Khi người dùng tải lên một bộ đồ bằng cách sử dụng tuyến đường này, đây là mã Symfony có liên quan sẽ được thực thi

  • src\Controller\HomeController. phphàm công khai FirstPart

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}

Việc này thật thẳng thắn. biểu mẫu web yêu cầu tiêu đề, mô tả và tệp PNG hợp lệ. Sau đó, ứng dụng sẽ lấy dữ liệu từ tệp hình ảnh đã tải lên, tạo một tên tệp duy nhất từ ​​tên tệp ban đầu và chỉ cần lưu trữ tệp trên hệ thống tệp [trong thư mục

$ exiftool -comment="" nasa.png
6, có thể truy cập công khai]

Giả sử một người dùng đã tải một bộ đồ của NASA lên trang web, với tên tệp ban đầu là nasa. png . Sau đó, nó sẽ được hiển thị trên trang chủ của ứng dụng và hình ảnh liên quan đến vụ kiện sẽ có thể truy cập được từ một URL có định dạng sau.

$ exiftool -comment="" nasa.png
7

Một tập tin hợp pháp tải lên ứng dụng

Cho đến nay rất tốt. Tuy nhiên, tính năng xử lý hình ảnh trong lộ trình đầu tiên này có một lỗ hổng nghiêm trọng. Do ứng dụng sử dụng tên tệp gốc của hình ảnh đã tải lên để lưu trữ nên người dùng kiểm soát phần mở rộng của tệp hình ảnh trên máy chủ web. Sau đó, kẻ tấn công có thể dễ dàng đặt tên cho tệp nasa. php và tải nó lên ứng dụng . sau đó nó sẽ được lưu trữ trên máy chủ web dưới dạng.

$ exiftool -comment="" nasa.png
8

Nếu tệp này chứa mã PHP hợp lệ, nó sẽ được thực thi bởi máy chủ khi người dùng yêu cầu. Hạn chế duy nhất là tệp này phải là tệp PNG hợp lệ, vì biểu mẫu Symfony kiểm tra loại MIME của hình ảnh được tải lên. kẻ tấn công không thể đơn giản tạo tập lệnh PHP cơ bản ; . Trong cấu hình của tuyến đường đầu tiên này, có thể sử dụng hai kỹ thuật tiêm PHP đơn giản

 

[Phương pháp số 1] Nhận xét PNG

Định dạng hình ảnh PNG cho phép thêming nhận xét vào tệp để lưu trữ một số siêu dữ liệu khác [xem . Chúng được xác định dễ dàng và là nơi hoàn hảo để đưa tải trọng PHP của chúng tôi. Ví dụ, một người có thể định nghĩa một nhận xét bằng cách sử dụng the PNG documentation]. These are easily defined, and a perfect place to inject our PHP payload. One could for instance define a comment using exiftool theo cách sau.

$ exiftool -comment="" nasa.png

Để xác nhận việc đưa trọng tải của chúng tôi vào nasa. png, chúng ta có thể kiểm tra dữ liệu chứa trong tệp ở định dạng thập lục phân bằng một

$ exiftool -comment="" nasa.png
9 đơn giản.

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
7

Tất cả những gì còn lại phải làm, đó là đổi tên nasa. png đến nasa. php , tải nó lên ứng dụng và truy cập nó thông qua thư mục có sẵn công khai ____170 . Máy chủ web sẽ diễn giải tệp dưới dạng tập lệnh PHP, bỏ qua tất cả dữ liệu hợp lệ của tệp PNG gốc và chỉ cần thực thi tải trọng PHP của chúng tôi sẽ được tìm thấy trong phần nhận xét của tệp.

Tải trọng PHP được thực thi thông qua nhận xét PNG 

[Phương pháp số 2] Chèn thô

Có thể sử dụng một phương thức đơn giản hơn nữa trong cấu hình đầu tiên này để để đưa tải trọng PHP của chúng tôi vào PNG. Người ta có thể chỉ cần thêm mã PHP sau dữ liệu của tệp PNG gốc.

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
9

Ngay cả khi tải trọng PHP của chúng tôi được chèn ở cuối, loại MIME của tệp vẫn được coi là

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
71. Vì tệp được tải lên máy chủ web nguyên trạng, mà không cần xử lý thêm, tải trọng PHP theo sau sẽ vẫn còn trong tệp. Sau đó, nó sẽ được thực thi bởi máy chủ theo cách tương tự như đối với .

 

2. Đánh bại quá trình nén hình ảnh PHP-GD

Tuy nhiên, hầu hết thời gian, các tệp hình ảnh không được lưu trữ nguyên trạng trên máy chủ, . Hình ảnh được thay đổi kích thước, nén hoặc mã hóa thành các định dạng tệp cụ thể bằng cách sử dụng một số thư viện PHP tiêu chuẩn như as assumed in the first part of the article. Images are resized, compressed or encoded into specific file formats using some standard PHP libraries like PHP-GD.

Lộ trình

$ exiftool -comment="" nasa.png
2 minh họa một kịch bản thực tế hơn một chút - và khó khăn hơn cho kẻ tấn công. Trước khi lưu trữ các tệp do người dùng tải lên, ứng dụng sẽ sử dụng hàm PHP-GD
# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
73 để nén tất cả các hình ảnh được tải lên máy chủ web. Đây là một thao tác khá phổ biến. Để làm như vậy, hai dòng đã được thêm vào chức năng xử lý hình ảnh

  • src\Controller\HomeController. phphàm công khai secondPart

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
3

 

So với tình huống được mô tả trong phần đầu tiên củae bài viết, chúng tôi hiện có thêm một ràng buộc. Tệp đã tải lên vẫns là tệp PNG hợp lệ ; . e. nén persist through the image processing performed by PHP-GD [i.e. the compression của hàm ______173].

Mặc dù hai cách tiếp cận naive trước đó sẽ không tồn tại image compression, another more subtle method should allow us to successfully smuggle our PHP payload despite this particular image transformation.

 

[Phương pháp số 3] - PLTE chunk

Tệp PNG chứa hai loại khối. khối phụ trợ [không bắt buộc phải tạo thành PNG hợp lệ] và khối quan trọng [that are essential in a PNG file] – see the PNG specification for more details. Khi nén tệp PNG, PHP-GD [và có thể là các thư viện nén hình ảnh khác thư viện] sẽ xóa ancillary chunks to reduce the size of the output file. Đây là lý do tại sao các nhận xét mà chúng tôi đã chèn tải trọng PHP của mình vào phần đầu tiên did not survive the compression process.

Nhưng điều gì sẽ xảy ra nếu chúng tôi có thể đưa tải trọng của mình vào một đoạn quan trọng của tệp PNG ? . an image. Một ứng cử viên hoàn hảo để thực hiện một phép tiêm như vậy là đoạn PLTE . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. . e. một danh sách màu. , a critical chunk that contains the « palette » of a PNG image, i.e. a list of color. Theo đặc tả PNG.

 

« Tđoạn PLTE này chứa từ 1 đến 256 mục bảng màu, mỗi mục là một chuỗi ba byte có dạng.

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
5

Số lượng mục nhập được xác định từ độ dài đoạn. Độ dài đoạn không chia hết cho 3 là lỗi. »

 

Sử dụng đoạn PLTE, chúng tôi có khả năng có sẵn 256*3 byte để đưa tải trọng của chúng tôi vào một đoạn quan trọng như vậy, như vậy là quá đủ. Hạn chế duy nhất là độ dài của tải trọng phải chia hết cho 3

Đặt tất cả những thứ này lại với nhau, đây là một tập lệnh PHP sẽ tạo một hình ảnh PNG độc hại với tải trọng PHP được chỉ định làm đối số đầu tiên và được chèn vào đoạn PLTE của nó

 

  • tải trọng/trình tạo/tạo_plte_png. php

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
6

 

Hãy thực thi kịch bản

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
7

Giờ đây, chúng tôi có thể tải hình ảnh PNG kết quả lên thông qua định tuyến

$ exiftool -comment="" nasa.png
2 . Việc truy cập hình ảnh đã tải lên – và được nén – từ máy chủ web sẽ thực thi tải trọng PHP của chúng tôi, do đó thể hiện tính bền vững của nó thông qua quá trình chuyển đổi hình ảnh được thực hiện bởi PHP-GD.

 

Tải trọng PHP được thực thi thông qua đoạn PLTE

 

 

3. Đánh bại việc thay đổi kích thước hình ảnh PHP-GD

Một thao tác tiêu chuẩn khác được ứng dụng web thực hiện khi xử lý hình ảnh là thay đổi kích thước để chuẩn hóa định dạng của chúng. Để đạt được điều này, ứng dụng có thể sử dụng các hàm PHP-GD chẳng hạn

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
76 hoặc
# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
77
.

The

$ exiftool -comment="" nasa.png
3 minh họa một tình huống trong đó ứng dụng đích nén và thay đổi kích thước PNG đầu vào . ing them.

  • src\Controller\HomeController. phphàm công khai Phần ba

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
2

 

Cấu hình như vậy thêm một lớp phức tạp khác cho kẻ tấn côngs. Khi thay đổi kích thước hình ảnh, ngay cả nội dung của các đoạn quan trọng như đoạn PLTE cũng sẽ bị hủy – và tải trọng của chúng tôi cùng với nó. Các hàm này thực sự tạo ra một hình ảnh hoàn toàn mới chỉ bằng cách sử dụng dữ liệu pixel . Quan trọng hoặc phụ trợ, dữ liệu chứa trong các phần của tệp gốc from the original file. Critical or ancillary, the data contained in the chunks of the original file [bên cạnh những phần xác định dữ liệu pixel] có thể sẽ bị bỏ qua.

Trong những điều kiện này, chỉ còn một vị trí duy nhất mà chúng tôi có thể ẩn tải trọng PHP của mình để làm cho tải trọng đó tồn tại trong quá trình thay đổi kích thước. dữ liệu pixel data của PNG được cung cấp file.

 

[Phương pháp số 4] Đoạn mã IDAT

Một phương pháp khá phức tạp – nhưng hiệu quả để đưa tải trọng PHP liên tụcs vào các tệp PNG là mã hóa nó trong PNG IDAT chunks. Các đoạn này chứa dữ liệu hình ảnh thực tế, tôi. e. pixel của PNG, được biểu thị bằng 3 byte cho các kênh màu RGB. Khi tạo khối IDAT, các pixel dài 3 byte được đặt trước .

To tạo ra một đoạn mã IDAT chứa mã PHP hợp lệ, do đó, người dùng sẽ tìm thấy sự kết hợp chính xác của các pixel thô, sau khi được xử lý bởi bộ lọc dòng PNG và thuật toán DEFLATE, sẽ xuất ra . Sự kết hợp như vậy sẽ khác nhau tùy thuộc vào kích thước mà hình ảnh PNG được thay đổi kích thước.

Mặc dù không tầm thường nhưng điều này có thể đạt được và đã được ghi lại rất nhiều tại đây - here for french-speaking readers. Chúng tôi sẽ tham khảo hai bài viết này để biết thêm chi tiết kỹ thuật; . the following script can be used in order to produce a 110x110 PNG image that, once resized to 55x55 [just like in our example for the

$ exiftool -comment="" nasa.png
3 route], will contain the PHP payload
# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
90
- a short, but efficient PHP webshell.

  • tải trọng/trình tạo/generate_idat_png. php

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
0

 

Bây giờ chúng tôi có thể sử dụng tập lệnh này để tạo hình ảnh PNG độc hại

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
1

Hãy tải tệp lên thông qua tuyến đường

$ exiftool -comment="" nasa.png
3 và thử kích hoạt webshell có trong hình thu nhỏ thu được. Yêu cầu HTTP sau sẽ dẫn đến việc thực thi lệnh
# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
92

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
2

 

Tải trọng PHP được thực thi thông qua IDAT chunk

As chúng ta có thể thấy trong ảnh chụp màn hình ở trên, lệnh ____192 được thực thi. Điều này có nghĩa là tải trọng PHP của chúng tôi, ẩn trong đoạn mã IDAT của hình ảnh PNG, được duy trì thông qua các phép biến đổi được thực hiện trên hình ảnh bởi PHP-GD when it produced the thumbnail.

Phương pháp buôn lậu khối IDAT hiệu quả như vậy, cần lưu ý rằng tìm đúng . Đầu ra được nén sẽ tạo ra một chuỗi có thể đọc được và bắt đầu ở ranh giới byte, điều này không phải lúc nào cũng đúng. payload able to defeat the PNG line filters and the DEFLATE algorithm is a tricky process. The compressed output should produce a readable string and start at a byte boundary, which isn’t always the case. Hơn nữa, sự kết hợp phù hợp của pixel thô để sử dụng sẽ liên tục thay đổi tùy thuộc vào thứ nguyên của thay đổi kích thước performed of the target application.

 

 

4. Đánh bại việc thay đổi kích thước hình ảnh Imagick

Hãy xem xét một kịch bản cuối cùng. Cho đến nay, chúng tôi chỉ đề cập đến xử lý hình ảnh được thực hiện bởi PHP-GD. Mặc dù đúng là thư viện này thường được sử dụng để xử lý ảnh trong PHP, nhưng các thư viện xử lý ảnh phổ biến khác thường được các ứng dụng web triển khai. Mỗi thư viện xử lý xử lý hình ảnh, nén và thay đổi kích thước theo một cách hơi khác, điều này mở ra những khả năng mới để chuyển lậu tải trọng PHP liên tục trong tệp PNG

Một trong những thư viện xử lý ảnh phổ biến nhất bên cạnh PHP-GD là Imagick, triển khai PHP của ImageMagick. Lộ trình

$ exiftool -comment="" nasa.png
4 minh họa một ứng dụng sử dụng nó để thay đổi kích thước tệp do người dùng tải lên bằng hàm
# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
95
.

  • src\Controller\HomeController. phphàm công khai thứ tưPhần

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
3

 

Khi hình ảnh được thay đổi kích thước bằng Imagick [thông qua ______195 hoặc các chức năng tương tự như

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
97], the constraints initially seem to be the same as for the PHP-GD library: a payload directly inserted in the file, in the comment of a PNG, or in its PLTE chunk will systematically be destroyed by the image transformations.

Tuy nhiên, có một tính đặc hiệu trong quá trình xử lý hình ảnh Imagick sẽ cho phép chúng tôi sử dụng một phương pháp thuận tiện hơn nhiều so với việc tiêm dữ liệu IDAT phức tạp

 

[Phương pháp số 5] đoạn văn bản

Theo thông số kỹ thuật PNG

« Văn bản […] văn bản [. ] khối được sử dụng để truyền tải thông tin văn bản liên quan đến hình ảnh [. ]. Mỗi đoạn văn bản chứa đầu tiênd một từ khóa xác định loại thông tin được đại diện bởi chuỗi văn bản. Các từ khóa sau được xác định trước và nên được sử dụng khi thích hợp.

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
4

Các từ khóa khác có thể được phát minh cho các mục đích khác »

 

Như chúng ta có thể thấy, các nhận xét PNG mà chúng ta đã sử dụng cho [Phương pháp số 1] không gì khác hơn là một loại đoạn văn bản đặc biệt được xác định trước

Điều đặc biệt thú vị là khi Imagick thay đổi kích thước một hình ảnh, nó thực sự sẽ thực hiện một số hành động trên các khối văn bản.

  • Xóa các đoạn văn bản được gắn thẻ là 'Nhận xét' .

  • Ghi đè giá trị của các đoạn văn bản sau [hoặc xác định chúng nếu chúng không tồn tại]. ______198 .

  • Giữ giá trị ban đầu của bất kỳ đoạn văn bản nào khác [bao gồm những đoạn văn bản không có định nghĩa trướcd keyword].

Từ đó, chúng ta có thể chỉ cần đặt tải trọng PHP của mình vào bất kỳ đoạn văn bản nào không thuộc loại 'Nhận xét' và không bị Imagick ghi đè. Bạn sẽ tìm thấy bên dưới một tập lệnh đơn giản sẽ mất a . . . . . . . . . . . . . . . . . . . . . . . . . PNG image as input, insert an arbitrary PHP payload into a tEXt chunk tagged ‘Synacktiv’, and put the resulting PNG into an output file:

  • tải trọng/trình tạo/tạo_tEXt_png. php

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
5

 

Hãy chạy tập lệnh

# Create the 'suit' object and link it to the Symfony form
$suit = new Suit[];
$form = $this->createForm[SuitType::class, $suit];
$form->handleRequest[$request];

# The form is submitted and valid if the user defined a title, a description,
# and uploaded a file with the PNG MIME type 
if [$form->isSubmitted[] && $form->isValid[]] {
            
    # Get the file uploaded through the form
    $suitFile = $form->get['suit']->getData[];

    # Build a unique filename from original filename
    $originalFilename = $suitFile->getClientOriginalName[];
    $newFilename = uniqid[].'_'.$originalFilename;

    # Store the uploaded file with the unique filename on the webservers in the 
    # thumbnails directory, which is simply {web_root}/suits_thumbnails/
    try {
         $suitFile->move[
             $this->getParameter['thumbnails_directory'],
             $newFilename
        ];
        $suit->setSuitFilename[$newFilename];
     } catch [FileException $e] {
          return new Response["File exception"];
     }

     # Store the 'suit' object in the database to persist it
     $entityManager->persist[$suit];
     $entityManager->flush[];
     return $this->redirectToRoute['app_home_homepage'];
}
6

Bây giờ chúng tôi có thể tải lên kết quả nasa. php sử dụng định tuyến

$ exiftool -comment="" nasa.png
4 của ứng dụng. Khi chúng tôi yêu cầu hình ảnh đã thay đổi kích thước, chúng tôi có thể thấy rằng tải trọng của chúng tôi đã thực sự được thực thi, chứng minh tính bền vững của < . payload through the resizing process of Imagick:

 

Tải trọng PHP được thực thi thông qua đoạn văn bản

 

 

Sự kết luận

Trước khi kết thúc nghiên cứu này, đây là bảng tóm tắt các kỹ thuật và kịch bản khác nhau mà chúng tôi đã đề cập

 

 Không xử lý Nén PHP-GD Thay đổi kích thước PHP-GD Thay đổi kích thước ảo thuật Thay đổi kích thước nhận xét PNG                                                     ❌Raw insertion                                                     ❌PLTE chunk                                                     ❌IDAT chunk                                                     ✅tEXt chunk                                                     ✅

 

Các cấu hình khác nhau được mô tả trong bài viết này cho phép chúng tôi cung cấp một bức tranh chính xác [không có ý định chơi chữ] về các kỹ thuật buôn lậu PHP khác nhau theo ý của kẻ tấn công. Các kỹ thuật này có thể được sử dụng khi có thể buộc máy chủ giải thích tệp hình ảnh dưới dạng PHP. Loại tình huống này có thể xảy ra vì nhiều lý do [e. g. kiểm tra tiện ích mở rộng yếu hoặc lỗ hổng Bao gồm tệp cục bộ] và thường xuyên hơn người ta có thể mong đợi. Trong trường hợp này, sẽ rất nguy hiểm nếu cho rằng việc xử lý và chuyển đổi hình ảnh có thể bảo vệ ứng dụng khỏi việc thực thi các tải trọng PHP tùy ý

Chức năng imagepng trong PHP là gì?

imagepng — Xuất hình ảnh PNG sang trình duyệt hoặc tệp .

Imagecreatefrompng là gì?

imagecreatefrompng[] trả về mã định danh hình ảnh đại diện cho hình ảnh thu được từ tên tệp đã cho . Mẹo. Một URL có thể được sử dụng làm tên tệp với chức năng này nếu trình bao bọc fopen đã được bật. Xem fopen[] để biết thêm chi tiết về cách chỉ định tên tệp.

Làm cách nào để biết hình ảnh là PNG hay JPG trong PHP?

Hãy thử chức năng hình ảnh exif_imagetype . Lưu câu trả lời này.

Loại chức năng nào được hiển thị hình ảnh PNG?

Hàm imagepng[] là một hàm có sẵn trong PHP dùng để hiển thị hình ảnh lên trình duyệt hoặc tệp. Công dụng chính của chức năng này là để xem một hình ảnh trong trình duyệt, chuyển đổi bất kỳ loại hình ảnh nào khác thành PNG và áp dụng các bộ lọc cho hình ảnh.

Chủ Đề