development

PHP 세션 수정 / 하이재킹

big-blog 2020. 6. 16. 07:52
반응형

PHP 세션 수정 / 하이재킹


PHP 세션 수정 및 하이재킹과 이러한 문제를 방지하는 방법에 대해 더 많이 이해하려고합니다 . Chris Shiflett 웹 사이트에서 다음 두 기사를 읽었습니다.

그러나 제대로 이해하고 있는지 잘 모르겠습니다.

세션 수정을 막기 위해 session_regenerate_id (true)를 호출하는 것으로 충분합니다. 누군가를 성공적으로 로그인 한 후? 나는 그것을 올바르게 이해한다고 생각합니다.

또한 세션 하이재킹을 방지하기 위해 $ _GET을 통해 URL로 전달 된 토큰을 사용하는 방법에 대해서도 설명합니다. 이것이 어떻게 정확하게 이루어 집니까? 누군가 로그인하면 토큰을 생성하여 세션 변수에 저장 한 다음 각 페이지에서 해당 세션 변수를 $ _GET 변수의 값과 비교할 것 같아요?

이 토큰은 세션 당 또는 페이지로드마다 한 번만 변경해야합니까?

또한 URL에 값을 전달하지 않고 도용을 방지하는 좋은 방법입니까? 이것은 훨씬 쉬울 것입니다.


좋아, 별개의 두 가지 관련 문제가 있으며 각각 다르게 처리됩니다.

세션 고정

공격자가 사용자 세션의 세션 식별자를 명시 적으로 설정하는 곳입니다. 일반적으로 PHP에서는 URL과 같은 URL을 제공하여 수행됩니다 http://www.example.com/index...?session_name=sessionid. 공격자가 클라이언트에 URL을 제공하면 세션 하이재킹 공격과 동일합니다.

세션 고정을 방지하는 몇 가지 방법이 있습니다 (모두 수행).

  • 파일 session.use_trans_sid = 0에서 설정 php.ini하십시오. 이것은 PHP에게 URL에 식별자를 포함하지 말고 식별자에 대한 URL을 읽지 말라고 지시합니다.

  • 파일 session.use_only_cookies = 1에서 설정 php.ini하십시오. 이것은 세션 식별자와 함께 URL을 사용하지 않도록 PHP에 지시합니다.

  • 세션 상태가 변경 될 때마다 세션 ID를 재생성하십시오. 이는 다음 중 하나를 의미합니다.

    • 사용자 인증
    • 세션에 민감한 정보 저장
    • 세션에 대한 변경
    • 기타...

세션 도용

공격자가 세션 식별자를 보유하고 해당 사용자 인 것처럼 요청을 보낼 수있는 곳입니다. 이는 공격자가 식별자를 가지고 있기 때문에 서버와 관련하여 유효한 사용자와 구분할 수는 없습니다.

세션 하이재킹을 직접 방지 할 수는 없습니다. 그러나 사용하기 매우 어렵고 어렵게하기위한 단계를 수행 할 수 있습니다.

  • 강력한 세션 해시 식별자를 사용 session.hash_function에서 php.ini. PHP <5.3 인 경우 session.hash_function = 1SHA1으로 설정하십시오 . PHP> = 5.3 인 경우 session.hash_function = sha256또는로 설정하십시오 session.hash_function = sha512.

  • 강력한 해시 보내기 session.hash_bits_per_character에서 php.ini. 이것을로 설정하십시오 session.hash_bits_per_character = 5. 이것은 크랙 하기 어렵지 않지만 공격자가 세션 식별자를 추측하려고 할 때 차이를 만듭니다. ID는 짧지 만 더 많은 문자를 사용합니다.

  • 함께 추가 엔트로피를 설정 session.entropy_file하고 session.entropy_length당신의 php.ini파일. 전자를 session.entropy_file = /dev/urandom엔트로피 파일에서 읽을 바이트 수로 설정합니다 session.entropy_length = 256.

  • 기본 PHPSESSID에서 세션 이름을 변경하십시오. 이는 호출 session_name()하기 전에 첫 번째 매개 변수로 고유 한 식별자 이름으로 호출 하여 수행됩니다 session_start.

  • 당신이 경우 정말 너무 세션 이름을 회전하지만 (당신은 시간에 의존 할 경우, 예를 들어)이을 변경하면 모든 세션이 자동으로 무효화 될 것으로 조심 수 편집증. 그러나 사용 사례에 따라 옵션 일 수 있습니다 ...

  • 세션 식별자를 자주 회전하십시오. 모든 요청 ( 이러한 수준의 보안 실제로 필요한 경우가 아니라면 )을 수행하지는 않지만 임의의 간격으로 수행합니다. 공격자가 세션을 가로 채면 너무 오랫동안 세션을 사용할 수 없기 때문에 자주 변경하려고합니다.

  • 세션에 사용자 에이전트를$_SERVER['HTTP_USER_AGENT'] 포함시킵니다 . 기본적으로 세션이 시작되면 다음과 같은 곳에 저장하십시오 $_SESSION['user_agent']. 그런 다음 각 후속 요청에서 일치하는지 확인하십시오. 이것은 가짜 일 수 있으므로 100 % 신뢰할 수는 없지만 그렇지 않은 것이 좋습니다.

  • 세션 에서 사용자의 IP 주소를$_SERVER['REMOTE_ADDR'] 포함하십시오 . 기본적으로 세션이 시작되면 다음과 같은 곳에 저장하십시오 $_SESSION['remote_ip']. 사용자에 대해 여러 IP 주소를 사용하는 일부 ISP (예 : AOL에 사용 된)에서 문제가 될 수 있습니다. 그러나 사용하면 훨씬 더 안전합니다. 공격자가 IP 주소를 위조하는 유일한 방법은 실제 사용자와 사용자 사이의 어느 시점에서 네트워크를 손상시키는 것입니다. 또한 네트워크를 손상 시키면 하이재킹 (MITM 공격 등)보다 훨씬 나빠질 수 있습니다.

  • 자주 증가하고 비교하는 세션 및 브라우저 측에 토큰을 포함하십시오. 기본적으로 각 요청 $_SESSION['counter']++에 대해 서버 측에서 수행하십시오. 또한 브라우저 측의 JS에서 동일한 작업을 수행하기 위해 로컬 저장소를 사용하여 무언가를하십시오. 그런 다음 요청을 보낼 때 간단히 토큰을 가져 와서 서버에서 해당 토큰이 동일한 지 확인하십시오. 이렇게하면 공격자가 정확한 카운터를 가지지 못하기 때문에 하이재킹 된 세션을 탐지 할 수 있어야합니다. 그렇지 않은 경우 2 개의 시스템이 동일한 수를 전송하고 하나의 시스템이 위조되었음을 알 수 있습니다. 모든 응용 프로그램에서 작동하지는 않지만 문제를 해결하는 한 가지 방법입니다.

둘에 대한 메모

세션 고정과 하이재킹의 차이점은 세션 식별자가 어떻게 손상되는지에 대한 것입니다. 수정시 식별자는 공격자가 미리 알고있는 값으로 설정됩니다. 하이재킹에서는 사용자가 추측하거나 도난당했습니다. 그렇지 않으면 식별자가 손상되면 두 가지의 효과는 동일합니다.

세션 ID 재생성

session_regenerate_id이전 세션을 사용하여 세션 식별자를 재생성 할 때마다 삭제해야합니다. 이것은 코어 세션 핸들러에서 투명하게 발생합니다. 그러나 일부 사용자 지정 세션 처리기session_set_save_handler() 는이 작업 수행하지 않으며 이전 세션 식별자를 공격 할 수 있습니다. 사용자 정의 세션 핸들러를 사용중인 경우, 열려있는 식별자를 추적하고, 저장 한 식별자와 동일하지 않은 경우 이전 식별자에서 명시 적으로 식별자를 삭제 (또는 변경)해야합니다.

Using the default session handler, you're fine with just calling session_regenerate_id(true). That will remove the old session information for you. The old ID is no longer valid and will cause a new session to be created if the attacker (or anyone else for that matter) tries to use it. Be careful with custom session handlers though....

Destroying a Session

If you're going to destroy a session (on logout for example), make sure you destroy it thoroughly. This includes unsetting the cookie. Using session_destroy:

function destroySession() {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );
    session_destroy();
}

Both session attacks have the same goal: Gain access to a legitimate session of another user. But the attack vectors are different:

  • In a Session Fixation attack, the attacker already has access to a valid session and tries to force the victim to use this particular session.

  • In a Session Hijacking attack, the attacker tries to get the ID of a victim’s session to use his/her session.

In both attacks the session ID is the sensitive data these attack are focused on. So it’s the session ID that needs to be protected for both a read access (Session Hijacking) and a write access (Session Fixation).

The general rule of protecting sensitive data by using HTTPS applies in this case, too. Additionally, you should to do the following:

To prevent Session Fixation attacks, make sure that:

To prevent Session Hijacking attacks, make sure that:

To prevent both session attacks, make sure that:

  • to only accept sessions that your application have initiated. You can do this by fingerprinting a session on initiation with client specific information. You can use the User-Agent ID but don’t use the remote IP address or any other information that might change from between requests.
  • to change the session ID using session_regenerate_id(true) after an authentication attempt (true only on success) or a change of privileges and destroy the old session. (Make sure to store any changes of $_SESSION using session_write_close before regenerating the ID if you want to preserved the session associated to the old ID; otherwise only the session with the new ID will be affected by those changes.)
  • to use a proper session expiration implementation (see How do I expire a PHP session after 30 minutes?).

The tokens you mention are a "nonce" - number used once. They don't necessarily have to be used only once, but the longer they're used, the higher the odds that the nonce can be captured and used to hijack the session.

Another drawback to nonces is that it's very hard to build a system that uses them and allows multiple parallel windows on the same form. e.g. the user opens two windows on a forum, and starts working on two posts:

window 'A' loads first and gets nonce 'P'
window 'B' loads second and gets nonce 'Q'

If you have no way of tracking multiple windows, you'll only have stored one nonce - that of window B/Q. When the user then submits their post from window A and passes in nonce 'P', ths system will reject the post as P != Q.


I did not read Shiflett's article, but I think you have misunderstood something.

By default PHP passes the session token in the URL whenever the client does not accept cookies. Oherwise in the most common case the session token is stored as a cookie.

This means that if you put a session token in the URL PHP will recognize it and try to use it subsequently. Session fixation happens when someone creates a session and then tricks another user to share the same session by opening a URL which contains the session token. If the user authenticates in some way, the malicious user then knows the session token of an authenticated one, who might have different privileges.

As I'm sure Shiflett explains, the usual thing to do is to regenerate a different token each time the privileges of a user change.


Yes you could prevent session fixation by regenerating the session id once upon login. This way if the attacker will not know the cookie value of the newly authenticated session. Another approach which totally stops the problem is set session.use_only_cookies=True in your runtime configuration. An attacker cannot set the value of a cookie in the context of another domain. Session fixation is relying on sending the cookie value as a GET or POST.

참고URL : https://stackoverflow.com/questions/5081025/php-session-fixation-hijacking

반응형