Skip to content

Instantly share code, notes, and snippets.

@praswicaksono
Last active May 3, 2026 17:59
Show Gist options
  • Select an option

  • Save praswicaksono/dac438e1f501fae0917b to your computer and use it in GitHub Desktop.

Select an option

Save praswicaksono/dac438e1f501fae0917b to your computer and use it in GitHub Desktop.
AfterLogic Webmail Pro + Aurora Keygen
<?php
Class Keygen {
private $serial;
private function randChar($length = 8) {
$characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$string = '';
for ($p = 0; $p < $length; $p++) {
$string .= $characters[mt_rand(0, strlen($characters)-1)];
}
return $string;
}
public function getHashKey($version)
{
$return = base64_decode('NEpVVjNIU1dJVDU1R1I2UjJGUVhaQkxaRVA3NzFETllDTThNQUs5OQ==');
if (2 === $version) { // Webmail Pro
$return = base64_decode('MkZRWDNIU1c0SlVWSVQ1NUdSNlJBSzk5WkJMWkVQNzcxRE5ZQ004TQ==');
} else if (3 === $version) { // Aurora
$return = base64_decode('M0hTVzJGUVhaQkxaQ004TUFLOTlJVDU1RVA3NzFETllHUjZSNEpVVg==');
}
return $return;
}
public function divideByFour($version, $char)
{
$result = strpos($this->getHashKey($version), $char);
return (false !== $result) ? (int) floor($result / 4) : false;
}
public function generate($version = 2) {
if ($version == 2) {
$this->serial .= "WM700-";
} elseif ($version == 3) {
$this->serial .= "AU700-";
} else {
return "Error version not found";
}
$var = rand(0,9);
$var4 = $this->randChar(1);
while($this->divideByFour($version,$var4) % 2 == 0)
{
$var4 = $this->randChar(1);
}
$this->serial .= $this->randChar(27).$var4.'-'.$var;
$var2 = ($var * 7 + 7) % 10;
$this->serial .= $var2.rand(0,9).rand(0,9);
$var3 = $this->randChar(1);
while($this->divideByFour($version,$var3) != 0)
{
$var3 = $this->randChar(1);
}
$this->serial .= $var3.$this->randChar(4);
return $this->serial;
}
}
$obj = new Keygen();
// 2 for webmailpro and 3 for aurora
print_r($obj->generate(3));
@rapsys
Copy link
Copy Markdown

rapsys commented Nov 28, 2022

Maybe a replay attack can be done by replacing KI.php and license file with an old one from :
afterlogic/aurora-module-licensing@e30a52f#diff-a8b460e8fea5607a2b05effa9f6512e5271f1e26ca6ab7890c7eab58cfc1e54c

Or someone may develop a replacement from unobfuscated KI.php https://www.unphp.net/

Or create a new generator with a self-generated public/private key pair and replace modules/Licensing/classes/AU80.key

Wasted 2 hours on that, so better save all vectors

ps : If you like their product please send them some money if you are not poor like me :)

@rapsys
Copy link
Copy Markdown

rapsys commented Nov 28, 2022

If there is more modules to activate than System, Calendar, CoreMobileWebclient and MailMultiAccountsPlugin tell me.

@mtcoliveira
Copy link
Copy Markdown

Edit file modules/Licensing/Module.php

In protected function getKeyInfo(), after $this->keyInfo = $oKI->GKI($sKey); add var_export($this->keyInfo); exit;

Add a trial key to data/settings/config.json

Add $this->keyInfo = [...]; in place of your var_export & exit with fixed content.

Enjoy ;)

ps : I wouldn't have bothered to post that if afterlogic had allowed a single or two user with full features by default

I think this is not working anymore in 9.7.1

@praswicaksono
Copy link
Copy Markdown
Author

Maybe a replay attack can be done by replacing KI.php and license file with an old one from : afterlogic/aurora-module-licensing@e30a52f#diff-a8b460e8fea5607a2b05effa9f6512e5271f1e26ca6ab7890c7eab58cfc1e54c

Or someone may develop a replacement from unobfuscated KI.php https://www.unphp.net/

Or create a new generator with a self-generated public/private key pair and replace modules/Licensing/classes/AU80.key

Wasted 2 hours on that, so better save all vectors

ps : If you like their product please send them some money if you are not poor like me :)

Unobfuscate is really just rename variable using hex editor, format the code and debug using xdebug. you just return correct array from KI.php

@Briesmi
Copy link
Copy Markdown

Briesmi commented May 3, 2026

Edit file modules/Licensing/Module.php
In protected function getKeyInfo(), after $this->keyInfo = $oKI->GKI($sKey); add var_export($this->keyInfo); exit;
Add a trial key to data/settings/config.json
Add $this->keyInfo = [...]; in place of your var_export & exit with fixed content.
Enjoy ;)
ps : I wouldn't have bothered to post that if afterlogic had allowed a single or two user with full features by default

I think this is not working anymore in 9.7.1

This still works fine!

But it's not necessary. Use the trick from @yoda1490, but choose a higher value fir expire, e.g. 'ExpiresIn' => 9999.
Cause: The trial key includes a timestamp. If you choose 200 (days) for expire, you still got unlimited time after 200 days, but not unlimited users anymore.

To stay in unlimited users, you can add e.g. 10 years ( 87660 hours) to the public function GetUserNumberLimitAsString() part.
In case 10 (trial):
change $iTime to $iTime = time() + (87660*60*60);
You can to that in public function GetLicenseInfo($Module = 'System') , too.
After that, the license stays in trial but expire after 3683 days. And u'll have that days for unlimited users, too.

Tested with version 9.8.x

Njoy!

Github

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment