mirror of https://github.com/MISP/MISP
new: Support for BECH32 (P2WPKH) BTC address
parent
d0f9fa8ea0
commit
871ca92c48
|
@ -217,9 +217,7 @@ jobs:
|
|||
- name: Run PHP tests
|
||||
run: |
|
||||
./app/Vendor/bin/parallel-lint --exclude app/Lib/cakephp/ --exclude app/Vendor/ --exclude app/Lib/random_compat/ -e php,ctp app/
|
||||
./app/Vendor/bin/phpunit app/Test/ComplexTypeToolTest.php
|
||||
./app/Vendor/bin/phpunit app/Test/JSONConverterToolTest.php
|
||||
./app/Vendor/bin/phpunit app/Test/CidrToolTest.php
|
||||
./app/Vendor/bin/phpunit app/Test/
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
|
|
|
@ -274,8 +274,13 @@ class ComplexTypeTool
|
|||
|
||||
private function __checkForBTC($input)
|
||||
{
|
||||
if (preg_match("#^[13][a-km-zA-HJ-NP-Z1-9]{25,34}$#i", $input['raw'])) {
|
||||
return array('types' => array('btc'), 'categories' => array('Financial fraud'), 'to_ids' => true, 'default_type' => 'btc', 'value' => $input['raw']);
|
||||
if (preg_match("#^([13][a-km-zA-HJ-NP-Z1-9]{25,34})|(bc|tb)1([023456789acdefghjklmnpqrstuvwxyz]{11,71})$#i", $input['raw'])) {
|
||||
return [
|
||||
'types' => ['btc'],
|
||||
'to_ids' => true,
|
||||
'default_type' => 'btc',
|
||||
'value' => $input['raw'],
|
||||
];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -305,7 +310,7 @@ class ComplexTypeTool
|
|||
// handle prepared composite values with the filename|hash format
|
||||
if (strpos($input['raw'], '|')) {
|
||||
$compositeParts = explode('|', $input['raw']);
|
||||
if (count($compositeParts) == 2) {
|
||||
if (count($compositeParts) === 2) {
|
||||
if ($this->__resolveFilename($compositeParts[0])) {
|
||||
$hash = $this->__resolveHash($compositeParts[1]);
|
||||
if ($hash) {
|
||||
|
@ -372,7 +377,6 @@ class ComplexTypeTool
|
|||
if (preg_match("#^cve-[0-9]{4}-[0-9]{4,9}$#i", $input['raw'])) {
|
||||
return [
|
||||
'types' => ['vulnerability'],
|
||||
'categories' => ['External analysis'],
|
||||
'to_ids' => false,
|
||||
'default_type' => 'vulnerability',
|
||||
'value' => strtoupper($input['raw']), // 'CVE' must be uppercase
|
||||
|
@ -381,7 +385,7 @@ class ComplexTypeTool
|
|||
// Phone numbers - for automatic recognition, needs to start with + or include dashes
|
||||
if ($input['raw'][0] === '+' || strpos($input['raw'], '-')) {
|
||||
if (!preg_match('#^[0-9]{4}-[0-9]{2}-[0-9]{2}$#i', $input['raw']) && preg_match("#^(\+)?([0-9]{1,3}(\(0\))?)?[0-9\/\-]{5,}[0-9]$#i", $input['raw'])) {
|
||||
return array('types' => array('phone-number', 'prtn', 'whois-registrant-phone'), 'categories' => array('Other'), 'to_ids' => false, 'default_type' => 'phone-number', 'value' => $input['raw']);
|
||||
return array('types' => array('phone-number', 'prtn', 'whois-registrant-phone'), 'to_ids' => false, 'default_type' => 'phone-number', 'value' => $input['raw']);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
@ -471,7 +475,7 @@ class ComplexTypeTool
|
|||
$temp = explode('\\', $input['raw']);
|
||||
if (strpos(end($temp), '.') || preg_match('/^.:/i', $temp[0])) {
|
||||
if ($this->__resolveFilename(end($temp))) {
|
||||
return array('types' => array('filename'), 'categories' => array('Payload installation'), 'to_ids' => true, 'default_type' => 'filename', 'value' => $input['raw']);
|
||||
return array('types' => array('filename'), 'to_ids' => true, 'default_type' => 'filename', 'value' => $input['raw']);
|
||||
}
|
||||
} else if (!empty($temp[0])) {
|
||||
return array('types' => array('regkey'), 'to_ids' => false, 'default_type' => 'regkey', 'value' => $input['raw']);
|
||||
|
|
|
@ -89,6 +89,22 @@ class FinancialTool
|
|||
'XK' => '20'
|
||||
);
|
||||
|
||||
const BTC_BASE32_CONVERT_TABLE = [
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
15, -1, 10, 17, 21, 20, 26, 30, 7, 5, -1, -1, -1, -1, -1, -1,
|
||||
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
|
||||
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1,
|
||||
-1, 29, -1, 24, 13, 25, 9, 8, 23, -1, 18, 22, 31, 27, 19, -1,
|
||||
1, 0, 3, 16, 11, 28, 12, 14, 6, 4, 2, -1, -1, -1, -1, -1
|
||||
];
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param string $value
|
||||
* @return bool
|
||||
*/
|
||||
public function validateRouter($type, $value)
|
||||
{
|
||||
$validationRoutes = array(
|
||||
|
@ -99,8 +115,8 @@ class FinancialTool
|
|||
'btc' => 'BTC',
|
||||
'xmr' => 'XMR'
|
||||
);
|
||||
if (in_array($type, array_keys($validationRoutes))) {
|
||||
return $this->{'validate' . strtoupper($validationRoutes[$type])}($value);
|
||||
if (isset($validationRoutes[$type])) {
|
||||
return $this->{'validate' . $validationRoutes[$type]}($value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -129,7 +145,6 @@ class FinancialTool
|
|||
return (int)$mod;
|
||||
}
|
||||
|
||||
|
||||
// validating using method described on wikipedia @ https://en.wikipedia.org/wiki/International_Bank_Account_Number#Algorithms
|
||||
public function validateIBAN($iban)
|
||||
{
|
||||
|
@ -197,11 +212,20 @@ class FinancialTool
|
|||
return false;
|
||||
}
|
||||
|
||||
// based on the php implementation of the BTC address validation example from
|
||||
// http://rosettacode.org/wiki/Bitcoin/address_validation
|
||||
/**
|
||||
* Based on the php implementation of the BTC address validation example from
|
||||
* http://rosettacode.org/wiki/Bitcoin/address_validation
|
||||
* @param string $address
|
||||
* @return bool
|
||||
*/
|
||||
public function validateBTC($address)
|
||||
{
|
||||
if (strlen($address) < 26 || strlen($address) > 35) {
|
||||
if ($this->validateBtcBech32($address)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$strlen = strlen($address);
|
||||
if ($strlen < 26 || $strlen > 35) {
|
||||
return false;
|
||||
}
|
||||
$decoded = $this->__decodeBase58($address);
|
||||
|
@ -226,12 +250,48 @@ class FinancialTool
|
|||
return true;
|
||||
}
|
||||
|
||||
private function validateBtcBech32($address)
|
||||
{
|
||||
if (!preg_match('/^(bc|tb)1([023456789acdefghjklmnpqrstuvwxyz]{11,71})$/i', $address, $match)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$hrp = strtolower($match[1]);
|
||||
|
||||
$expand1 = [];
|
||||
$expand2 = [];
|
||||
for ($i = 0; $i < strlen($hrp); $i++) {
|
||||
$o = ord($hrp[$i]);
|
||||
$expand1[] = $o >> 5;
|
||||
$expand2[] = $o & 31;
|
||||
}
|
||||
$data = array_merge($expand1, [0], $expand2);
|
||||
|
||||
$chars = strtolower($match[2]);
|
||||
$chars = array_map('ord', str_split($chars));
|
||||
foreach ($chars as $char) {
|
||||
$data[] = ($char & 0x80) ? -1 : self::BTC_BASE32_CONVERT_TABLE[$char];
|
||||
}
|
||||
$generator = [0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3];
|
||||
$chk = 1;
|
||||
foreach ($data as $char) {
|
||||
$top = $chk >> 25;
|
||||
$chk = ($chk & 0x1ffffff) << 5 ^ $char;
|
||||
for ($j = 0; $j < 5; $j++) {
|
||||
$value = (($top >> $j) & 1) ? $generator[$j] : 0;
|
||||
$chk ^= $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $chk === 1;
|
||||
}
|
||||
|
||||
private function __decodeBase58($input)
|
||||
{
|
||||
$alphabet = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
||||
|
||||
$out = array_fill(0, 25, 0);
|
||||
for ($i=0;$i<strlen($input);$i++) {
|
||||
for ($i = 0; $i < strlen($input); $i++) {
|
||||
$p = strpos($alphabet, $input[$i]);
|
||||
if ($p === false) {
|
||||
return false;
|
||||
|
@ -239,7 +299,7 @@ class FinancialTool
|
|||
$c = $p;
|
||||
for ($j = 25; $j--;) {
|
||||
$c += (int)(58 * $out[$j]);
|
||||
$out[$j] = (int)($c % 256);
|
||||
$out[$j] = $c % 256;
|
||||
$c /= 256;
|
||||
$c = (int)$c;
|
||||
}
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
App::uses('ThreatLevel', 'Model');
|
||||
|
||||
/**
|
||||
* ThreatLevel Test Case
|
||||
*
|
||||
*/
|
||||
class ThreatLevelTest extends CakeTestCase {
|
||||
|
||||
/**
|
||||
* Fixtures
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $fixtures = array(
|
||||
'app.threat_level',
|
||||
'app.event',
|
||||
'app.user',
|
||||
'app.role',
|
||||
'app.post',
|
||||
'app.thread',
|
||||
'app.attribute',
|
||||
'app.shadow_attribute'
|
||||
);
|
||||
|
||||
/**
|
||||
* setUp method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->ThreatLevel = ClassRegistry::init('ThreatLevel');
|
||||
}
|
||||
|
||||
/**
|
||||
* tearDown method
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function tearDown() {
|
||||
unset($this->ThreatLevel);
|
||||
|
||||
parent::tearDown();
|
||||
}
|
||||
|
||||
}
|
|
@ -411,6 +411,27 @@ EOT;
|
|||
$this->assertEquals('btc', $results[0]['default_type']);
|
||||
}
|
||||
|
||||
public function testCheckFreeTextBtcBech32(): void
|
||||
{
|
||||
$complexTypeTool = new ComplexTypeTool();
|
||||
|
||||
$validAddresses = [
|
||||
'BC1QW508D6QEJXTDG4Y5R3ZARVARY0C5XW7KV8F3T4',
|
||||
'tb1qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q0sl5k7',
|
||||
'bc1pw508d6qejxtdg4y5r3zarvary0c5xw7kw508d6qejxtdg4y5r3zarvary0c5xw7k7grplx',
|
||||
'BC1SW50QA3JX3S',
|
||||
'bc1zw508d6qejxtdg4y5r3zarvaryvg6kdaj',
|
||||
'tb1qqqqqp399et2xygdj5xreqhjjvcmzhxw4aywxecjdzew6hylgvsesrxh6hy',
|
||||
];
|
||||
|
||||
foreach ($validAddresses as $validAddress) {
|
||||
$results = $complexTypeTool->checkFreeText($validAddress);
|
||||
$this->assertCount(1, $results);
|
||||
$this->assertEquals($validAddress, $results[0]['value']);
|
||||
$this->assertEquals('btc', $results[0]['default_type']);
|
||||
}
|
||||
}
|
||||
|
||||
public function testCheckFreeTextSsdeep(): void
|
||||
{
|
||||
$complexTypeTool = new ComplexTypeTool();
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
require_once __DIR__ . '/../Lib/Tools/FinancialTool.php';
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class FinancialToolTest extends TestCase
|
||||
{
|
||||
public function testValidateBtc(): void
|
||||
{
|
||||
$financialTool = new FinancialTool();
|
||||
$this->assertTrue($financialTool->validateBTC('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa'), 'P2PKH');
|
||||
$this->assertTrue($financialTool->validateBTC('3GRdnTq18LyNveWa1gQJcgp8qEnzijv5vR'), 'P2SH');
|
||||
$this->assertTrue($financialTool->validateBTC('bc1qnkyhslv83yyp0q0suxw0uj3lg9drgqq9c0auzc'), 'P2WPKH');
|
||||
$this->assertTrue($financialTool->validateBTC('bc1qar0srrr7xfkvy5l643lydnw9re59gtzzwf5mdq'), 'P2WPKH');
|
||||
$this->assertTrue($financialTool->validateBTC('bc1qc7slrfxkknqcq2jevvvkdgvrt8080852dfjewde450xdlk4ugp7szw5tk9'), 'P2WPKH');
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* ThreatLevelFixture
|
||||
*
|
||||
*/
|
||||
class ThreatLevelFixture extends CakeTestFixture {
|
||||
|
||||
/**
|
||||
* Fields
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $fields = array(
|
||||
'id' => array('type' => 'boolean', 'null' => false, 'default' => null, 'key' => 'primary'),
|
||||
'name' => array('type' => 'string', 'null' => false, 'length' => 50, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
|
||||
'description' => array('type' => 'string', 'null' => true, 'default' => null, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
|
||||
'form_description' => array('type' => 'string', 'null' => false, 'collate' => 'utf8_bin', 'charset' => 'utf8'),
|
||||
'indexes' => array(
|
||||
'PRIMARY' => array('column' => 'id', 'unique' => 1)
|
||||
),
|
||||
'tableParameters' => array('charset' => 'latin1', 'collate' => 'latin1_swedish_ci', 'engine' => 'InnoDB')
|
||||
);
|
||||
|
||||
/**
|
||||
* Records
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $records = array(
|
||||
array(
|
||||
'id' => 1,
|
||||
'name' => 'High',
|
||||
'description' => '*high* means sophisticated APT malware or 0-day attack',
|
||||
'form_description' => 'Sophisticated APT malware or 0-day attack'
|
||||
),
|
||||
array(
|
||||
'id' => 2,
|
||||
'name' => 'Medium',
|
||||
'description' => '*medium* means APT malware',
|
||||
'form_description' => 'APT malware'
|
||||
),
|
||||
array(
|
||||
'id' => 3,
|
||||
'name' => 'Low',
|
||||
'description' => '*low* means mass-malware',
|
||||
'form_description' => 'Mass-malware'
|
||||
),
|
||||
array(
|
||||
'id' => 4,
|
||||
'name' => 'Undefined',
|
||||
'description' => '*undefined* no risk',
|
||||
'form_description' => 'No risk'
|
||||
),
|
||||
);
|
||||
|
||||
}
|
Loading…
Reference in New Issue