Ребят привет. Почитал вот это BitTorrent ботнет - от дизайна до реализации, а так же вот это bep_0005.html и вот это bep_0044.html.
Язык программирования не принципиален, тут важнее реализация идеи. Я попробовал сделать это на голанге. Получилось примерно так:
Вкратце, шерстим нужный TargetID методом find_node, набиваем таблицу alive_dht_table и после сортировки по "расстоянию" начинаем крепить данные в сети.
Так вот, эта конструкция для связки get_peers/announce_peer (bep_0005) прекрасно работает. А вот для связки get/put (bep_0044) нихрена не работает.
Большая часть узлов возвращает "203 invalid token" хотя токен я беру из запроса get секунду назад, source порт тотже самый для обоих запросов.
Сильно меньшая часть узлов вроде как принимает данные, но при повторном запросе возвращают пустую строку там где должны быть данные. Даже без предварительной публикации они возвращают эту пустую строку, будто какая-то тупая заглушка стоит на эту часть протокола.
Кто нибудь пробовал с этим работать? Может есть какие-то мысли или опыт? Я пока склоняюсь к тому, что протокол вроде есть, базовые его моменты соблюдаются, а расширения вроде "Storing and retrieving of arbitrary data in the BitTorrent DHT" тупо игнорятся т.к. не обязательны для существования сети.
Язык программирования не принципиален, тут важнее реализация идеи. Я попробовал сделать это на голанге. Получилось примерно так:
Код:
salt := "zalupen"
seq := int64(0)
value := "1234"
dht_self_id = make([]byte, 20)
rand.Read(dht_self_id)
priv_seed := []byte{199,132,99,87,240,13,35,250,184,120,104,112,127,97,223,146,150,39,2,91,85,58,169,197,96,171,153,222,56,102,115,145}
priv := ed25519.NewKeyFromSeed(priv_seed)
pub, _ := priv.Public().([]byte)
target_buf := bytes.NewBuffer(pub)
target_buf.Write([]byte(salt))
t := sha1.Sum(target_buf.Bytes())
target := t[:]
dht_find_node_recursion("87.98.162.88:6881", target)
sort.Slice(alive_dht_table, func(i, j int) bool { return alive_dht_table[i].distance < alive_dht_table[j].distance })
b := fmt.Sprintf("4:salt%d:%s3:seqi%de1:v%d:%s", len(salt), salt, seq, len(value), value)
sign, _ := priv.Sign(nil, []byte(b), &ed25519.Options{
Context: "Example_ed25519ctx",
})
req_get := dht_req{
A: dht_req_a{
Id: string(dht_self_id),
Seq: seq,
Target: string(target),
},
T: "aa",
Y: "q",
Q: "get",
}
req_put := dht_req{
A: dht_req_a{
Id: string(dht_self_id),
K: string(pub),
Salt: salt,
Seq: seq,
Sig: string(sign),
//Token: string(),
V: value,
},
T: "aa",
Y: "q",
Q: "put",
}
tid := make([]byte, 4)
for i, _ := range alive_dht_table {
rand.Read(tid)
req_get.T = string(tid)
resp, err := dht_send_req(alive_dht_table[i].ip, req_get)
if err != nil {
fmt.Println(err)
continue
}
fmt.Printf("%T %v\n", resp.R.V, resp.R.V)
if len(resp.E) > 0 {
if code, ok := resp.E[0].(int64); ok {
if str, ok := resp.E[1].(string); ok {
fmt.Fprintf(color.Output, "%s return error %d %s\n", yellow(alive_dht_table[i].ip), code, str)
continue
}
}
}
if len(resp.R.Token) == 0 {
continue
}
req_put.A.Token = resp.R.Token
fmt.Println("put token", hex.EncodeToString([]byte(req_put.A.Token)))
rand.Read(tid)
req_put.T = string(tid)
resp, err = dht_send_req(alive_dht_table[i].ip, req_put)
if err != nil {
fmt.Println(err)
continue
}
if len(resp.E) > 0 {
if code, ok := resp.E[0].(int64); ok {
if str, ok := resp.E[1].(string); ok {
fmt.Fprintf(color.Output, "%s return error %d %s\n", yellow(alive_dht_table[i].ip), code, str)
continue
}
}
}
fmt.Fprintf(color.Output, "%s store success\n", green(alive_dht_table[i].ip))
}
Вкратце, шерстим нужный TargetID методом find_node, набиваем таблицу alive_dht_table и после сортировки по "расстоянию" начинаем крепить данные в сети.
Так вот, эта конструкция для связки get_peers/announce_peer (bep_0005) прекрасно работает. А вот для связки get/put (bep_0044) нихрена не работает.
Большая часть узлов возвращает "203 invalid token" хотя токен я беру из запроса get секунду назад, source порт тотже самый для обоих запросов.
Сильно меньшая часть узлов вроде как принимает данные, но при повторном запросе возвращают пустую строку там где должны быть данные. Даже без предварительной публикации они возвращают эту пустую строку, будто какая-то тупая заглушка стоит на эту часть протокола.
Кто нибудь пробовал с этим работать? Может есть какие-то мысли или опыт? Я пока склоняюсь к тому, что протокол вроде есть, базовые его моменты соблюдаются, а расширения вроде "Storing and retrieving of arbitrary data in the BitTorrent DHT" тупо игнорятся т.к. не обязательны для существования сети.
Последнее редактирование: