프롤로그
시간이 부족해
문제
https://dreamhack.io/wargame/challenges/343
코드는 따로 주어지지 않았다
코드
처음 입장했을 때 이렇게 존재하고, 소스코드는
<head>
<title>Tmitter</title>
<style>
* {margin:0px; padding:0px;}
body {text-align:center;}
.banner {background-color:#eef; height:200px;}
.cont {padding:80px;font-size:20pt;}
.cont input {background-color:#eea; width:170px; height:80px; font-size:12pt;}
#loginform {display:none; position:absolute; top:200px; left:100px;}
#loginform table {background-color:#dde; border:1px solid #ccd;}
#loginform td {text-align:center;}
#loginform input {width:100px;}
</style>
<script>
function loginf(){
var ab=document.getElementById("loginform");
//ab.style.left=event.x;
ab.style.left=0;
//ab.style.top=event.y;
ab.style.top=0;
ab.style.display="block";
}
</script>
</head>
<body>
<div class="banner">
<img src="./tmitter.png" width=400><br /><br />
<h1>TMITTER is <s>not</s> fake twitter! :p</h1>
</div>
<div class="cont">
have an account? <input type="button" onclick="loginf();" value="Sign in">
</div>
<div><hr /></div>
<div class="cont">
New to Tmitter? <input type="button" onclick="window.location='./join.php';" value="Sign Up">
</div>
<div id="loginform">
<form method="post" action="./tmitter.php">
<table>
<tr><td>ID</td><td><input type="text" name="id" maxlength="32"></td></tr>
<tr><td>PS</td><td><input type="password" name="ps" maxlength="32"></td></tr>
<tr><td colspan=2><input type="submit" value="login"></td></tr>
</table>
</form>
</div>
</body>
여기서 확인할 수 있다.
그리고 문제조건에서 나온
you need login with "admin"s id!
===========================
create table tmitter_user(
idx int auto_increment primary key,
id char(32),
ps char(32)
);
이 부분
풀이전략
char과 varchar의 차이를 알아야 한다
CHAR | VARCHAR |
고정 길이 문자형 타입 | 가변 길이 문자형 타입 |
테이블 생성 시 지정된 고정 길이만큼 공간 차지 | 입력된 문자열의 길이에 따라 공간이 할당 |
char(10)으로 선언되었을 때 abc를 입력하면 "abc "로 저장 | varchar(10)으로 선언되었을 때 abc를 입력하면 "abc"만 저장 |
고정된 길이 데이터를 사용하기에 전화번호, 고정된 Id 저장할 때 유리 | 메모리 절약 가능하며, 문자열의 길이가 다양하게 바뀌는 데이터에 유리 |
조회할 때 속도 면에서 유리 | 데이터 길이 추적하는 메타 데이터 필요, 메모리 오버헤드 |
만약에 둘 다 "admin 123" 이 아이디로 회원가입을 진행한다면?
32글자가 초과되는 뒷부분은 전부 사라진 채로 "admin "이 데이터베이스에 저장이 된다.
만약에 기존에 admin으로 저장이 먼저 되어있었더라면...
char 의 경우 기존에 admin 계정은 "admin "
varchar의 경우 기존에 admin계정은 그대로 "admin"으로 저장이 된다.
즉 admin 123으로 회원가입을 진행하면 admin계정이 새로 생성될 것이다.
풀이 과정
일단
id : admin
pw : qwertyu
로 접근을 시도하면 위와 같이 admin is exist!!가 출력이 된다.
그리고 최대 길이 또한 32글자로 막혀있어서(소스코드에서 확인가능) 맨 뒤에 123이 붙지 않는다.
그래서 개발자도구에서
maxlength=100으로 설정후에 다시 시도해보자.
그랬더니 회원가입이 진행이 완료되었다.
왜 회원가입이 가능한가? 다시 소스코드를 봐보자.
you need login with "admin"s id!
===========================
create table tmitter_user(
idx int auto_increment primary key,
id char(32),
ps char(32)
);
id에 대한 중복처리가 전혀 이루어지지 않았다.
그니까 지금 아마 테이블에는
idx | id | ps |
1 | admin | 기존 비번 |
2 | admin | qwertyu( 내가 방금 생성한 비번) |
이렇게 존재할 것이다.
id 중복에 대한 처리가 없고, idx에 대해서만 기본키로 설정이 되어있기 때문이다.
그래서 이제 admin으로 다시 로그인하면
플래그 값이 나온다.
에필로그
이런 취약점은 처음봐서 신기해서 작성하였다.
'보안 스터디 > 웹 해킹' 카테고리의 다른 글
[webhacking.kr] old-26 문제 풀이 (2) | 2024.10.01 |
---|---|
[드림핵/워게임] random-test (웹 해킹) (2) | 2024.09.26 |
[드림핵/워게임] baby-union (웹 해킹) (9) | 2024.09.25 |
[드림핵/워게임] what-is-my-ip (웹 해킹) (3) | 2024.09.22 |
[드림핵/워게임][wargame.kr] login filtering (웹해킹) (2) | 2024.09.20 |