不关注公众号获取激活码使用ghxi音乐下载网站行动失败的简单总结
首先,总的来说——行动失败了。问题出在对面判断是否返回有效数据的方式。打开网站后你会自动得到一个叫PHPSESSID的cookie。如果你提交了正确的激活码,服务器会在数据库里保存你的PHPSESSID。提交查询请求后服务器在数据库里找到你的PHPSESSID时才会返回有效数据,否则返回{"code":403}
。还有一个潜在因素是我个人技术力不够。我不是搞网络安全的,只知道自己琢磨+百度出来的那些半吊子破解技术。绕过这种需要联网进行的验证操作时我有99%的概率搞不定。以后还得多加努力啊🌚
最后把行动记录放出来吧。如果有谁看见了这篇文章并且正好有意愿小试牛刀的话可以参考一下,但是不要重蹈覆辙:
进入
https://music.ghxi.com/
,网页自动弹出输入激活码的窗口。打开F12菜单进入调试器界面,出现了经典debugger()循环,禁用断点后刷新网页直接解决掉。
找到判断验证码的js代码部分,观察以后可以发现控制激活的关键代码是这两行:
this.lock.open = 1; this.lock.lock_plane_dialog = false;
第一句使用户可以使用网站的各个按钮,第二句关闭提示输入激活码的窗口。在F12的控制台页面输入时要把this改成vue。输入代码关闭弹窗之后尝试搜索,网站提示“请先解锁”并重新出现输入激活码弹窗。
进入F12的网络页面分析请求和响应。
作为curl指令导出的post请求:
curl 'https://music.ghxi.com/wp-admin/admin-ajax.php' -X POST -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/99.0' -H 'Accept: */*' -H 'Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'X-Requested-With: XMLHttpRequest' -H 'Origin: https://music.ghxi.com' -H 'Connection: keep-alive' -H 'Referer: https://music.ghxi.com/' -H 'Cookie: PHPSESSID=f168lbt1nfsp2h78j0tv3dt4a3' -H 'Sec-Fetch-Dest: empty' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Site: same-origin' -H 'DNT: 1' -H 'Sec-GPC: 1' -H 'TE: trailers' --data-raw 'action=gh_music_ajax&type=search&music_type=qq&search_word=hello'
服务端响应:{"code":403}
请求中没有过分可疑的部分,初步判定激活码验证操作不全在本地进行。
尝试关注公众号获取激活码后进行正常的激活流程并分析请求和响应。
作为curl指令导出的post请求:
curl 'https://music.ghxi.com/wp-admin/admin-ajax.php' -X POST -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:99.0) Gecko/20100101 Firefox/99.0' -H 'Accept: */*' -H 'Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' -H 'X-Requested-With: XMLHttpRequest' -H 'Origin: https://music.ghxi.com' -H 'Connection: keep-alive' -H 'Referer: https://music.ghxi.com/' -H 'Cookie: PHPSESSID=f168lbt1nfsp2h78j0tv3dt4a3' -H 'Sec-Fetch-Dest: empty' -H 'Sec-Fetch-Mode: cors' -H 'Sec-Fetch-Site: same-origin' -H 'DNT: 1' -H 'Sec-GPC: 1' --data-raw 'action=gh_music_ajax&type=postAuth&code=ghyy521'
服务端响应:{"code":200,"msg":"u89e3u9501u6210u529f"}
再次发送最开始查询歌曲的post请求,得到的响应如下:
{"code":200,"data":[{"songname":"Hello","singer":"Greg Kurstin","albumname":"Hello"......
更换不同IP地址的机器发送相同的查询请求能得到有效的数据。
得出结论:对方根据其数据库是否存储了激活码验证成功时客户端的PHPSESSID来决定是否返回有效数据。由于个人能力有限,结束行动。
附:网站js代码
var ajaxurl = 'https://music.ghxi.com/wp-admin/admin-ajax.php';
var plugin_name = 'gh_music';
var img = 'https://music.ghxi.com/wp-content/plugins/gh-music/static/img/music.svg';
var vue = new Vue({
el: '#app',
data: {
lock: {
open: 1,
key: '',
lock_plane_dialog: false,
post_loading: false
},
player: null,
search_word: '',
drawer: false,
music_type: 'qq',
search_list: [],
down_menu_open: false,
down_menu: {
size320: 0,
sizeflac: 0,
lrc: 0,
songid: '',
songname: '',
singer: '',
url: '',
},
loading: {
search: false,
down_menu: false,
play: false
},
play: {
url: '',
play: false,
item: {
songname: '点击播放音乐',
singer: '果核音乐',
albumname: '免费音乐下载',
album_img: img
}
},
down_plane_dialog: false,
about_plane_dialog: false,
about_version_dialog: false,
app_info: {
version: '1.1'
}
},
methods: {
click_play() {
if (this.play.url == '') {
this.$toast.message('老表,先点击要听的音乐')
return;
}
this.player.play();
this.play.play = true;
},
playMusic(item) {
this.loading.play = true;
$.post(ajaxurl, {
action: plugin_name + '_ajax',
type: 'getMusicUrl',
music_type: this.music_type,
music_size: '128',
songid: item.songid
}, (data) => {
var obj = JSON.parse(data);
if (obj.code == 200) {
this.play.url = obj.url;
this.play.play = true;
this.play.item = item;
this.player.src = this.play.url;
this.player.play();
} else {
}
this.loading.play = false;
})
},
search() {
if (this.lock.open != 1) {
this.lock.lock_plane_dialog = true;
return;
}
this.loading.search = true;
$.post(ajaxurl, {
action: plugin_name + '_ajax',
type: 'search',
music_type: this.music_type,
search_word: this.search_word
}, (data) => {
var obj = JSON.parse(data);
if (obj.code == 200) {
this.search_list = obj.data;
} else if (obj.code == 403) {
this.$toast.error('请先解锁');
this._lock()
} else {
this.$toast.error('搜索发生错误');
}
this.loading.search = false;
})
},
clickDownMusic(item) {
this.down_menu_open = true;
this.down_menu.sizeflac = item.sizeflac;
this.down_menu.size320 = item.size320;
this.down_menu.songid = item.songid;
this.down_menu.songname = item.songname;
this.down_menu.singer = item.singer;
},
downMusic(music_size) {
this.loading.down_menu = true;
$.post(ajaxurl, {
action: plugin_name + '_ajax',
type: 'getMusicUrl',
music_type: this.music_type,
music_size,
songid: this.down_menu.songid
}, (data) => {
var obj = JSON.parse(data);
if (obj.code == 200) {
this.down_menu.url = obj.url;
this.down_plane_dialog = true;
} else if (obj.code == 403) {
this.down_plane_dialog = false;
this.down_menu_open = false;
this._lock();
}
this.loading.down_menu = false;
})
},
_lock() {
this.lock.lock_plane_dialog = true;
this.lock.open = 0;
},
auth() {
$.post(ajaxurl, {
action: plugin_name + '_ajax',
type: 'isauth',
}, (data) => {
var obj = JSON.parse(data);
if (obj.code === 200) {
this.lock.open = 1;
this.lock.lock_plane_dialog = false;
} else {
this._lock();
}
})
},
post_auth() {
if (this.lock.key.length < 6) {
this.$toast.error('请输入密码')
return;
}
this.lock.post_loading = true;
$.post(ajaxurl, {
action: plugin_name + '_ajax',
type: 'postAuth',
code: this.lock.key
}, (data) => {
var obj = JSON.parse(data);
if (obj.code === 200) {
this.lock.open = 1;
this.lock.lock_plane_dialog = false;
} else {
this.$toast.error(obj.msg)
this.lock.lock_plane_dialog = true;
this.lock.open = 0;
}
this.lock.post_loading = false;
})
},
copyText(text) {
const input = document.createElement('input');
document.body.appendChild(input);
input.value = text;
input.select();
document.execCommand('Copy')
document.body.removeChild(input);
this.$toast.success('复制成功');
}
},
mounted() {
this.$toast.config({
position: 'top', // 弹出的位置
time: 2000, // 显示的时长
closeIcon: 'close', // 关闭的图标
close: false, // 是否显示关闭按钮
successIcon: 'check_circle', // 成功信息图标
infoIcon: 'info', // 信息信息图标
warningIcon: 'priority_high', // 提醒信息图标
errorIcon: 'warning' // 错误信息图标
})
this.player = document.createElement("audio");
document.documentElement.appendChild(this.player);
this.auth()
noDebuger();
}
})
function noDebuger() {
function testDebuger() { var KJD$u1 = new window["x44x61x74x65"](); debugger; if (new window["x44x61x74x65"]() - KJD$u1 > 10) { window["x64x6fx63x75x6dx65x6ex74"]['x62x6fx64x79']['x69x6ex6ex65x72x48x54x4dx4c'] = 'x3cx64x69x76x3eu79c1u6709u63a5u53e3uff0cu8bf7u52ffu8c03u7528uff1ax68x74x74x70x73x3ax2fx2fx6dx75x73x69x63x2ex67x68x78x69x2ex63x6fx6dx3cx2fx64x69x76x3e'; return true } return false }
function start() {
while (testDebuger()) {
testDebuger()
}
}
if (!testDebuger()) {
window['x6fx6ex62x6cx75x72'] = function () {
setTimeout(function () {
start()
}, 500)
}
} else {
start()
}
}