-
Notifications
You must be signed in to change notification settings - Fork 53
Falha ao autenticar requisição #53
Comments
Error: Falha ao autenticar requisição |
O token mais longo que consegui gerar foi esse {
"requestToken": "YW5kcm9pZDtici5jb20uY29ycmVpb3MucHJlYXRlbmRpbWVudG87RjMyRTI5OTc2NzA5MzU5ODU5RTBCOTdGNkY4QTQ4M0I5Qjk1MzU3ODs1LjEuMTQ=",
"data": "05/07/2023 00:00:06",
"sign": "79d6f2e24946a01753cfb2b2b7c67fb4"
} |
@jhowbhz n consegui usar seu token, dá o msm erro. |
Uai, eu acabei de usar aqui normalmente. |
como vc consegue gerar isso? |
Eu consegui usando o proprio APP dos correios, adiantando a hora do Relógio do celular até saber qual era o maximo permitido. Ontem eu achei também a funcao que gera esse código, mas nao conseguir entender, pois nao sou dev java. |
Desconsidere, consegui acessar faltava o Header, mas via código eu consegui acessar tb. Sobre o código java não consegue disponibilizar para nós? talvez alguém aqui entenda |
A parte que eu descompilei é a seguinte: não se é exatamente essa parte, mas foi o mais proximo que eu encontrei. O código abaixo foi retirado da ultima versao do APK public int hashCode() {
String str = this.f12310a;
int hashCode = str == null ? 0 : str.hashCode();
long j9 = this.f12311b;
int i10 = (((hashCode ^ 1000003) * 1000003) ^ ((int) (j9 ^ (j9 >>> 32)))) * 1000003;
f.b bVar = this.f12312c;
return i10 ^ (bVar != null ? bVar.hashCode() : 0);
}
public String toString() {
return "TokenResult{token=" + this.f12310a + ", tokenExpirationTimestamp=" + this.f12311b + ", responseCode=" + this.f12312c + "}";
} Pedi o GPT para me explicar mais ou menos o que é esse código, veja o que ele disse: O código fornecido não gera um token. Em vez disso, os métodos hashCode() e toString() são implementações padrão usadas para gerar um valor de hash e uma representação de string de um objeto em Java. O método hashCode() é usado para gerar um valor único de hash para o objeto com base em seus atributos. Nesse caso, ele está calculando um valor de hash combinando o hash do atributo f12310a (convertido em um inteiro usando hashCode()) com o hash do atributo f12311b (convertido em um inteiro de 64 bits). O método toString() retorna uma representação em string do objeto. Nesse caso, ele está concatenando os valores dos atributos f12310a, f12311b e f12312c em uma string formatada. Portanto, esses métodos são usados para calcular o hash e fornecer uma representação em string de um objeto da classe TokenResult, mas não geram um token real. |
Acho que precisaria saber também como são valorezidas as variáveis f12310a, f12310b e f12310c |
Essa é a classe completa. package m6;
import m6.f;
/* loaded from: classes.dex */
final class b extends f {
/* renamed from: a reason: collision with root package name */
private final String f12310a;
/* renamed from: b reason: collision with root package name */
private final long f12311b;
/* renamed from: c reason: collision with root package name */
private final f.b f12312c;
/* renamed from: m6.b$b reason: collision with other inner class name */
/* loaded from: classes.dex */
static final class C0154b extends f.a {
/* renamed from: a reason: collision with root package name */
private String f12313a;
/* renamed from: b reason: collision with root package name */
private Long f12314b;
/* renamed from: c reason: collision with root package name */
private f.b f12315c;
@Override // m6.f.a
public f a() {
String str = "";
if (this.f12314b == null) {
str = " tokenExpirationTimestamp";
}
if (str.isEmpty()) {
return new b(this.f12313a, this.f12314b.longValue(), this.f12315c);
}
throw new IllegalStateException("Missing required properties:" + str);
}
@Override // m6.f.a
public f.a b(f.b bVar) {
this.f12315c = bVar;
return this;
}
@Override // m6.f.a
public f.a c(String str) {
this.f12313a = str;
return this;
}
@Override // m6.f.a
public f.a d(long j9) {
this.f12314b = Long.valueOf(j9);
return this;
}
}
private b(String str, long j9, f.b bVar) {
this.f12310a = str;
this.f12311b = j9;
this.f12312c = bVar;
}
@Override // m6.f
public f.b b() {
return this.f12312c;
}
@Override // m6.f
public String c() {
return this.f12310a;
}
@Override // m6.f
public long d() {
return this.f12311b;
}
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof f) {
f fVar = (f) obj;
String str = this.f12310a;
if (str != null ? str.equals(fVar.c()) : fVar.c() == null) {
if (this.f12311b == fVar.d()) {
f.b bVar = this.f12312c;
f.b b10 = fVar.b();
if (bVar == null) {
if (b10 == null) {
return true;
}
} else if (bVar.equals(b10)) {
return true;
}
}
}
return false;
}
return false;
}
public int hashCode() {
String str = this.f12310a;
int hashCode = str == null ? 0 : str.hashCode();
long j9 = this.f12311b;
int i10 = (((hashCode ^ 1000003) * 1000003) ^ ((int) (j9 ^ (j9 >>> 32)))) * 1000003;
f.b bVar = this.f12312c;
return i10 ^ (bVar != null ? bVar.hashCode() : 0);
}
public String toString() {
return "TokenResult{token=" + this.f12310a + ", tokenExpirationTimestamp=" + this.f12311b + ", responseCode=" + this.f12312c + "}";
}
}``` |
Olha o que o GPT disse sobre esta classe: Claro! Esta é uma classe b que estende a classe abstrata f. Ela contém três campos privados: f12310a, f12311b e f12312c. Os campos f12310a e f12311b são do tipo String e long, respectivamente, enquanto o campo f12312c é do tipo f.b. A classe também contém um construtor privado que inicializa esses campos. A classe b também inclui uma classe interna estática C0154b, que implementa a interface abstrata f.a. Essa classe interna é usada para construir instâncias da classe b. A classe b implementa os métodos abstratos da classe f, que incluem b(), c() e d(). Ela também inclui implementações dos métodos equals(), hashCode() e toString(). Esses métodos são usados para comparar e representar objetos da classe b. Em resumo, a classe b representa um resultado de token de autenticação com um token de autenticação, um carimbo de data/hora de expiração do token e um código de resposta. A classe interna C0154b é usada para construir instâncias de b. Acho que precisavamos da classe f também :( |
Eu consigo pegar qualquer classe la no APP, só falar... rsrs mas eu realmente nao manjo nada de JAVA/Kotlin. Sabe o que eu acho engraçado, é: por que esse token aqui não expira? {
"requestToken": "YW5kcm9pZDtici5jb20uY29ycmVpb3MucHJlYXRlbmRpbWVudG87RjMyRTI5OTc2NzA5MzU5ODU5RTBCOTdGNkY4QTQ4M0I5Qjk1MzU3ODs1LjEuMTQ=",
"data": "04/07/2023 17:39:44",
"sign": "bd2401834330086b78386c036b3936ab"
} |
A grande questão é: O app é feito em flutter, então a parte de gerar o token muito provavelmente ta dentro do binario do flutter (libapp.so). Esses metodos de token provavelmente são de alguma biblioteca nativa do android, creio que não tenha relação com o token que estamos procurando. Lembrando que uma app flutter para android consiste em uma casca nativa (java) e um binario que é carregado na abertura do app (libapp.so) |
@jhowbhz precisamos da classe f |
@jhowbhz gostaria de pedir também todas as referências a palavra “C0154b” no código. Teria como você hospedar esse código completo em algum lugar pra gente poder ver melhor. Eu sei ler o código mas não tenho android nem debug setup para android. |
Vou subir pro meu github pra gente estudar o apk deles, breve posto aqui |
Resolvido. |
|
mito demais |
Bonito não ficou, mas está funcionando. vlw demais!!! var m = new Date();
var data =
("0" + m.getDate()).slice(-2) +
"/" +
("0" + (m.getMonth() + 1)).slice(-2) +
"/" +
m.getFullYear() +
" " +
("0" + m.getHours()).slice(-2) +
":" +
("0" + m.getMinutes()).slice(-2) +
":" +
("0" + m.getSeconds()).slice(-2);
const sign = crypto
.createHash("md5")
.update(`requestToken${l}data${data}`)
.digest("hex");
console.log(l, data, sign);
u(s.PROXYAPP_TOKEN, {
method: "POST",
headers: {
"content-type": "application/json",
"user-agent": "Dart/3.0 (dart:io)",
},
data: {
requestToken: l,
data,
sign,
},
}) |
@tegila Que tal assim?
|
Solução em Kotlin:
|
Eu criaria uma funçao para gerar o sign e resetaria o sign toda vez que desse um erro na requisiçao fun generateSign(token: String): Pair<String, String> {
val data = LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"))
val sign = MessageDigest
.getInstance("MD5")
.digest("requestToken$token$data$data".toByteArray())
.joinToString("") { "%02x".format(it) }
return Pair(data, sign)
}
fun getToken(client: Any, requestToken: String): String? {
for (i in 1..10) {
val (data, sign) = generateSign(requestToken)
val payload = mapOf(
"requestToken" to requestToken,
"data" to data,
"sign" to sign
)
val headers = mapOf(
"content-type" to "application/json",
"user-agent" to "Dart/3.0 (dart:io)"
)
val response = post(
"https://proxyapp.correios.com.br/v2/app-validation",
headers = headers,
json = payload
)
if (response.statusCode == 201) {
val token = response.jsonObject.getString("token")
if (token != null) {
return token
}
} else {
println("Algo deu errado na requisição dos Correios: ${response.statusCode}: ${response.text} na data $data")
}
delay(1000)
}
throw Exception("Não foi possível obter um token válido nos Correios")
} |
repliquei esta solução aqui e está funcional, quem quiser utilizar: https://github.com/ferezini/Correios-Brasil/tree/atu-correios/ |
Acabei de fazer esse exemplo também funcional na minha API, o exemplo está em python, se alguem precisar. import hashlib
token = "YW5kcm9pZDtici5jb20uY29ycmVpb3MucHJlYXRlbmRpbWVudG87RjMyRTI5OTc2NzA5MzU5ODU5RTBCOTdGNkY4QTQ4M0I5Qjk1MzU3ODs1LjEuMTQ="
data = datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S")
hash_object = hashlib.md5()
hash_object.update(f"requestToken{token}data{data}".encode())
sign = hash_object.hexdigest()
print(sign) |
Poderia depois por favor, explicar como chegou a essa conclusão, ficaria grato. |
pelo que entendi o sign deles nada mais é do que o MD5 do token combinado com a data |
Mas eu acho que ele quer saber como o rapaz descobriu isso. |
Exatamente kkk essa é a chave da questão, literalmente.... kkkk |
Acho que vai ficar um pouco desapontado com a resposta, mas a versão resumida é que foi no chute mesmo. Eu tava travado nesse problema para resolver o RastreioBot e, obviamente, não conseguia reverter o hash. |
Gente, boa noite. Subi a nova versão com as alterações de vocês, quando tiver mais tempo vou reescrever toda essa parte para deixar mais simples. Obrigado pela ajuda de vocês, abraços. |
e os correios ataca novamente... Agora na terceira tentativa, temos um hash unico e maior.
|
aqui eu desde ontem nao consigo obter o token valido Alguem tá conseguindo usar o token? |
Provavelmente mudaram o APP. Vai precisar de algum ninja pra decompilar o flutter de novo e encontrar onde está a mudança que cria o hash novo. |
sim import encodings List all available encodings in Python's standard libraryall_encodings = encodings.aliases.aliases.values() Remove duplicatesall_encodings_unique = list(set(all_encodings)) Function to try all available encodingsdef try_decode_all_encodings(token_base64):
Try decoding the example token with all available encodingsdecoded_str_all_encodings_example = try_decode_all_encodings(REQUEST_TOKEN) Showing a subset for brevitysubset_results = {k: decoded_str_all_encodings_example[k] for k in list(decoded_str_all_encodings_example.keys())[:10]} ['mac_roman', 'cp850', 'quopri_codec', 'cp437', 'iso8859_14', 'euc_jp', 'utf_32_le', 'iso2022_jp_2', 'gb2312', 'gb18030', 'latin_1', 'mac_cyrillic', 'cp1252', 'big5', 'hz', 'tis_620', 'utf_16_le', 'cp1125', 'iso8859_15', 'uu_codec', 'shift_jis', 'euc_jis_2004', 'iso8859_2', 'cp1256', 'iso8859_7', 'utf_32_be', 'cp861', 'iso8859_3', 'johab', 'cp1254', 'cp852', 'koi8_r', 'cp1257', 'cp855', 'mac_turkish', 'iso8859_11', 'utf_7', 'cp932', 'iso2022_jp_2004', 'iso8859_16', 'mac_latin2', 'bz2_codec', 'cp1140', 'cp1251', 'cp1258', 'base64_codec', 'cp037', 'cp273', 'cp863', 'ptcp154', 'big5hkscs', 'cp1253', 'cp775', 'utf_16_be', 'cp950', 'gbk', 'rot_13', 'shift_jis_2004', 'iso8859_9', 'cp862', 'cp1255', 'iso2022_jp', 'iso8859_5', 'cp424', 'mbcs', 'hex_codec', 'cp860', 'iso8859_4', 'cp858', 'cp866', 'mac_iceland', 'iso2022_jp_1', 'euc_jisx0213', 'kz1048', 'cp500', 'hp_roman8', 'iso8859_6', 'iso8859_10', 'utf_32', 'cp949', 'euc_kr', 'cp864', 'iso8859_13', 'iso2022_jp_3', 'cp869', 'iso8859_8', 'cp1250', 'utf_16', 'cp1026', 'utf_8', 'ascii', 'iso2022_kr', 'mac_greek', 'zlib_codec', 'iso2022_jp_ext', 'shift_jisx0213', 'cp865', 'cp857'] retornou isso dai NO token antigo ['iso8859_8', 'iso8859_14', 'cp1125', 'utf_32_be', 'cp037', 'mbcs', 'cp1255', 'mac_greek', 'latin_1', 'base64_codec', 'cp1252', 'ptcp154', 'gb18030', 'hz', 'koi8_r', 'iso2022_jp_2', 'cp863', 'iso2022_jp', 'uu_codec', 'iso8859_6', 'cp855', 'utf_16_be', 'iso8859_9', 'cp500', 'cp864', 'iso8859_5', 'mac_latin2', 'iso8859_4', 'ascii', 'iso2022_jp_2004', 'shift_jis', 'iso8859_13', 'iso8859_15', 'shift_jis_2004', 'tis_620', 'euc_jisx0213', 'cp950', 'utf_16_le', 'iso8859_11', 'cp1256', 'cp850', 'cp869', 'iso2022_jp_ext', 'mac_roman', 'cp932', 'hp_roman8', 'euc_jp', 'cp1257', 'cp1250', 'iso8859_16', 'iso2022_jp_1', 'utf_16', 'cp1254', 'cp1140', 'kz1048', 'euc_jis_2004', 'gbk', 'bz2_codec', 'cp775', 'rot_13', 'mac_iceland', 'cp949', 'big5hkscs', 'cp273', 'cp865', 'cp852', 'johab', 'iso8859_3', 'cp437', 'utf_32_le', 'mac_cyrillic', 'mac_turkish', 'cp1253', 'iso8859_7', 'cp861', 'cp857', 'quopri_codec', 'utf_32', 'shift_jisx0213', 'utf_8', 'cp862', 'iso8859_10', 'cp424', 'cp1251', 'cp1258', 'iso8859_2', 'euc_kr', 'iso2022_kr', 'iso2022_jp_3', 'cp858', 'utf_7', 'cp860', 'cp866', 'big5', 'cp1026', 'hex_codec', 'zlib_codec', 'gb2312'] |
Acredito que isso não tem relevância. "Só" precisa decompilar o apk de novo e encontrar o trecho de código que monta o request. Já fizeram isso na v2, resta esperar alguém fazer pra gente na v3. Talvez o @jhowbhz consiga encontrar de novo como já fez antes |
mas esse token funciona So mudar de V2 pra V3 na autenticaçao " Cannot connect to host proxyapp.correios.com.br:443 ssl:default [Não há endereço associado com o nome]" |
Era uma grande possibilidade kkkkkk |
Rodei o jadx aqui num apk que baixei da net, não encontrei nada de v3 no app. Consegui encontrar o método antigo que gerava o hash que postaram aqui. Mas nada dessa v3. Talvez o app nao esteja atualizado ou eu não sei procurar. Nao manjo mt de eng reversa mobile =/ |
POST: Body:
|
Como gera esse token? Não conseguiu encontrar? |
Eu pego no APK deles... hueuheuhuheuhe |
Aaa pode crer, usando aquele programinha la pra interceptar as requests. Verdade. Mas aqui num ta rolando =/ |
essa ta boa |
Ta de boa mesmo, tava faltando o User-Agent na requisição. Ta safe mesmo. O foda é quando esse requestToken não for mais válido auhauh |
Esse momento chegou.. |
o token só dura 24 horas, se gerar com um dia a frente ele chega a durar 48 horas |
esse aqui vai expirar dia 01 as 11am
|
o legal era voces passarem como encontra o token |
O token não é gerado com o requestToken? Antes (no v2/app-validation) usando o data e o sign e aparentemente mudaram o endereço (v3/app-validation agora) e um novo requestToken que aparentemente é fixo no cód. |
@tecomanow É exatamente do |
pessoal, criei um slack sobre este assunto, quem quiser entrar https://join.slack.com/t/novoworkspace-gy79184/shared_invite/zt-22d38753o-EhySiuK76VOK~GSeyFwENg |
O problema é que tem que fazer engenharia reversa do app. E parece que não é todo mundo que sabe... Ninguém ta escondendo nada aqui não kkk Muito pelo contrário, diga-se de passagem. Pra pegar o token tem instrução aqui: #49 (comment) Agora, isso não é viavel em nenhum cenário imaginável. Enquanto alguém não conseguir debugar o app vai ter que sempre fazer esse processo manual. |
Aparentemente o erro da semana retrasada retornou, provavelmente aquele token expirou.
The text was updated successfully, but these errors were encountered: