ASP.NET Session hijacking with Forms authentication 동영상
: http://www.youtube.com/watch?v=DcmUo5FMLyI
Introduction
ASP.NET Session keeps track of the user by creating a cookie called “ASP.NET_SessionId” in the user browser. This cookie value is checked for every request to ensure that the data being served is specific to that user. In many application, Session variable is used to track the logged in user, ie. If a session variable exists for that user then the User is logged in otherwise not.
ASPX PAGE
In the above code snippet, we have two TextBoxes, two Buttons and a Label control.<fieldset>
<legend>Login</legend>
<p>
Username :
<asp:TextBox ID="txtU" runat="server" />
</p>
<p>
Password :
<asp:TextBox ID="txtP" runat="server" />
</p>
<p>
<asp:Button ID="btnSubmit" runat="server" Text="Login" OnClick="LoginMe" />
<asp:Label ID="lblMessage" runat="server" EnableViewState="false" />
<asp:Button ID="btnLogout" runat="server" Text="Logout" OnClick="LogoutMe" Visible="false" />
</p>
</fieldset>
CODE BEHIND
On click of the Login button, LoginMe method fires that creates Session[“LoggedIn”] after validating the TextBoxes value.protected void Page_Load(object sender, EventArgs e)
{
if (Session["LoggedIn"] != null)
{
lblMessage.Text = "Congratulations !, you are logged in.";
lblMessage.ForeColor = System.Drawing.Color.Green;
btnLogout.Visible = true;
}
else
{
lblMessage.Text = "You are not logged in.";
lblMessage.ForeColor = System.Drawing.Color.Red;
}
}
protected void LoginMe(object sender, EventArgs e)
{
// Check for Username and password (hard coded for this demo)
if (txtU.Text.Trim().Equals("u") && txtP.Text.Trim().Equals("p"))
{
Session["LoggedIn"] = txtU.Text.Trim();
}
else
{
lblMessage.Text = "Wrong username or password";
}
}
protected void LogoutMe(object sender, EventArgs e)
{
Session.Clear();
Session.Abandon();
Session.RemoveAll();
}
Output
How to fix this vulnerability
Simple fix
Bullet proof fix
MODIFIED CODE BEHIND
protected void Page_Load(object sender, EventArgs e)
{
//NOTE: Keep this Session and Auth Cookie check condition in your Master Page Page_Load event
if (Session["LoggedIn"] != null && Session["AuthToken"] != null && Request.Cookies["AuthToken"] != null)
{
if (!Session["AuthToken"].ToString().Equals(Request.Cookies["AuthToken"].Value))
{
// redirect to the login page in real application
lblMessage.Text = "You are not logged in.";
}
else
{
lblMessage.Text = "Congratulations !, you are logged in.";
lblMessage.ForeColor = System.Drawing.Color.Green;
btnLogout.Visible = true;
}
}
else
{
lblMessage.Text = "You are not logged in.";
lblMessage.ForeColor = System.Drawing.Color.Red;
}
}
protected void LoginMe(object sender, EventArgs e)
{
// Check for Username and password (hard coded for this demo)
if (txtU.Text.Trim().Equals("u") && txtP.Text.Trim().Equals("p"))
{
Session["LoggedIn"] = txtU.Text.Trim();
// createa a new GUID and save into the session
string guid = Guid.NewGuid().ToString();
Session["AuthToken"] = guid;
// now create a new cookie with this guid value
Response.Cookies.Add(new HttpCookie("AuthToken", guid));
}
else
{
lblMessage.Text = "Wrong username or password";
}
}
protected void LogoutMe(object sender, EventArgs e)
{
Session.Clear();
Session.Abandon();
Session.RemoveAll();
if (Request.Cookies["ASP.NET_SessionId"] != null)
{
Response.Cookies["ASP.NET_SessionId"].Value = string.Empty;
Response.Cookies["ASP.NET_SessionId"].Expires = DateTime.Now.AddMonths(-20);
}
if (Request.Cookies["AuthToken"] != null)
{
Response.Cookies["AuthToken"].Value = string.Empty;
Response.Cookies["AuthToken"].Expires = DateTime.Now.AddMonths(-20);
}
}
LoginMe method
LogoutMe method
Page_Load event (In real time application, keep this logic into the Master Page Page_Load method)
OUTPUT
복사한 사이트 : http://www.codeproject.com/Articles/210993/Session-Fixation-vulnerability-in-ASP-NET
참고 : HTTP Session Hijacking
HTTP 프로토콜의 특성
HTTP는 기본적으로 비연결유지(stateless) 프로토콜이다. 반면, telnet과 ftp와 같은 프로토콜은 클라이언트와 서버 사이에 하나의 연결(session)이 성립되어 통신하는 프로토콜이다. 따라서, 우리가 보통 웹 브라우저를 열어 URL을 입력하고 해당 홈페이지에 들어간다는 것은 해당 홈페이지에 포함되어 있는 페이지(html), 그림(jpg, gif 등), 자바스크립트(js) 등을 다운받기 위해 개별적인 여러 개의 80 요청(request)을 발송한 후 서버로부터 각각의 응답(reply)을 받는 것을 의미한다.
이러한 일련의 요청과 응답이 이루어진 후 해당 서버와의 통신은 다시 종료된다. 위와 같은 기본적인 지식을 알고 있다면 다음과 같은 질문을 할 수 있다. HTTP는 비연결유지 프로토콜이라고 하였는데 Session Hijacking 이란 공격은 어떻게 가능한 것인가? 이는 HTTP 세션 관리를 위해 사용되는 Session ID를 통해서 가능하다.
Session ID란 무엇인가?
웹 서버는 다수의 웹 페이지 요청자를 구별하기 위하여 각각의 사용자의 세션에 대해서 임의의 긴 문자열 값인 Session ID를 부여한다. 사용자가 홈페이지 방문시 혹은 인증 로그인시에 생성된다. 이러한 Session ID는 사용자의 계정, 암호, 그 밖의 IP 주소, timestamp 등의 여러 파라미터들을 조합하여 생성할 수 있다.
Session ID는 사용자와 일련의 웹 서핑 동작을 연결시켜줌으로써 웹 사이트 로그인 후 다른 페이지 방문시마다 매번 로그인을 하지 않아도 되는 편리함을 제공해준다.
우리가 신문 홈페이지나 포털 사이트에 들어갈 때 광고 배너가 자동으로 바뀐다던지, 쇼핑몰이나 인터넷 서적몰에서 구매 카트의 목록이 유지되는 것은 모두 이러한 원리이다. 즉, Session ID를 통해 인증과 인가(authentication
& authorization)라는 세션 관리를 수행할 수 있다.
Session ID는 어디에 존재하는가?
Session ID는 우리가 흔히 듣는 쿠키(cookie)라는 곳에 저장되는 것이 일반적이다. 그러나 가끔은 웹 브라우저 주소창 URL이나 HTML 페이지 폼 소스 상의 hidden 필드에 포함되어 드러나기도 한다.
1) 쿠키
2) 웹 브라우저 주소창의 URL
3) 웹 페이지 폼 소스 상의 hidden field
Session ID의 취약성은 무엇인가?
웹 서버에서의 Session ID 생성 기법 및 관리 기법에 따라서 다음과 같은 취약점이 존재할 수 있다.
위와 같은 취약성에 대한 Session ID 공격의 유형은 다음과 같다.
Session ID 공격유형
지금까지 Session ID가 무엇인지, 어떤 형태로 존재하는지, 왜 취약한지에 대해서 알아보았다. 다음에는 실제 공격 유형에 대해 살펴보고, 대응 방안에 대해서도 논의해 보도록 하겠다.
Session ID 공격 유형
Session ID에 대한 공격은 크게 2 단계로 이루어진다. 1단계는 Session ID 취득 단계이고 2단계는 취득한 Session ID 공략 단계이다.
[그림1] HTTP Session Hijacking 공격 흐름도
공격자는 Session ID를 취득하기 위하여 웹 서버와 웹 클라이언트의 트래픽을 직접적으로 스니핑하거나, 웹 서버 상에 공격 코드를 삽입하여 두고 사용자가 클릭할 때 Cookie, Session ID 값을 전송받을 수 있도록 한다. 웹 서버와 웹 클라이언트 사이의 트래픽을 직접적으로 스니핑하는 방법은 일반적인 네트워크 트래픽 스니핑 기법을 통해 가능하다.
POST /xxxxxx HTTP/1.1Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*Referer: http://xxx.xxx..comAccept-Language: koContent-Type: application/x-www-form-urlencodedAccept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)Host: ibn.kbstar.comContent-Length: 297Connection: Keep-AliveCache-Control: no-cacheCookie: Session=QJ48621878865 |
[그림2] 네트워크 트래픽 스니핑을 통한 HTTP 요청 헤더 안의 쿠키값
웹 서버 상의 HTML 코드 삽입이 가능한 페이지는 주로 사용자가 글을 게시할 수 있는 게시판이나 자료실 등에 존재한다. 정상적인 글을 게재하는 대신 공격자는 HTML 코드 및 스크립트를 심어 넣는다. 일반 사용자는 해당 게시물을 열람하게 될 때 자신도 모르는 사이 Cookie, Session ID 정보가 제 3 의 공격자 서버나 이메일로 전송되게 된다. (이러한 공격 기법을 Cross-Site Scripting이라고 부른다.)
<form name=f method=POST action="http//host/hello.php"><input type=hidden name="name"value="<script>alert(document.cookie)</script>"></form><script>f.submit()</script> |
[그림3] 쿠키값 탈취를 위한 HTML 삽입 코드 예
결과적으로 공격자는 취득한 타인의 Session ID 값을 웹 서버에 요청함으로써 HTTP Session Hijacking 공격을 시도할 수 있다. 물론 이 공격이 성공하려면 Session ID 값이 유효해야 하므로, 사용자가 로그온 한 상태에서 공격이 이루어져야 하거나 Session ID 값의 유지 시간이 긴 경우라는 제한 사항이 필요하다.
그러나, 기본적으로 잘못 설계된 세션 관리 기법을 사용하고 있는 웹 서버는 이러한 Hijacking 공격에 취약할 수 밖에 없다. 굳이 타인의 Session ID 값을 직.간접적으로 취득하지 않고도 무작위 추측 대입(Brute-force Guessing)함으로써 공격이 가능하다. 공격자는 정상적인 로그인 과정시 분석한 자신의 Cookie 값, 웹 브라우저의 주소창의 URL, 웹 페이지 폼 소스 hidden field 내에 노출된 Session ID 값 자체를 분석한다.
Session ID 생성 방식의 취약점을 파악한 후, 공격자의 컴퓨터에서 로컬 프록시 툴이나 웹 브라우저 창 URL 주소창에서 직접 Sessioion ID 값 단일 대입을 시도한다. 더 나아가 자동적인 Session ID 대입 스크립트를 작성하여 공격할 수도 있다.
http://mmail.xxx.co.kr/mletter1/read_mail.asp?id=2266&tableName=musicMail1927&fromEmail=xxx@xxx.co.kr http://www.xxx.co.kr/view/UID2305670410000 http://www.xxx.co.kr/view/UID2305670410341 http://www.xxx.co.kr/view/UID2305670411302 |
[그림4] 정상적인 Session ID 값
http://mmail.xxx.co.kr/mletter1/read_mail.asp?id=3734&tableName=musicMail1927&fromEmail=xxx@xxx.co.kr http://www.xxx.co.kr/view/UID2305670410001 http://www.xxx.co.kr/view/UID2305670410002 http://www.xxx.co.kr/view/UID2305670419999 |
[그림5] 무작위 추측 대입된 Session ID 값
대응 방안
HTTP Session Hijacking 공격에 대하여 웹 어플리케이션 개발자는 다음과 같은 점을 고려하여 세션 관리 기법을 구현하여야 한다.
1. Session ID 생성 범위값을 사용자 수에 대비하여 충분히 큰 값으로 설정한다. 2. Session ID는 가능한 한 추측 불가능(random)하게 생성한다. 무작위 추측 대입 공격을 할 때 공격자는 그만큼 더 많은 시간을 투입하여야 하며 현재 연결되어 활성화 되어 있는 유효한 Session ID 값을 찾는 확률은 낮아진다. 3. Session Timeout 기능과 Session ID 재생성 기능을 사용한다. 일정 시간 동안 활동이 없는 사용자는 새로운 Session ID로 재로그인하도록 하고, 사용자 로그 아웃 시에는 Session ID 값을 폐기한다. 장시간 접속이 필요한 어플리케이션의 경우에는 일정 주기마다 Session ID값을 자동으로 재생성하여 세션을 유지하도록 한다. 4. 무작위 추측 대입(Brute-force Guessing)에 대비하여 일정 회수 이상의 인증 실패시에는 사용자 잠금 기능을 구현한다. 5. 로그인 이후에도 중요한 서비스 이용시에는 사용자 인증을 통하여 인가된 사용자만이 해당 서비스를 이용할 수 있도록 통제한다. 6. Cookie 내용 안의 Session ID와 기타 변수값 자체를 암호화한다. 7. 웹 서비스 자체의 중요성에 따라 Cookie가 전달되는 방식을 SSL로 구현함으로써 스니핑 공격에 대응할 수도 있다. 8. 웹 서비스 상에 공격자가 HTML 공격 코드 삽입이 가능한 페이지가 있는지 점검한다. 직접적인 공격 코드 삽입을 차단할 수 있도록 특수 문자 및 스크립트 코드를 필터링하여야 한다. |
지금까지 HTTP Session Hijacking 공격 기법에 대해서 알아보았다. 대부분이라고 말할 수는 없지만 요즘 인터넷에 서비스되고 있는 인기 있는 웹 컨텐츠 서버는 기본적으로 안전한 세션 관리 기법으로 구현되어 있다. 그러나, 웹 컨텐츠의 인지도와는 별도로 이러한 공격 기법에 대한 인지 없이 비보안적으로 구현된 e-메일 카드 서비스, 전자 앨범 서비스 사이트 등이 다수 존재하는 것 또한 현실이다.
HTTP Session Hijacking공격에 대한 대비는 안전한 웹 어플리케이션 구축을 위한 여러가지 항목 중에 필수적인 한 가지 사항이며, 기획 및 개발구현 단계에서 반드시 고려되어야 한다.
[출처] 코코넛 시큐레터 2004년 5월호