보안 스터디/웹 해킹

[드림핵/워게임] [wargame.kr] tmitter (웹 해킹)

성밍쟁 2024. 9. 28. 17:51
728x90
반응형

프롤로그

시간이 부족해

 

 

문제

https://dreamhack.io/wargame/challenges/343

 

[wargame.kr] tmitter

Description you need login with "admin"s id! create table tmitter_user( idx int auto_increment primary key, id char(32), ps char(32) );

dreamhack.io

 

코드는 따로 주어지지 않았다

 

 

코드

처음 입장했을 때 이렇게 존재하고, 소스코드는

<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으로 다시 로그인하면

플래그 값이 나온다.

 

 

 

에필로그

이런 취약점은 처음봐서 신기해서 작성하였다.

 

728x90
반응형