记一次某设备的授权p解

admin 2024年6月3日16:48:54评论17 views字数 14498阅读48分19秒阅读模式

拿到了一个虚拟机程序镜像,安装起来分析一下某设备。

为了保护隐私,这边厚码一下,把一些敏感的信息都给替换掉了。

在审计之前,你得先保证程序能够正常跑起来,那么就要把程序的授权给干掉。

找到web端口对应进程

yum install net-tools -y
netstat -lnpt

得到系统开放的端口和进程,例如

[root@testName ~]# netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:27017           0.0.0.0:*               LISTEN      28708/mongod        
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1417/master         
tcp        0      0 0.0.0.0:60000           0.0.0.0:*               LISTEN      2039/sshd: /usr/sbi 
tcp6       0      0 :::7687                 :::*                    LISTEN      45857/java          
tcp6       0      0 :::9200                 :::*                    LISTEN      2554/java           
tcp6       0      0 :::7473                 :::*                    LISTEN      45857/java          
tcp6       0      0 :::7474                 :::*                    LISTEN      45857/java          
tcp6       0      0 :::9300                 :::*                    LISTEN      2554/java           
tcp6       0      0 ::1:25                  :::*                    LISTEN      1417/master         
tcp6       0      0 :::443                  :::*                    LISTEN      2642/node /usr/loca 
tcp6       0      0 127.0.0.1:9600          :::*                    LISTEN      2824/java           
tcp6       0      0 :::60000                :::*                    LISTEN      2039/sshd: /usr/sbi 
tcp6       0      0 :::50051                :::*                    LISTEN      1772/netmgrd        
tcp6       0      0 :::6789                 :::*                    LISTEN      2794/java 

优先看允许所有人访问的,例如这里的

:::443
0.0.0.0:60000

一个个访问过去

记一次某设备的授权p解

这里确认443是web端口,并且知道对应的pid是2642,去找到端口对应的文件路径

[root@testName ~]# ps -aux | grep 2642
test       2642  0.4  3.5 1181852 290420 ?      Ssl  Jan16   1:00 node /usr/local/testName/program/jd_analysis/bin/www
root     108152  0.0  0.0 112832  2340 pts/2    S+   01:03   0:00 grep --color=auto 2642

或者直接看/proc/2642 下面的信息。这里是一个二进制文件,如果是apache或者nginx这种中间件,就要去看指定的配置文件的信息。

[root@testName ~]# ls -alh /proc/2642
total 0
dr-xr-xr-x   9 test test 0 Jan 16 20:54 .
dr-xr-xr-x 246 root root 0 Jan 16 20:54 ..
-r--r--r--   1 test test 0 Jan 17 01:04 arch_status
dr-xr-xr-x   2 test test 0 Jan 16 20:55 attr
-rw-r--r--   1 test test 0 Jan 17 01:04 autogroup
-r--------   1 test test 0 Jan 17 01:04 auxv
-r--r--r--   1 test test 0 Jan 17 01:04 cgroup
--w-------   1 test test 0 Jan 17 01:04 clear_refs
-r--r--r--   1 test test 0 Jan 16 20:55 cmdline
-rw-r--r--   1 test test 0 Jan 17 01:04 comm
-rw-r--r--   1 test test 0 Jan 17 01:04 coredump_filter
-r--r--r--   1 test test 0 Jan 17 01:04 cpuset
lrwxrwxrwx   1 test test 0 Jan 17 01:04 cwd -> /
-r--------   1 test test 0 Jan 17 01:04 environ
lrwxrwxrwx   1 test test 0 Jan 17 01:04 exe -> /usr/local/testName/program/node/bin/node
dr-x------   2 test test 0 Jan 16 20:55 fd
dr-x------   2 test test 0 Jan 17 01:04 fdinfo
-rw-r--r--   1 test test 0 Jan 17 01:04 gid_map
-r--------   1 test test 0 Jan 17 01:04 io
-r--r--r--   1 test test 0 Jan 17 01:04 limits
-rw-r--r--   1 test test 0 Jan 17 01:04 loginuid
dr-x------   2 test test 0 Jan 17 01:04 map_files
-r--r--r--   1 test test 0 Jan 17 01:04 maps
-rw-------   1 test test 0 Jan 17 01:04 mem
-r--r--r--   1 test test 0 Jan 17 01:04 mountinfo
-r--r--r--   1 test test 0 Jan 17 01:04 mounts
-r--------   1 test test 0 Jan 17 01:04 mountstats
dr-xr-xr-x  51 test test 0 Jan 17 01:04 net
dr-x--x--x   2 test test 0 Jan 17 01:04 ns
-r--r--r--   1 test test 0 Jan 17 01:04 numa_maps
-rw-r--r--   1 test test 0 Jan 17 01:04 oom_adj
-r--r--r--   1 test test 0 Jan 17 01:04 oom_score
-rw-r--r--   1 test test 0 Jan 17 01:04 oom_score_adj
-r--------   1 test test 0 Jan 17 01:04 pagemap
-r--------   1 test test 0 Jan 17 01:04 personality
-rw-r--r--   1 test test 0 Jan 17 01:04 projid_map
lrwxrwxrwx   1 test test 0 Jan 17 01:04 root -> /
-rw-r--r--   1 test test 0 Jan 17 01:04 sched
-r--r--r--   1 test test 0 Jan 17 01:04 schedstat
-r--r--r--   1 test test 0 Jan 17 01:04 sessionid
-rw-r--r--   1 test test 0 Jan 17 01:04 setgroups
-r--r--r--   1 test test 0 Jan 17 01:04 smaps
-r--r--r--   1 test test 0 Jan 17 01:04 smaps_rollup
-r--------   1 test test 0 Jan 17 01:04 stack
-r--r--r--   1 test test 0 Jan 16 20:54 stat
-r--r--r--   1 test test 0 Jan 17 01:04 statm
-r--r--r--   1 test test 0 Jan 16 20:55 status
-r--------   1 test test 0 Jan 17 01:04 syscall
dr-xr-xr-x  12 test test 0 Jan 17 01:04 task
-rw-r--r--   1 test test 0 Jan 17 01:04 timens_offsets
-r--r--r--   1 test test 0 Jan 17 01:04 timers
-rw-rw-rw-   1 test test 0 Jan 17 01:04 timerslack_ns
-rw-r--r--   1 test test 0 Jan 17 01:04 uid_map
-r--r--r--   1 test test 0 Jan 17 01:04 wchan

从cmdline文件中可以看到启动命令是

node /usr/local/testName/program/jd_analysis/bin/www

那么就可以定位到 /usr/local/testName/program/jd_analysis/bin/www 但是这里是一个二进制文件

vi看一下发现是一个nodejs文件,包含了../app

#!/usr/bin/nodejs
var debug = require('debug')('my-application');
var app = require('../app');

var slowloris = require('node-slowloris');

app.set('port', process.env.PORT || 80);

var server = app.listen(app.get('port'), function() {
  debug('Express server listening on port ' + server.address().port);
});

//server.setTimeout(0);

slowloris(server, {
  headerTimeout250000// in ms, default 2500
  minRate500,       // bytes per second, default 500
  rateOverhead50    // in ms this will be subtracted from the time when calculating the rate, default 50
});

到这里就可以定位到源码在 /usr/local/testName/program/jd_analysis/

[root@testName ~]# ls /usr/local/testName/program/jd_analysis/
app.js  bin  byteExchangeUtil.js  db  log4j.js  logs  npm-debug.log  package.json  public  routes  views  winston.js

是node.js写的程序

代码分析

再往上一级的目录比较大,应该是用到的组件。我们先拉下来jd_analysis的代码看看

[root@testName ~]# ls /usr/local/testName/program/
conf  c_program  download  elasticsearch  java  jd_analysis  las.json  laswatchdog  logstash  mongodb  neo4j  net-snmp  node  node_modules  phantomjs  upgrade

这里sftp一开始用不了,改一下sshd_config的配置就可以用了,把sftp的注释给去掉了

# override default of no subsystems
Subsystem       sftp    /usr/libexec/openssh/sftp-server

看了一下大致理解路由走向,app.use可以注册成一个路由,貌似nodejs也支持使用event绑定直接定义成路径,但是这里没看见

app.use()是Express中的一个中间件函数,用于将中间件函数绑定到应用程序的路径上。它可以接收一个或多个回调函数作为参数,每个回调函数都会在请求被路由匹配之前执行。假设我们有一个Express应用程序,并且需要对所有请求进行身份验证。我们可以使用app.use()来绑定一个身份验证中间件函数

/*app.use('/asset',asset);
app.use('/account',account);*/

app.use('/', routes);

app.use('/systemSetting', systemSetting);
app.use("/state", state);
app.use('/statistics', statistics);
app.use('/logSearch', logSearch);
app.use('/posiSearch', posiSearch);
app.use("/historySearch", historySearch);
app.use("/associationRules", associationRules);
app.use("/log", log);
app.use("/operationHistory", operationHistory);
app.use("/reverseHistory", reverseHistory);
app.use("/relationRule", relationRule);
app.use("/graph", graph);
app.use("/relationRuleFil", relationRuleFil);
app.use("/portrait", portrait);
app.use("/assetList", assetList);
app.use("/assetType", assetType);
app.use('/monitor', monitor);
app.use('/analysisRules', analysisRules);
app.use("/alarm", alarm);
app.use('/filterRules', filterRules);
app.use('/associationAnalysis', associationAnalysis);
app.use("/authorization", authorization);
app.use("/role", role);
app.use("/loginManager", loginManager);
app.use("/report", report);
app.use("/alarmOverview", alarmOverview);
app.use("/alarmUserRanking", alarmUserRanking);
app.use("/userOperation", userOperation);
app.use("/systemAlarmStatistics", systemAlarmStatistics);
app.use("/systemAlert", systemAlert);
app.use('/alert', alert);
app.use('/alertNotice', alertNotice);
app.use('/componentShape', componentShape);
app.use('/netWorkSetup', netWorkSetup);
app.use('/communicationSetup', communicationSetup);
app.use('/doubleMdisk', doubleMdisk);
app.use("/cascade", cascade);
app.use("/verControl", verControl);
app.use("/serverMailSetting", serverMailSetting);
app.use("/cipherStrategy", cipherStrategy);
app.use("/regular", regular);
app.use("/indexInformation", indexInformation);
app.use("/policeInformation", policeInformation);
app.use("/collector", collector);
app.use("/knowledge", knowledge);
app.use("/files", files);
app.use("/logSummary", logSummary);
app.use("/logImport", logImport);
app.use("/logMonitoring", logMonitoring);
app.use("/record", record);
app.use("/licenseInformation", licenseInformation);
app.use("/systemUpgrade", systemUpgrade);
app.use("/ping", ping);
app.use("/traceroute", traceroute);
app.use("/shutdownOrrestart", shutdownOrrestart);
app.use("/alertSing", alertSing);
app.use("/whiteList", whiteList);
app.use("/blockConfig", blockConfig);
app.use("/dbConfig", dbConfig);
app.use("/searchConditon", searchConditon);
app.use("/homeState", homeState);
app.use("/oem", oem);
app.use("/collectorManager", collectorManager);
app.use("/api", api);
// app.use("/supOS", supOS);
app.use("/sysinfo", sysinfo);
app.use("/theme", theme);
app.use("/netconf", netconf);
app.use("/system"System);
app.use("/auth", authJs);
app.use("/ifarm", ifarm);
app.use("/upgrade", ftpUpgrade);
app.use("/serviceSetting", serviceSetting);
app.use("/onlineParser", onlineParser);
app.use("/lexicon",lexicon)
app.use("/topology", topology);
app.use("/Filter"Filter);
app.use('/users', users);
app.use('/acquisition', acquisition);
app.use('/SafetyLibrary'SafetyLibrary); //安全库路由
app.use("/mergerRules", mergerRules);

还有一些路由如/ueditor/ueditor等,直接搜索app.use(" 就可以得到了。

授权破解

看描述授权是过期的,去看看相关代码

记一次某设备的授权p解
function execCheckLicenceStatus() {
    var task = cron.schedule("*/1 * * * *"function () {
        checkLicenceStatus();
    });
}

授权状态检测

function checkAuthAssetNum(cal) {
    var countquery = asset.count({"licenceStatus"1});
    countquery.exec(function (err, count) {
        if (err) {

        } else {
            getLiceceAssetNum(function (sum, id) {
                var result = sum - count;
                var number = 0;
                var noLicenResult = result;
                if (result > 0) {
                    var query = asset.find({"licenceStatus"0});
                    query.exec(function (err, noLicenceResult) {
                        if (noLicenceResult != null) {
                            noLicenceResult.forEach(function (element, index) {
                                if (index <= noLicenResult - 1) {
                                    asset.update({_id: element._id}, {
                                        $set: {
                                            licenceStatus1
                                        }
                                    }, function (err) {
                                        console.log("licence 更换")
                                    });
                                    result = result - 1;
                                } else {
                                    result = 0;
                                }
                            });
                        }
                    });
                    number = result
                } else {
                    var query = asset.find({"licenceStatus"1}).sort({assetUpdateTime:-1});
                    query.exec(function (err, result) {
                        if (result != null) {
                            result.forEach(function (element, index) {
                                if (index > sum - 1) {
                                    asset.update({_id: element._id}, {
                                        $set: {
                                            licenceStatus0,
                                            assetEventCount0
                                        }
                                    }, function (err) {
                                        console.log("licence 更换")
                                    });
                                }
                            });
                        }
                    });
                    number = 0;
                }
                licenceModel.update({_id: id}, {
                    $set: {
                        surplusNum: number
                    }
                }, function (err) {

                });
                cal(result);
            })
        }
    });
}

感觉是uuid这些授权信息是从mongodb数据库拿的,需要连上数据库看看。

注释里的测试数据感觉也是有参考价值的

/*license.update({uuid: "eff3467a-e80e-11ea-a5c2-52540082e7d4"}, {
    $set: {
        sequenceStatus: 1,
        timeStatus: 1,
        volume: 1601557932000,
        resourceNum: 100,
        volumePercent: 1,
        surplusNum: 99,
        volumeStatus: 100,
        time: 34,
        changeStatus:1
    }
},{upsert:true},function (err, result) {
    if (err) {
        console.log("active deviceLicence save license-updated failed,the error is:["+err+"]");
        cb(0)
    } else {
        cb(1)
    }
})*/

/*license.update({uuid: "eff3467a-e80e-11ea-a5c2-52540082e7d4"}, {
    $set: {
        sequenceStatus: 1,
        timeStatus: 1,
        volume: 1601557932000,
        resourceNum: 100,
        volumePercent: 1,
        surplusNum: 99,
        volumeStatus: 60,
        time: 30,
        changeStatus:1
    }
},{upsert:true},function (err, result) {
    if (err) {
        console.log("active deviceLicence save license-updated failed,the error is:["+err+"]");
        cb(0)
    } else {
        cb(1)
    }
});*/

/*var aesResult = aseUtil.aes_encrypt_containAll("aa0e6fce-802b-440e-8ceb-1842f086c00dv112020-08-27T16:37:29+08:002020-09-27T23:59:59+08:00100","OFB").toString();
var mkSummary = StringUtil.getSha256(aesResult);
console.log(mkSummary)*/


/*aesResult = aseUtil.aes_encrypt("aa0e6fce-802b-440e-8ceb-1842f086c00dv132020-08-17T13:42:22+08:002021-02-17T23:59:59+08:00100","148fc14fa50b7f52","9e3612f18c520c6b","OFB");
console.log(aesResult.toString())
console.log(StringUtil.getSha256(aesResult.toString()));*/

用账号密码连接一下数据库。

192.168.121.143
admin
root
[email protected]

数据表信息一开始是隐藏的,但是可以这样打开

记一次某设备的授权p解
_id resourceNum sequenceStatus timeStatus time volumeStatus volume volumePercent changeStatus uuid surplusNum
5fe308c93c863febac7g021b 0 1 1 0 0 0 0 0 e360a26e-28a9-11eb-a97f-5254003827cb 0

结合这里的代码注释就可以修改成合格的license了

var licenceInfoModel = new Schema({
    sequenceStatus:Number//默认1
    timeStatus:Number,  //默认1
    time:Number//剩余时间
    volumeStatus:Number//授权天数
    volume:Number//授权时间
    volumePercent:Number//已用资源
    resourceNum:Number//授权资源数
    uuid:String//UUID信息
    surplusNum:Number//剩余资源数
    changeStatus:Number
});

代码里的授权判断

var availableDay = parseInt((result.volume - new Date().getTime()) / (24 * 60 * 60 * 1000));
console.log("licence avaliableDay is:" + availableDay);

那么把这个字段改成合适的时间戳就可以了。

例如 1715479245312 就有115天了。(这里有一个坑点,忘记了字段原来的属性是啥了,我改了这个字段的属性为string,否则默认的属性无法保存)

接口也可以访问了

记一次某设备的授权p解
用账号密码登录一下对比更直观

记一次某设备的授权p解

这里就可以看见登录成功啦

记一次某设备的授权p解

如果是授权未更新登录则是下图这样

记一次某设备的授权p解

漏洞审计……等后续得空更新1下

原文始发于微信公众号(安全光圈):记一次某设备的授权p解

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年6月3日16:48:54
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   记一次某设备的授权p解https://cn-sec.com/archives/2810170.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息