Cyber Anakins Lightsaber - A Minishell-based backdoor
<?php
require_once("formular/_config.php");
$GLOBALS['opac_token'] = "";
function HttpRequest($url, $post=null, $headers=array())
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_TIMEOUT,8);
curl_setopt($ch, CURLOPT_HTTP200ALIASES, array(200, 201));
if ($post!==null)
{
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
}
if ($GLOBALS['opac_token']!="") array_push($headers, "Authorization: Bearer ".$GLOBALS['opac_token']);
if (count($headers) > 0) curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
function OpacAuth()
{
if ($GLOBALS['opac_token']!="") return $GLOBALS['opac_token'];
$file = "formular/data/token.txt";
$ftime = @filemtime($file);
if ($ftime!==false)
{
$pass = time() - $ftime;
if ($pass < OPAC_SESSION_DURATION)
{
$f = @fopen($file,"r");
if ($f)
{
$token = fread($f,10000);
fclose($f);
if ($token!="")
{
$GLOBALS['opac_token']=$token;
return $token;
}
}
}
}
$post ="grant_type=password";
$post.="&client_id=".URLEncode(OPAC_CLIENT_ID);
$post.="&client_secret=".URLEncode(OPAC_SECRET);
$post.="&username=".URLEncode(OPAC_USER_NAME);
$post.="&password=".URLEncode(OPAC_PASSWORD);
$post.="&scope=read&refresh_token=";
$url = OPAC_HOST . "/opacg/api/v1/oauth2/token";
$result = HttpRequest($url, $post, array("accept: application/json"));
if ($result === false)
{
die("ERROR: Ошибка подключения при авторизации в OPAC!");
}
if (preg_match("/\"access_token\":\"([^\"]*)\"/",$result, $g))
{
$token = $g[1];
$f = @fopen($file,"w");
if ($f)
{
fwrite($f, $token);
fclose($f);
}
$GLOBALS['opac_token']=$token;
return $token;
}
die("ERROR: Не найден параметр access_token при авторизации в OPAC!");
}
function OnAuthError()
{
$file = "formular/data/token.txt";
$f = @fopen($file,"w");
if ($f) fclose($f);
}
function OpacBookGetField($book, $fieldNumber)
{
reset($book['fields']);
foreach($book['fields'] as $field)
{
if ($field['number'] == $fieldNumber)
{
return $field['value'];
}
}
return "";
}
function GetUnimarc($field, $tag)
{
if (preg_match("/\\$".$tag."(.*?)\\\$/",$field, $g) ||
preg_match("/\\$".$tag."(.*)$/",$field, $g))
{
return $g[1];
}
return "";
}
function SetUnimarc($field, $tag, $value)
{
if (GetUnimarc($field, $tag)==$value) return;
$s = preg_replace("/\\$".$tag.".*?\\$/","\$$tag$value\$", $field);
if ($s==$field)
{
$s = preg_replace("/\\$".$tag.".*$/","\$$tag$value", $field);
if ($s==$field)
{
$s.="\$$tag$value";
}
}
return $s;
}
function OpacBookGetUnimarc($book, $fieldNumber, $tag)
{
return GetUnimarc(OpacBookGetField($book, $fieldNumber), $tag);
}
function OpacBookSetUnimarc($book, $fieldNumber, $tag, $value)
{
reset($book['fields']);
foreach($book['fields'] as &$field)
{
if ($field['number'] == $fieldNumber)
{
$field['value']=SetUnimarc($field['value'], $tag, $value);
break;
}
}
return $book;
}
function CombineOpacMultivolumeBooks($part, $common)
{
$commonName = OpacBookGetUnimarc($common, "200", "a");
$partName = OpacBookGetUnimarc($part, "200", "a");
if ($commonName!="")
{
if ($partName!="")
{
$partName = "$commonName. $partName";
}
else
$partName = $commonName;
$part = OpacBookSetUnimarc($part, "200", "a", $partName);
$partName = OpacBookGetUnimarc($part, "200", "a");
}
$commonAuthor = OpacBookGetUnimarc($common, "200", "f");
$partAuthor = OpacBookGetUnimarc($part, "200", "f");
if ($partAuthor=="" && $commonAuthor!="")
{
$part = OpacBookSetUnimarc($part, "200", "f", $commonAuthor);
}
$commonAge = OpacBookGetUnimarc($common, "333", "a");
$partAge = OpacBookGetUnimarc($part, "333", "a");
if ($partAge=="" && $commonAge!="")
{
$part = OpacBookSetUnimarc($part, "333", "a", $commonAge);
}
$commonDesc = OpacBookGetUnimarc($common, "330", "a");
$partDesc = OpacBookGetUnimarc($part, "330", "a");
if ($commonDesc!="")
{
if ($partDesc!="")
{
$partDesc = "$commonDesc. $partDesc";
}
else
$partDesc = $commonDesc;
$part = OpacBookSetUnimarc($part, "330", "a", $partDesc);
}
return $part;
}
function OpacParseBook($json, $canLoadCommon=true)
{
$book = array();
$book['id']=$json['id'];
$book['fields'] = array();
foreach($json['attributes']['UNIMARC'] as $line)
{
if (preg_match("/^(\d\d\d) ..(.*)$/",$line, $g))
{
array_push($book['fields'], array("number"=>$g[1], "value"=>$g[2]));
}
}
if ($canLoadCommon)
{
$line = OpacBookGetField($book, "909");
if (strpos($line,"MULTIVOLUME.COMMON")!==false)
$book['common']=true;
else
if (strpos($line,"MULTIVOLUME.PART")!==false)
{
$v = OpacBookGetUnimarc($book, "461", "1001");
if ($v!='')
{
$v = str_replace("\\\\","%255C", $v);
$common = OpacGetBook($v, false);
$book = CombineOpacMultivolumeBooks($book, $common);
}
}
}
return $book;
}
function OpacFindBooks($search, $position=0, $limit=100, $sort=null)
{
$search = preg_replace("/[\(\)]/","",$search);
OpacAuth();
$header = array("accept: application/vnd.api+json");
$url = OPAC_HOST . "/opacg/api/v1/databases/".OPAC_DB_ID."/records?filter[query]=";
$url.=urlencode($search);
$url.="&filter[presence]=INCLUDE&options[views]=UNIMARC";
if ($sort && $sort!="")
{
$url.="&sort=".URLEncode($sort);
}
$url.="&limit=$limit&position=$position";
$response = HttpRequest($url, null, $header);
if ($response === false)
{
OnAuthError();
die("ERROR: Ошибка связи с OPAC во время поиска книг!");
}
$result = json_decode($response, true);
if ($result === false || !isset($result['data']))
{
OnAuthError();
die("ERROR: $response");
}
$books = array();
foreach($result['data'] as $json)
{
$book = OpacParseBook($json);
if (!isset($book['common'])) array_push($books, $book);
}
return $books;
}
function OpacGetBook($id, $canLoadCommon=true)
{
OpacAuth();
$header = array("accept: application/vnd.api+json");
$id = urlencode($id);
$url = OPAC_HOST ."/opacg/api/v1/databases/".OPAC_DB_ID."/records/$id?options[views]=UNIMARC";
$response = HttpRequest($url, null, $header);
if ($response === false)
{
OnAuthError();
die("ERROR: Ошибка связи с OPAC во время запроса книги!");
}
$result = json_decode($response, true);
if ($result === false || !isset($result['links']))
{
OnAuthError();
die("ERROR: $response");
}
return OpacParseBook($result['data'], $canLoadCommon);
}
function GetReaderByTicket($ticket, $fio)
{
$query = urlencode("(barcode $ticket) AND (fio $fio)");
OpacAuth();
$header = array("accept: application/vnd.api+json");
$url = OPAC_HOST ."/opacg/api/v1/readers?filter[query]=$query&limit=1&position=0";
$response = HttpRequest($url, null, $header);
if ($response === false)
{
OnAuthError();
die("ERROR: Ошибка связи с OPAC!");
}
$result = json_decode($response, true);
if ($result === false || !isset($result['meta']) || $result['meta']['count']==0)
{
OnAuthError();
die("ERROR: Читатель не найден!");
}
//print("ERROR: ");
//print_r($result);
//exit(0);
$reader = array();
$reader['id']=$result['data'][0]['id'];
$reader['name']=$fio;
$reader['ticket']=$ticket;
$reader['dateOfFinish']=preg_replace("/^(\d\d\d\d)(\d\d)(\d\d)/","$3.$2.$1",$result['data'][0]['attributes']['dateOfFinish']);
return $reader;
}
function GetReaderBooks($readerId)
{
$readerId = urlencode($readerId);
OpacAuth();
$header = array("accept: application/vnd.api+json");
$url = OPAC_HOST ."/opacg/api/v1/readers/$readerId/checkouts";
$response = HttpRequest($url, null, $header);
if ($response === false)
{
OnAuthError();
die("ERROR: Ошибка связи с OPAC во время запроса книги!");
}
$result = json_decode($response, true);
if ($result === false || !isset($result['links']))
{
OnAuthError();
die("ERROR: $response");
}
$bookList = array();
foreach($result['data'] as $data)
{
//$bookID = str_replace("\\", "%255C",$data['attributes']['recordId']);
$bookId = $data['attributes']['recordId'];
$opTime = $data['attributes']['operationTime']; // 04.10.2021 12:56:00
$nextOpTime = $data['attributes']['nextOperationTime']; // 04.11.2021
$exemplar = $data['attributes']['itemCode'];
array_push($bookList, array("bookId"=>$bookId, "exemplar"=>$exemplar, "operationTime"=>$opTime, "nextOperationTime"=>$nextOpTime));
}
return $bookList;
}
//print OpacAuth();
/*
$books = OpacFindBooks("FT Сивков");
foreach($books as $book)
{
$g = GetBookNameAndAuthor($book);
$img = GetBookTitleFile($book);
print "<h1>".$g['name']."</h1>";
if ($img!="") print "<img src='".OPAC_HOST."$img'>";
print "<div>".$g['author']."</div>\n";
}
*/
//var_dump();
//print OpacFindBooks("FT Райский сад");
?>
May the force be with you, always.