-
Notifications
You must be signed in to change notification settings - Fork 109
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
Scanner crash when encountering certain kind of malware #72
Comments
Same here on another wordpress website : File responsible for the crash is here : I move it to the quarantine, and now the scan is OK. Again, triggering the scan on the quarantine does not crash the scanner ... |
Hi kdescoubes, The problem is in the file: vendor/marcocesarato/amwscan/src/Deobfuscator.php private function calc($expr)
{
if (is_array($expr)) {
$expr = $expr[0];
}
preg_match('~(min|max)?\(([^\)]+)\)~mi', $expr, $exprArr);
if (!empty($exprArr[1]) && ($exprArr[1] === 'min' || $exprArr[1] === 'max')) {
return $exprArr[1](explode(',', $exprArr[2]));
}
preg_match_all('~([\d\.]+)([\*\/\-\+])?~', $expr, $exprArr);
if (!empty($exprArr[1]) && !empty($exprArr[2])) {
if (in_array('*', $exprArr[2], true)) {
$pos = array_search('*', $exprArr[2], true);
$res = @$exprArr[1][$pos] * @$exprArr[1][$pos + 1];
$expr = str_replace(@$exprArr[1][$pos] . '*' . @$exprArr[1][$pos + 1], $res, $expr);
$expr = $this->calc($expr);
} elseif (in_array('/', $exprArr[2], true)) {
$pos = array_search('/', $exprArr[2], true);
$res = $exprArr[1][$pos] / $exprArr[1][$pos + 1];
$expr = str_replace($exprArr[1][$pos] . '/' . $exprArr[1][$pos + 1], $res, $expr);
$expr = $this->calc($expr);
} elseif (in_array('-', $exprArr[2], true)) {
$pos = array_search('-', $exprArr[2], true);
$res = $exprArr[1][$pos] - $exprArr[1][$pos + 1];
$expr = str_replace($exprArr[1][$pos] . '-' . $exprArr[1][$pos + 1], $res, $expr);
$expr = $this->calc($expr);
} elseif (in_array('+', $exprArr[2], true)) {
$pos = array_search('+', $exprArr[2], true);
$res = $exprArr[1][$pos] + $exprArr[1][$pos + 1];
$expr = str_replace($exprArr[1][$pos] . '+' . $exprArr[1][$pos + 1], $res, $expr);
$expr = $this->calc($expr);
} else {
return $expr;
}
}
return $expr; As you can see, this is a recursive function that - for some reason - has an erroneous stop condition for the file you indicated and goes into very, very deep levels of recursion (in my case, about ~281000 - until the memory on the stack is exhausted). I haven't had time to disarm this function and analyze the stop condition, but it seems that a simple and sufficient workaround is to add an additional guard in the form: if($level>100000) return ""; This will interrupt further nesting if it goes too far :) So, all the correct function code will therefore look as follows: private function calc($expr, $level = 0)
{
if($level>100000) return "";
if (is_array($expr)) {
$expr = $expr[0];
}
preg_match('~(min|max)?\(([^\)]+)\)~mi', $expr, $exprArr);
if (!empty($exprArr[1]) && ($exprArr[1] === 'min' || $exprArr[1] === 'max')) {
return $exprArr[1](explode(',', $exprArr[2]));
}
preg_match_all('~([\d\.]+)([\*\/\-\+])?~', $expr, $exprArr);
if (!empty($exprArr[1]) && !empty($exprArr[2])) {
if (in_array('*', $exprArr[2], true)) {
$pos = array_search('*', $exprArr[2], true);
$res = @$exprArr[1][$pos] * @$exprArr[1][$pos + 1];
$expr = str_replace(@$exprArr[1][$pos] . '*' . @$exprArr[1][$pos + 1], $res, $expr);
$expr = $this->calc($expr, $level+1);
} elseif (in_array('/', $exprArr[2], true)) {
$pos = array_search('/', $exprArr[2], true);
$res = $exprArr[1][$pos] / $exprArr[1][$pos + 1];
$expr = str_replace($exprArr[1][$pos] . '/' . $exprArr[1][$pos + 1], $res, $expr);
$expr = $this->calc($expr, $level+1);
} elseif (in_array('-', $exprArr[2], true)) {
$pos = array_search('-', $exprArr[2], true);
$res = $exprArr[1][$pos] - $exprArr[1][$pos + 1];
$expr = str_replace($exprArr[1][$pos] . '-' . $exprArr[1][$pos + 1], $res, $expr);
$expr = $this->calc($expr,$level+1);
} elseif (in_array('+', $exprArr[2], true)) {
$pos = array_search('+', $exprArr[2], true);
$res = $exprArr[1][$pos] + $exprArr[1][$pos + 1];
$expr = str_replace($exprArr[1][$pos] . '+' . $exprArr[1][$pos + 1], $res, $expr);
$expr = $this->calc($expr,$level+1);
} else {
return $expr;
}
}
return $expr;
} This is completely sufficient (at least for my needs). I sincerely greet you and warm hugs for the file that helped me to solve this problem, |
Hi, @Borcejn |
@AldoTapiaInnova Just run index.php from src |
I too have the same experience. Malware is present, yet the scanner fails. I had to use strace -e trace=file to discover the offending php scan file. |
I have the same problem. The scanner "takes off" when it encounters a file. |
@58legend my fix definitely helps (I checked it just now). If the scanner crashed, you did something wrong. |
@Borcejn Thank you for your reply. This is very important to me. I appreciate your help.
What am i doing wrong? |
@58legend oh no, you cannot edit .phar directly. It's like trying to edit a zip/tar archive in notepad :) Instead you need to download all files of this project and then edit mentioned script. After fix run awmscan/src/index.php (you can set "scanner" as an alias for this localization in your environment). |
I understand what you mean. Downloaded and edited Dist, after this build new phar file. |
@58legend in my case, the scan still crashes for reasons unknown to me (( I downloaded your version, but the flight did not stop |
Hi there,
I use your scanner on multiple websites, but some times, it crashes prematurely (like described in issue #46 for example).
So I tried to run the scanner on sub directory until I find THE one which makes the scanner crashed.
I found a malware (attached), I move it to quarantine, then ran the scanner again : it didn't crash !
What's really weird is that if I run the scanner on the quarantine, it doesn't crash ...
(the file was a dot php file of course, renamed it to txt to upload it)
2308ba68.txt
The text was updated successfully, but these errors were encountered: