[GWCTF 2019] re3
degrau
- Programa de 64 bits, sem shell, aberto diretamente com ida, primeiro de tudo para recuperar a string no programa
- De acordo com o salto correto para encontrar a função relacionada ao sinalizador, abaixo você pode ver ABC ...... * /, acho que há criptografia base64 no programa
- Não há f5 aqui. Estima-se que o pote jz afetou o funcionamento normal de ida. Primeiro , vamos dar uma olhada na função principal acima,
main (). O
comprimento da string de entrada é de 32 bits. Use a função mprotect para modificar o endereço de comprimento 0xF000 em dword_400000 para Legível, gravável e executável, os dados em sub_402219 () foram XORed. - Pode-se observar que a função sub_402219 () não apenas participa do XOR como dados, mas também é referenciada como uma função, e esta função não pode ser aberta.Após
adivinharmos o XOR, esta função é a função real. Portanto, primeiro restaure os dados em sub_402219 () e
clique diretamente em sub_402219 na parte do pseudo código para pular para seu segmento de dados. Você deve
encontrá- lo no código de montagem e pressionar D para convertê-lo em tipo de dados e
então usar o script idc para restaurar os dados. Primeiro entre em contato com o script idc, basta registrar
primeiro shif + f2 para chamar o editor de script e, em seguida, você pode editar o script idc. A sintaxe é um pouco semelhante a c. Para a sintaxe específica, consulte este artigo e este artigo para
explicar brevemente o método de escrita. Primeiro, defina uma variável local addr, que é a posição inicial dos dados que queremos reparar, i é usado para percorrer e o loop for subsequente copia a função principal, e a última éPatchByte(addr+i,Byte(addr+i)^0x99)
esta frase.
Primeiro, olhe para a gramática do PatchByte, esta frase começa com addr, usa i para percorrer o endereço e define o valor do endereço correspondente para byte_402219 [addr + i] = byte_402219 [addr + i] ^ 0x99
Clique em executar para restaurar o dados
e selecione os dados após a restauração Pressione c, selecione forçar para forçar a execução e converta os dados em código.
Em seguida, pressione p para criar uma função no início do código em 0x402219.
Agora volte e olhe nossa função principal
sub_402219 ( ). Esta função pode ser aberta. O salto na linha 19 é o Baidu. Veja, para ver a neve para uma explicação
Erro de reconhecimento de limite de função, ou
devido a alguns motivos, o compilador irá separar algum código, não armazenado em uma área contínua, mas em outros locais, esses blocos às vezes são reconhecidos por ida, chamados de chunks, e alguns não podem ser reconhecidos. Neste ponto, você mesmo deve configurá-lo manualmente.
Se for um erro de reconhecimento de limite, então alt + p para encontrar o final correto;
se for o último, então adicione a área de destino a esta função por meio de append_func_tail. Além disso, você deve primeiro indefinir a área de destino.
Fui ao Baidu para ver o wp desta questão e descobri que não o afetava, então não continuei a descartá-lo.
-
Continue a olhar para main (), e então chame sub_40207B ()
sub_40207B (), seu parâmetro unk_603170 () não pode ser visto diretamente em ida, e então mova para ver se
sub_40207B () chama a função sub_401CF9, é muito longo, Apenas não postado, de acordo com
o código de recurso da
função , você pode descobrir que este é o código de recurso do algoritmo p273 de criptografia md5 n1book.Esta função executa principalmente a criptografia md5 na tabela base64 duas vezes. -
Depois, há sub_402219 ()
sub_400A71 ().
Primeiro, ele faz um loop 4 vezes como um todo. Ao processar os dados, byte_4023A0 é usado.
De acordo com a imagem no n1book que postei acima, podemos descobrir que este é um s criptografado por AES caixa, então a função desta função é deunk_603170(base64表进行了两次md5加密后的结果)
entrada, pois a chave
sub_40196E () tem o mesmo código de recurso, que deve ser a etapa da criptografia AES, então sua função é usar aunk_603170(上一层传入的base64表进行了两次md5加密后的结果)
chave como a chave para realizar a criptografia AES nos dados nós inserimos e obtemos
após 9 ~ 11 linhas de processamento Pegue os dados em byte_6030a0, extraia os dados em
byte_6030a0 byte_6030a0 = BC0AADC0147C5ECCE0B140BC9C51D52B46B2B9434DE5324BAD7FB4B39CDB4B5B -
Neste ponto, a lógica do programa é esclarecida.
Primeiro, o resultado da tabela base64 sendo criptografada em MD5 duas vezes é passado para unk_603170
unk_603170 e os dados que inserimos são criptografados em AES para obter byte_6030a0
unk_603170. Pode ser ajustado ou MD5 online plataforma de criptografia. Obtenha ou escreva seu próprio script de criptografia md5 e execute-o -
Ajuste o valor de unk_603170 (principalmente porque não consigo obter a chave correta depois de usar a criptografia md5 do site da ferramenta duas vezes, e o python escrito por mim está preso entre a conversão de codificação)
porque é um arquivo elf, então preciso usar um ajuste móvel virtual, sobre como usar o IDA para ajustar o arquivo ELF (usando uma máquina virtual), leia este artigo em detalhes. A
premissa é que a máquina física e a máquina virtual podem pingar uma à outra. Se o ping falhar, redefina a placa de rede da máquina virtual.
Depois de ajustar por um longo tempo, eu finalmente descobri para mim.unk_603170=CB8D493521B47A4CC1AE7E62229266CE
Aqui está um registro das falhas na depuração desta questão.
Em primeiro lugar, você pode ver que o programa pode ignorar esta saída (0), desde que a string de entrada comprimento é 32, mas na operação real, não está funcionando. Minha maneira de ignorar é executar o if para julgar o próximo ponto de interrupção e, em seguida,
definir o próximo ponto de interrupção antes de executar a atribuição para unk_603170 e, em seguida, executar f9 para o primeiro ponto de interrupção e, em seguida, ctrl + f7 para executar o segundo intervalo. Clique em e, em seguida, dê um passo único f8 para unk_603170 para concluir a atribuição, vá para unk_603170. -
Finalmente, use unk_603170 para descriptografar byte_6030a0, a ferramenta online falha ao descriptografar, publica o exp de outro python2 mestre e a conversão codificada com python3 é travada.
from Crypto.Cipher import AES
import codecs
aes = AES.new(decode_hex('CB8D493521B47A4CC1AE7E62229266CE')[0], AES.MODE_ECB)
print(aes.decrypt(decode_hex('BC0AADC0147C5ECCE0B140BC9C51D52B46B2B9434DE5324BAD7FB4B39CDB4B5B')[0]))
sinalizar {924a9ab2163d390410d0a1f670}
Fonte de exp: https://www.cnblogs.com/Mayfly-nymph/p/12829168.html