Build an accurate method for configurable PHP Exploitation programs

Source: Internet
Author: User
This article illustrates several methods for creating configurable PHP Exploitation programs. This article also discusses the use of fantasy configuration points in the program, and seeks a balance between the use of the program Overfire configuration and overfire closed. This article illustrates several methods to create configurable PHP exploits. This article also discusses the configuration points of fantasy in the application, and seeks a balance between the configuration of Overfire and overfire sealing by using the program.

If you want to allow others or companies to apply your PHP Exploitation program, make sure the program is configurable. At least, you need to answer the question that the user sets the database logon and password in a safe way, so that the materials in the account are not openly disclosed.

This article shows several tips for storing configuration settings and compiling these settings. In addition, what elements need to be configured and how to avoid the problem of excessive configuration or insufficient configuration is provided to the leaders.

Apply the INI file for configuration

PHP has built-in support for configuration files. This is implemented through the initialization file (ini) mechanism like the php. INI file, which defines constants such as database connection timeout or session storage. If you want to, you can customize the configuration in this php. ini file. To clarify, I add the following lines of code to the php. ini file.

Myapptempdir = foo

Then, I wrote a small PHP script to read this configuration item, as shown in listing 1.

Listing 1. ini1.php

<? Php
Function get_template_directory ()
{
$ V = get_cmd_var ('myapptempdir ');
Return ($ v = null )? 'Tempdir': $ v;
}

Echo (get_template_directory (). '\ n ');
?>
When you run this code in the command line, the following results are obtained:

% Php ini1.php
Foo
%
Great. But why can't I use the scale INI function to obtain the value of the myapptempdir configuration item? I 've learned that in most cases, custom configuration items cannot be obtained using these methods. However, the application of the get_cfg_var function can be visited.

To make this method simpler, the visit to the variable is encapsulated in the second function. the Function application configures the key name and a default value as the parameter, as shown below.

Listing 2. ini2.php

Function get_ini_value ($ n, $ dv)
{
$ C = get_cfg_var ($ n );
Return ($ c = null )? $ Dv: $ c;
}

Function get_template_directory ()
{
Return get_ini_value ('myapptempdir', 'tempdir ');
}
This is a good generalization of how to visit the INI file. Therefore, if you want to apply a different mechanism or store this INI file to another position, you don't have to worry about changing a large number of functions.

I do not recommend using the INI file as the configuration of the exploitation program. There are two reasons for this. First, though this is easier to read INI files, it is almost impossible to write INI files securely. Therefore, this is only suitable for read-only configuration items. Second, the php. ini file is shared among all the exploitation programs on the server, so I don't think the configuration items specific to the exploitation program should be written in this file.

What do I know about INI files? The most important thing is how to reset the include path to Add configuration items, as shown below.

Listing 3. ini3.php

<? Php


Echo (ini_get ('include _ path'). '\ n ');
Ini_set ('include _ path ',
Ini_get ('include _ path'). ':./mylib ');
Echo (ini_get ('include _ path'). '\ n ');
?>
In this example, I add my local mylib directory to the include path, so I can add the require PHP file from this directory without adding the path to the require statement.

Configuration in PHP

A replacement measure for storing configuration entries in the INI file is usually to apply a simple PHP script to keep data. The following is an example.

Listing 4. config. php

<? Php
# Specify the location of the temporary directory
#
$ TEMPLATE_DIRECTORY = 'tempdir ';
?>
The code for applying this constant is as follows.

Listing 5. php. php

<? Php
Require_once 'config. php ';

Function get_template_directory ()
{
Global $ TEMPLATE_DIRECTORY;
Return $ TEMPLATE_DIRECTORY;
}

Echo (get_template_directory (). '\ n ');
?>
The code first contains the configuration file (config. php), and then you can directly apply these constants.

The application of this technique has many advantages. First, if some people only browse the config. php file, the page is blank. Therefore, you can put config. php in the same file and use it as the root of the Web application. Second, it can be compiled in any editor, and in some compilers, it even has the syntax coloring and syntax check functions.

The problem with this technique is that it is a read-only technique like an INI file. Extracting data from this file is easy, but it is difficult to adjust the data in this PHP file. in some cases, it is even impossible.

The following interchange method shows how to write a configuration system that is essentially readable and writable.


Text files

The previous two examples are suitable for read-only configuration items, but what about read and write configuration parameters? First, check the text configuration file in listing 6.

Listing 6. config.txt

# My application's configuration file
Title = My App
TemplateDirectory = tempdir
This is the same file structure as the INI file, but I have compiled a help tool myself. To this end, I created my own Configuration class, as shown below.

Listing 7. text1.php

<? Php
Class Configuration
{
Private $ configFile = 'config.txt ';
Private $ items = array ();
Function _ construct () {$ this-> parse ();}
Function _ get ($ id) {return $ this-> items [$ id];}
Function parse ()
{
$ Fh = fopen ($ this-> configFile, 'r ');
While ($ l = fgets ($ fh ))
{
If (preg_match ('/^ #/', $ l) = false)
{
Preg_match ('/^ (.*?) = (.*?) $/', $ L, $ found );
$ This-> items [$ found [1] = $ found [2];
}
}
Fclose ($ fh );
}
}

$ C = new Configuration ();

Echo ($ c-> TemplateDirectory. '\ n ');
?>
This code first creates a Configuration object. The structure function then reads config.txt and uses the parsed file content to set the local variable $ items




The script then looks for TemplateDirectory, which is not directly defined in the object. Therefore, the app sets the $ id of 'templatedirectory' to call the magic _ get method, __get method returns the value in the $ items array for this key.

This _ get method is specific to the PHP V5 environment, so this script must be run under PHP V5. In fact, all the scripts in this article need to be run in PHP V5.

When running this script on the command line, you can see the following results:

% Php text1.php
Tempdir
%
Everything is in the hunch that the object reads the config.txt file and then gets the correct value for the TemplateDirectory configuration item.

But how should I set a configuration value? Create a new method and some new test code in this class to get this effect, as shown below.

Listing 8. text2.php

<? Php
Class Configuration
{
...

Function _ get ($ id) {return $ this-> items [$ id];}

Function _ set ($ id, $ v) {$ this-> items [$ id] = $ v ;}
Function parse (){...}
}
$ C = new Configuration ();
Echo ($ c-> TemplateDirectory. '\ n ');
$ C-> TemplateDirectory = 'foobar ';
Echo ($ c-> TemplateDirectory. '\ n ');
?>
Now we have a _ set function, which is the "cousin" of The _ get function ". This function does not get a value for a member variable. it is called only when a member variable is set. Set the value of the test code at the bottom and print the new value.

The following is the result of running this code in the command line:

% Php text2.php
Tempdir
Foobar
%
Great! But how can we fix this fix by storing it in a file? Therefore, you need to write a file and read it. The new function used to write files is as follows.

Listing 9. text3.php

<? Php
Class Configuration
{
...

Function save ()
{
$ Nf = '';
$ Fh = fopen ($ this-> configFile, 'r ');
While ($ l = fgets ($ fh ))
{
If (preg_match ('/^ #/', $ l) = false)
{
Preg_match ('/^ (.*?) = (.*?) $/', $ L, $ found );
$ Nf. = $ found [1]. '='. $ this-> items [$ found [1]. '\ n ';
}
Else
{
$ Nf. = $ l;
}
}
Fclose ($ fh );
Copy ($ this-> configFile, $ this-> configFile. '. bak ');
$ Fh = fopen ($ this-> configFile, 'w ');
Fwrite ($ fh, $ nf );
Fclose ($ fh );
}
}

$ C = new Configuration ();
Echo ($ c-> TemplateDirectory. '\ n ');
$ C-> TemplateDirectory = 'foobar ';
Echo ($ c-> TemplateDirectory. '\ n ');
$ C-> save ();
?>
The new save function controls config.txt wonderfully. I did not just use the updated configuration item to override the file (this will remove the comment), but read the file and mechanically override the content in the $ items array. In this way, the comments in the file are retained.

Run the script on the command line and output the content in the text configuration file. the following output is displayed.


Listing 10. reserved function output

% Php text3.php
Tempdir
Foobar
% Cat config.txt
# My application's configuration file
Title = My App
TemplateDirectory = foobar
%
The original config.txt file is now updated by the new value.


XML configuration file

Although text files are easy to browse and compile, they are not as popular as XML files. In addition, XML has many practical compilers, which can understand the mark, special symbol escape, and so on. So what is the XML version of the configuration file? Listing 11 shows the XML format configuration file.

Listing 11. config. xml

<? Xml version = '1. 0'?>
<Config>
<Title> My App </Title>
<TemplateDirectory> tempdir </TemplateDirectory>
</Config>
Listing 12 shows the updated Configuration class of the application XML to load Configuration settings.

Listing 12. xml1.php

<? Php
Class Configuration
{
Private $ configFile = 'config. XML ';
Private $ items = array ();
Function _ construct () {$ this-> parse ();}
Function _ get ($ id) {return $ this-> items [$ id];}
Function parse ()
{
$ Doc = new DOMDocument ();
$ Doc-> load ($ this-> configFile );
$ Cn = $ doc-> getElementsByTagName ('config ');
$ Nodes = $ cn-> item (0)-> getElementsByTagName ('*');
Foreach ($ nodes as $ node)
$ This-> items [$ node-> nodeName] = $ node-> nodeValue;
}
}

$ C = new Configuration ();
Echo ($ c-> TemplateDirectory. '\ n ');
?>
It seems that XML has another benefit: code is simpler and easier than text version code. In order to retain this XML, another version of the save function is required to retain the results as XML instead of text.

Listing 13. xml2.php

...
Function save ()
{
$ Doc = new DOMDocument ();
$ Doc-> formatOutput = true;

$ R = $ doc-> createElement ('config ');
$ Doc-> appendChild ($ r );

Foreach ($ this-> items as $ k => $ v)
{
$ Kn = $ doc-> createElement ($ k );
$ Kn-> appendChild ($ doc-> createTextNode ($ v ));
$ R-> appendChild ($ kn );
}

Copy ($ this-> configFile, $ this-> configFile. '. bak ');

$ Doc-> save ($ this-> configFile );
}
...
This code creates a new XML Document Object Model (DOM) and retains all the data in the $ items array to this Model. After completing these steps, apply the save method to keep XML as a file.


Application Database

The last change method is to apply the value of the configuration element to a database. First, we need to use a simple mode to store configuration data. The following is a simple mode.

Listing 14. schema. SQL

Drop table if exists settings;
Create table settings (
Id mediumint not null AUTO_INCREMENT,
Name TEXT,
Value TEXT,
Primary key (id)
);
This request carries out some adjustments based on utilization program requirements. For example, if you want to store configuration elements according to each user, you need to add the user ID as an additional column.




To read and write data, I wrote the updated Configuration class as shown in Figure 15.

Listing 15. db1.php

<? Php
Require_once ('Db. php ');
$ Dsn = 'MySQL: // root: password @ localhost/config ';
$ Db = & DB: Connect ($ dsn, array ());
If (PEAR: isError ($ db) {die ($ db-> getMessage ());}

Class Configuration
{
Private $ configFile = 'config. XML ';
Private $ items = array ();
Function _ construct () {$ this-> parse ();}
Function _ get ($ id) {return $ this-> items [$ id];}
Function _ set ($ id, $ v)
{
Global $ db;
$ This-> items [$ id] = $ v;
$ Sth1 = $ db-> prepare ('delete FROM settings WHERE name =? ');
$ Db-> execute ($ sth1, $ id );
If (PEAR: isError ($ db) {die ($ db-> getMessage ());}
$ Sth2 = $ db-> prepare ('Insert INTO settings (id, name, value) VALUES (0 ,?, ? )');
$ Db-> execute ($ sth2, array ($ id, $ v ));
If (PEAR: isError ($ db) {die ($ db-> getMessage ());}
}

Function parse ()
{
Global $ db;
$ Doc = new DOMDocument ();
$ Doc-> load ($ this-> configFile );
$ Cn = $ doc-> getElementsByTagName ('config ');
$ Nodes = $ cn-> item (0)-> getElementsByTagName ('*');
Foreach ($ nodes as $ node)
$ This-> items [$ node-> nodeName] = $ node-> nodeValue;
$ Res = $ db-> query ('select name, value FROM settings ');
If (PEAR: isError ($ db) {die ($ db-> getMessage ());}
While ($ res-> fetchInto ($ row )){
$ This-> items [$ row [0] = $ row [1];
}
}
}

$ C = new Configuration ();
Echo ($ c-> TemplateDirectory. '\ n ');
$ C-> TemplateDirectory = 'new Foo ';
Echo ($ c-> TemplateDirectory. '\ n ');
?>
This is actually a mix of text/database solutions. Observe the parse method carefully. This class first reads the text file to get the initial value, then reads the database, and then updates the key to the latest value. After setting a value, the key is removed from the database and a new record with updated values is added.

It is interesting to observe how the Configuration class works through multiple versions in this article. it can read data from text files, XML files, and databases, and keep the same interface. I encourage you to use APIs with the same stability during development. For the client of the object, it is not clear how the task runs. What is important is the contract between the object and the client.

What is Configuration and how to configure

Finding an appropriate intermediate point between too many configuration options and insufficient configuration is difficult. It can be determined that any database configuration (for example, database name, database user and password) should be configurable. In addition, I have some basic recommended configuration items.

In advanced settings, each feature should have an independent enable/disable option. Agree or disable these options based on their importance to the exploitation program. For example, in a Web forum exploitation program, the latency feature is enabled by default. However, email notification is disabled by default, as this seems to require customization.


All user interface (UI) options should be set to a single position. The structure of the interface (for example, menu position, additional menu items, URLs linked to specific elements of the interface, application logo, and so on) should all be set to a single position. I strongly recommend that you do not specify font, color, or style entries as configuration items. These settings should be made through Cascading Style Sheet (CSS), and the configuration system should specify which CSS file to apply. CSS is an effective and mobile method for setting fonts, styles, colors, and so on. There are a lot of excellent CSS tools, and your Exploitation program should make good use of CSS, rather than trying to set the scale on its own.

In each feature, I recommend setting 3 to 10 configuration options. These configuration options should be named in a meaningful way. If the configuration option can be set through the UI, the option names in the text file, XML file, and database should be directly related to the title of the interface element. In addition, all these options should have clear default values.

In general, the following options should be configurable: email address, what CSS applies, the status of the system resources referenced from the file, and the file name of the graphic element.

For graphic elements, you may want to create an independent configuration file type named skin, which contains settings for the configuration file, contains the status of CSS files, the status of graphics, and these types of things. Then, you can select multiple skin files. This makes the wide range of appearance and perception of the application more simple. This also provides an opportunity for users to switch their skin between different product installations. This article does not cover these skin files, but the basic knowledge you have learned here will make the support for skin files more simple.

Conclusion

Configurability is a crucial part for any PHP application, and the beginning should be the central part of the design. I hope this article will help you implement the configuration architecture and provide some guidance on what configuration options should be promised.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.