PHP sqlite_single_query()和sqlite_array_query()函数远程代码执行漏洞

PHP是广泛使用的通用目的脚本语言,特别适合于Web开发,可嵌入到HTML中。
 
如果对PHP的sqlite_single_query()和sqlite_array_query()函数使用了空的SQL查询的话,函数可能会使用未初始化的内存,这可能导致执行任意代码。以下是ext/sqlite/sqlite.c中的有漏洞代码段:
 
/* {{{ proto array sqlite_single_query(resource db, string query [, bool
first_row_only [, bool decode_binary]])
Executes a query and returns either an array for one single column or the
value of the first row. */
 
PHP_FUNCTION(sqlite_single_query)
{
       ...
   struct php_sqlite_result *rres;
   ...
       rres = (struct php_sqlite_result *)emalloc(sizeof(*rres)); [1]
       sqlite_query(NULL, db, sql, sql_len, PHPSQLITE_NUM, 0, NULL, &rres, NULL
       TSRMLS_CC); [2]
   ...
       real_result_dtor(rres TSRMLS_CC); [3]
}
 
在[1]处所分配的资源rres没有在[2]处清零。如果查询为空,就可能在[3]传送给real_result_dtor内存。
 
static void real_result_dtor(struct php_sqlite_result *res TSRMLS_DC)
{
       int i, j, base;
 
       if (res->vm) {
               sqlite_finalize(res->vm, NULL);
       }
 
       if (res->table) {
               if (!res->buffered && res->nrows) {
                       res->nrows = 1; /* only one row is stored */
               }
               for (i = 0; i < res->nrows; i++) {
                       base = i * res->ncolumns;
                       for (j = 0; j < res->ncolumns; j++) {
                               if (res->table[base + j] != NULL) {
                                       efree(res->table[base + j]);
                               }
                       }
               }
               efree(res->table); [1]
       }
 
       if (res->col_names) {
               for (j = 0; j < res->ncolumns; j++) {
                       efree(res->col_names[j]);
               }
               efree(res->col_names); [2]
       }
 
   ...
 
       efree(res);
}
 
如果通过某种方式控制了传送给real_result_dtor的res,就可能触发双重释放。
 
 
 
解决方法
建议升级PHP产品至最新版本,请到厂商的主页下载:
 
http://www.php.net
posted @ 2019-05-20 10:22  mrhonest  阅读(232)  评论(0)    收藏  举报