我最近突然发现pc端的discord也能一次性上传多于一个的附件🤔我觉得是时候研究下高级discord drive antics了(确信🤔
照例,先上传两个普通txt文件,一个内容是AquaCriUGUU
,一个内容是AmberCriUGUU
(都没有回车),抓下包:
-----------------------------12657909637655735752817477993
Content-Disposition: form-data; name="files[0]"; filename="aqua.txt"
Content-Type: text/plain
AquaCriUGUU
-----------------------------12657909637655735752817477993
Content-Disposition: form-data; name="files[1]"; filename="amber.txt"
Content-Type: text/plain
AmberCriUGUU
-----------------------------12657909637655735752817477993
Content-Disposition: form-data; name="payload_json"
{"content":"","nonce":"912253418741956608","type":0,"sticker_ids":[],"attachments":[{"id":"0","filename":"aqua.txt"},{"id":"1","filename":"amber.txt"}]}
-----------------------------12657909637655735752817477993--
这就是post请求的所有内容了🤔上面那坨数字对应着请求里header
-H 'Content-Type: multipart/form-data; boundary=---------------------------12657909637655735752817477993'
里的数字,用来将每个文件和最后的payload隔开🤔实测改成什么1145141919810都是没有问题的,当然如果文件里面出现了这个玩意那就不太好收场了(悲🤔
既然post请求如此,那么我们就可以构造post请求了🤔bash代码如下:
tmpfile="/tmp/barbruh"
delimiter="-----------------------------1145141919810"
function formdata(){ # 1 = id,2 = filepath
fileid="1"
filepath="2"
mimetype=`file -b --mime-type "filepath"`
filename="{filepath##*/}"
line1='Content-Disposition: form-data; name="files['"1"']"; filename="'"filename"'"'
line2='Content-Type: '"mimetype"
# line3=`cat "filepath"`
echo -n "delimiter"'\r\n'"line1"'\r\n'"line2"'\r\n\r\n' >> "tmpfile"
cat "filepath" >> "tmpfile"
echo -n'\r\n' >> "tmpfile"
attachments="attachments, "'{"id":"'"fileid"'","filename":"'"filename"'"}'
# echo "files"
}
function payload(){
line1='Content-Disposition: form-data; name="payload_json"'
line2='{"content":"","type":0,"sticker_ids":[],"attachments":['"{attachments/, /}"']}'
line3="3"
res="delimiter"'\r\n'"line1"'\r\n\r\n'"line2"'\r\n'"delimiter--"'\r\n'
echo -n "res" >> "tmpfile"
}
echo -n "" > "tmpfile"
attachments=""
formdata 0 "/tmp/aqua.txt"
formdata 1 "/tmp/amber.txt"
payload
cat "tmpfile" | curl 'https://discord.com/api/v9/channels/1145141919810/messages' -X POST \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0' \
-H 'Accept: */*' \
-H 'Accept-Language: en-US' \
-H 'Content-Type: multipart/form-data; boundary=---------------------------1145141919810' \
-H 'Origin: https://discord.com' \
-H 'Connection: keep-alive' \
-H 'Referer: https://discord.com/channels/1145141919810/1145141919810' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Pragma: no-cache' \
-H 'Cache-Control: no-cache' \
-H 'TE: trailers' \
--data-binary "@-"
注意到我先将所有构造好的post数据保存到了一个临时文件里,然后直接将这个临时文件通过管道塞进curl里,就像我在搜书盘的bash脚本里做的那样🤔为什么我需要这样做?因为至少在cygwin里,试图通过将文件读入字符串的方式构造符合需求的post数据,将直接撑爆cygwin的bash解释器🤔我不清楚为什么它垃圾到处理一个50MB大小的字符串都不行,但这也说明是时候扬长避短了🤔bash的长其实在文件处理方面(确信🤔那么我们便将上面生成的所有玩意全部塞进临时文件里面,echo需要加-n
来避免多生成回车🤔
当然,我觉得像以前那样使用-F也是可行的,搞不好还不用生成临时文件,这个就接下来再折腾了(悲🤔
thonk
我看了一遍bash管道的实现之后,突然发现如果我把所有构造post数据的代码写进一个函数,在这个函数里把所有的post数据扔进stdout,这样我不就可以直接管道进curl了吗🤔而且curl那部分也可以写成一个函数,主要是判断该走webhook还是走账号,反正curl接收post数据的地方是stdin,而不是参数(确信🤔
所以,只需要将原来的那两个函数后面的重定向到临时文件的部分删掉就完事了🤔现在的代码长这样子:
delimiter="1145141919810"
function formdata_v2(){ # 1 = id,2 = filepath
fileid="1"
filepath="2"
mimetype=`file -b --mime-type "filepath"`
filename="{filepath##*/}"
line1='Content-Disposition: form-data; name="files['"1"']"; filename="'"filename"'"'
line2='Content-Type: '"mimetype"
echo -n "-----------------------------delimiter"'\r\n'"line1"'\r\n'"line2"'\r\n\r\n'
cat "filepath"
echo -n '\r\n'
attachments="attachments, "'{"id":"'"fileid"'","filename":"'"filename"'"}'
}
function payload_v2(){ line1='Content-Disposition: form-data; name="payload_json"'
line2='{"content":"","type":0,"sticker_ids":[],"attachments":['"{attachments/, /}"']}'
line3="3"
res="-----------------------------delimiter"'\r\n'"line1"'\r\n\r\n'"line2"'\r\n'"-----------------------------delimiter--"'\r\n'
echo -n "res"
}
function formpostdata() {
opts="#"
for nein in `seq 1 "opts"`
do
opt["nein"]="1"
shift
done
fileid=0
attachments=""
for nein in `seq 1 "opts"`
do
formdata_v2 "fileid" "{opt[nein]}"
let fileid++
done
payload_v2
}
function upload2discord() {
# two modes:
# # webhook mode: 1 = webhook url
# # selfbot mode:1 = auth, #2 = guildid/channelid
if [ "2" ]
then
realchannelid="{2/}"
curl "https://discord.com/api/v9/channels/{2#*/}/messages" -X POST \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0' \
-H 'Accept: */*' \
-H 'Accept-Language: en-US' \
-H "Authorization:1" \
-H "Content-Type: multipart/form-data; boundary=---------------------------delimiter" \
-H 'Origin: https://discord.com' \
-H 'Connection: keep-alive' \
-H "Referer: https://discord.com/channels/2" \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Pragma: no-cache' \
-H 'Cache-Control: no-cache' \
-H 'TE: trailers' \
--data-binary "@-"
else
curl "1" -X POST \
-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0' \
-H 'Accept: */*' \
-H 'Accept-Language: en-US' \
-H "Content-Type: multipart/form-data; boundary=---------------------------delimiter" \
-H 'Origin: https://discord.com' \
-H 'Connection: keep-alive' \
-H 'Sec-Fetch-Dest: empty' \
-H 'Sec-Fetch-Mode: cors' \
-H 'Sec-Fetch-Site: same-origin' \
-H 'Pragma: no-cache' \
-H 'Cache-Control: no-cache' \
-H 'TE: trailers' \
--data-binary "@-"
fi
}
使用的时候,只需要先在formpostdata
后面跟上需要上传的文件路径,要上传几个文件就跟几个(当然,也可以配置成从一个文件里面读取要上传的文件列表),然后加上管道符号,再使用upload2discord
,后面要么跟webhook url,要么跟auth和guildid/channelid
比如formpostdata "/tmp/yajuusenpai.mp4" "/tmp/sandstorm.hakushin.mp4" | upload2discord 'https://discordapp.com/api/webhooks/1145141919810/iiyokoiyoikuikuyajuu'
bruh
实战测试的时候,我发现一个非常蛋疼的问题,webhook没法支持总文件大小太大的上传,它会报错
{"message": "Request entity too large", "code": 40005}
这就非常蛋疼了🤔但这点不影响账号方式,至少nitro账号可以一次性上传200MB的文件,至于上传这么大的一坨文件需要等多长时间我就不清楚了🤔再说了,这算新玩意,我还没测试这玩意能不能多线程呢(悲🤔至于改那个discord drive,我暂时不准备改,那玩意现在还能用🤔