js-confuser icon indicating copy to clipboard operation
js-confuser copied to clipboard

TypeError: this[o] is not a function

Open Probabilities opened this issue 1 year ago • 8 comments

Describe the bug:

Unable to obfuscate my script since I get this error

`TypeError: this[o] is not a function`

The syntax of the code is correct. I can run it without the obfuscation.

Code:

const uuid = require('uuid').v4;
const { createHash, createCipheriv, createDecipheriv } = require('crypto');
const { request } = require('undici');
const { execSync } = require('child_process');
const os = require('os');

class keyauth {
    constructor (name, ownerid, secret, version, hash_to_check) {
        if(!(name && ownerid && secret && version && hash_to_check) ) {
            console.log('Make sure you fill out all fields')
            process.exit(1)
        }

        this.name = name

        this.ownerid = ownerid
    
        this.secret = secret

        this.version = version
        this.hash_to_check = hash_to_check
    };

    initialize = () => new Promise(async(resolve) => {
        this.enckey = createHash('sha256').update(uuid().substring(0, 8)).digest('hex');
        const init_iv = createHash('sha256').update(uuid().substring(0, 8)).digest('hex');

        const post_data = {
            'type': Buffer.from('init').toString('hex'),
            'ver': Encryption.encrypt(this.version, this.secret, init_iv),
            'hash': this.hash_to_check,
            'enckey': Encryption.encrypt(this.enckey, this.secret, init_iv),
            'name': Buffer.from(this.name).toString('hex'),
            'ownerid': Buffer.from(this.ownerid).toString('hex'),
            'init_iv': init_iv
        }

        const response = await Misc.make_request(post_data)
        const decrypted = Encryption.decrypt(response, this.secret, init_iv)

        const parsed = JSON.parse(decrypted)

        if(!parsed.success || parsed.success == false){
            return resolve(false)
        }

        this.sessionid = parsed.sessionid
        this.initialized = true
        
        resolve(parsed)
    });

    upgrade = (username, license) => new Promise(async(resolve) => {
        this.check_initialize()

        const init_iv = createHash('sha256').update(uuid().substring(0, 8)).digest('hex');

        const post_data = {
            'type': Buffer.from('upgrade').toString('hex'),
            'username': Encryption.encrypt(username, this.enckey, init_iv),
            'key': Encryption.encrypt(license, this.enckey, init_iv),
            'sessionid': Buffer.from(this.sessionid).toString('hex'),
            'name': Buffer.from(this.name).toString('hex'),
            'ownerid': Buffer.from(this.ownerid).toString('hex'),
            'init_iv': init_iv
        }

        const response = await Misc.make_request(post_data)
        const decrypted = Encryption.decrypt(response, this.enckey, init_iv)

        const parsed = JSON.parse(decrypted)

        return resolve(parsed)
    })

    register = (user, password, license, hwid = null) => new Promise(async(resolve) => {
        this.check_initialize()

        if(!hwid) {
            hwid = Misc.get_hwid()
            global.hwid = hwid
        }

        const init_iv = createHash('sha256').update(uuid().substring(0, 8)).digest('hex');

        const post_data = {
            'type': Buffer.from('register').toString('hex'),
            'username': Encryption.encrypt(user, this.enckey, init_iv),
            'pass': Encryption.encrypt(password, this.enckey, init_iv),
            'key': Encryption.encrypt(license, this.enckey, init_iv),
            'hwid': Encryption.encrypt(hwid, this.enckey, init_iv),
            'sessionid': Buffer.from(this.sessionid).toString('hex'),
            'name': Buffer.from(this.name).toString('hex'),
            'ownerid': Buffer.from(this.ownerid).toString('hex'),
            'init_iv': init_iv
        }

        const response = await Misc.make_request(post_data)
        const decrypted = Encryption.decrypt(response, this.enckey, init_iv)

        const parsed = JSON.parse(decrypted)

        return resolve(parsed)
    })

    login = (username, password, hwid = null) => new Promise(async(resolve) => {
        this.check_initialize()

        if(!hwid) {
            hwid = Misc.get_hwid()
            global.hwid = hwid
        }

        const init_iv = createHash('sha256').update(uuid().substring(0, 8)).digest('hex');

        const post_data = {
            'type': Buffer.from('login').toString('hex'),
            'username': Encryption.encrypt(username, this.enckey, init_iv),
            'pass': Encryption.encrypt(password, this.enckey, init_iv),
            'hwid': Encryption.encrypt(hwid, this.enckey, init_iv),
            'sessionid': Buffer.from(this.sessionid).toString('hex'),
            'name': Buffer.from(this.name).toString('hex'),
            'ownerid': Buffer.from(this.ownerid).toString('hex'),
            'init_iv': init_iv
        }

        const response = await Misc.make_request(post_data)
        const decrypted = Encryption.decrypt(response, this.enckey, init_iv)

        const parsed = JSON.parse(decrypted)

        return resolve(parsed)
    })

    webhook = (webid, body = '', param = '', type = 'application/json') => new Promise(async(resolve) => {
        this.check_initialize()

        if(type == 'application/json') body = JSON.stringify(body)

        const init_iv = createHash('sha256').update(uuid().substring(0, 8)).digest('hex');

        const post_data = {
            'type': Buffer.from('webhook').toString('hex'),
            'webid': Encryption.encrypt(webid, this.enckey, init_iv),
            'params': Encryption.encrypt(param, this.enckey, init_iv),
            'body': Encryption.encrypt(body, this.enckey, init_iv),
            'conttype': Encryption.encrypt(type, this.enckey, init_iv),
            'sessionid': Buffer.from(this.sessionid).toString('hex'),
            'name': Buffer.from(this.name).toString('hex'),
            'ownerid': Buffer.from(this.ownerid).toString('hex'),
            'init_iv': init_iv
        }

        const response = await Misc.make_request(post_data)
        const decrypted = Encryption.decrypt(response, this.enckey, init_iv)

        const parsed = JSON.parse(decrypted)

        if(parsed.success && parsed.success == true) {
            return resolve(parsed)
        }

        resolve(parsed)
    })

    globalVar = (variable_name) => new Promise(async(resolve) => {
        this.check_initialize()

        const init_iv = createHash('sha256').update(uuid().substring(0, 8)).digest('hex');

        const post_data = {
            'type': Buffer.from('var').toString('hex'),
            'varid': Encryption.encrypt(variable_name, this.enckey, init_iv),
            'sessionid': Buffer.from(this.sessionid).toString('hex'),
            'name': Buffer.from(this.name).toString('hex'),
            'ownerid': Buffer.from(this.ownerid).toString('hex'),
            'init_iv': init_iv
        }

        const response = await Misc.make_request(post_data)
        const decrypted = Encryption.decrypt(response, this.enckey, init_iv)

        const parsed = JSON.parse(decrypted)

        
        if(parsed.success && parsed.success == true) {
            return resolve(parsed?.message)
        }

        resolve(parsed.message)
    })

    getvar = (variable_name) => new Promise(async(resolve) => {
        this.check_initialize()

        const init_iv = createHash('sha256').update(uuid().substring(0, 8)).digest('hex');

        const post_data = {
            'type': Buffer.from('getvar').toString('hex'),
            'var': Encryption.encrypt(variable_name, this.enckey, init_iv),
            'sessionid': Buffer.from(this.sessionid).toString('hex'),
            'name': Buffer.from(this.name).toString('hex'),
            'ownerid': Buffer.from(this.ownerid).toString('hex'),
            'init_iv': init_iv
        }

        const response = await Misc.make_request(post_data)
        const decrypted = Encryption.decrypt(response, this.enckey, init_iv)

        const parsed = JSON.parse(decrypted)

        resolve(parsed)
    })

    check_initialize() {
        if(!this.initialized) {
            console.log('Not initialized')
            return process.exit(1)
        }

        return true
    };
}

class Encryption {
    static encrypt(message, enc_key, iv) {
        try{
            const _key = createHash('sha256').update(enc_key).digest('hex').substring(0, 32)
    
            const _iv = createHash('sha256').update(iv).digest('hex').substring(0, 16)
    
            return this.encrypt_string(message, _key, _iv)
        }catch(err){
            process.exit(1)
        }
    };

    static encrypt_string(plain_text, key, iv) {
        const cipher = createCipheriv('aes-256-cbc', key, iv)
        let crypted = cipher.update(plain_text, 'utf-8', 'hex')
        crypted += cipher.final('hex')
        return crypted
    };

    static decrypt(message, key, iv) {
        try{
            const _key = createHash('sha256').update(key).digest('hex').substring(0, 32)
    
            const _iv = createHash('sha256').update(iv).digest('hex').substring(0, 16)
    
            return this.decrypt_string(message, _key, _iv)
        }catch(err) {
            return JSON.stringify({ success: false, message: 'Failed to decrypt' })
        }
    };

    static decrypt_string(cipher_text, key, iv) {
        const decipher = createDecipheriv('aes-256-cbc', key, iv)
        let decrypted = decipher.update(cipher_text, 'hex', 'utf-8')
        decrypted += decipher.final('utf-8')
        return decrypted
    }
}


class Misc {
    static get_hwid() {
        if(os.platform() != 'win32') return false

        const cmd = execSync('wmic useraccount where name="%username%" get sid').toString('utf-8')

        const system_id = cmd.split('\n')[1].trim()
        return system_id
    };

    static make_request = (data) => new Promise(async(resolve) => {
        const { body } = await request('https://keyauth.win/api/1.0/', {
            method: 'POST', 
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            },
            body: new URLSearchParams(data).toString()
        }).catch(() => {
            return resolve(false)
        })

        try{
            var response = await body.text()
        }catch{
            return resolve(false)
        }

        resolve(response)
    })
}

module.exports = keyauth

Expected behavior

no errors I guess lol

Actual behavior

doesnt obfuscate

Additional context

Failed to find the issue.

Probabilities avatar Nov 30 '23 21:11 Probabilities

Hi can share your config

MichaelXF avatar Nov 30 '23 23:11 MichaelXF

Hi can share your config

Hi, I used the medium preset and that didn't work so I reverted to disabling all the options where also that did not work

Probabilities avatar Nov 30 '23 23:11 Probabilities

Oh this is because of the class properties being used. Unfortunately, escodegen, has not been updated in a while to support this.

I would rewrite your class fields to regular class methods if your code is small enough.

In the future, a better generator will be used by JS-Confuser that supports this

MichaelXF avatar Nov 30 '23 23:11 MichaelXF

Oh this is because of the class properties being used. Unfortunately, escodegen, has not been updated in a while to support this.

I would rewrite your class fields to regular class methods if your code is small enough.

In the future, a better generator will be used by JS-Confuser that supports this

is this from the encryption class when i call this.decrypt_string etc?

Probabilities avatar Nov 30 '23 23:11 Probabilities

can you please show me an example?

Probabilities avatar Dec 01 '23 09:12 Probabilities

Change all class properties to method definitions

initialize = () => new Promise(…

to

initialize() { return new Promise(… }

MichaelXF avatar Dec 01 '23 20:12 MichaelXF

thanks, working now :)

Probabilities avatar Dec 02 '23 19:12 Probabilities

I ran into the same issue. It'd be great to add a warning that the ()=> constuct is not allowed, at least until the scrambler is updated.

CABrouwers avatar Apr 22 '24 20:04 CABrouwers