늘모자란, 개발

늘모자란, 개발


you need login with "admin"s id!

===========================

create table tmitter_user(
 idx int auto_increment primary key,
 id char(32),
 ps char(32)
);


짭트위터 ... admin으로 로그인해야한다고 한다.
웃긴게 로그인버튼은 눌리지도 않는데 일단은 admin이라는 아이디로 가입부터 해보기로 한다

필터는 안되있고 admin 으로 가입하려면 존재한다는 에러가 반겨준다.
옛날에 한 가락이 있으니 admin + ' '도 해보고 이것저것 해봤으나 안된다.

0x61646d696e 는 존재한다는것 같지만
CHAR(97,100,109,105,110) 를 해보니까 화면이 전환되었다. 이름 그대로 가입시켜준다 ㅋㅋ CHAR 함수는 사용할 수 없는것 같다.
잘 생각해보면 디비 스킴을 왜 공개해줬을까. 아이디에 혹시 32자이상해주면 마지막은 잘리고, tim()되면서 admin으로 가입할 수 있지 않을까?

요컨데 이렇게 말이다.

id=admin                                                                                           1&ps=1234567


자릿수는 그냥 32자 넘기려고 대강 친것이다. 어쨌든 이렇게 하면 가입이 정상적으로 이뤄지고, 로그인할수도 있어 key를 얻게 된다.
2016/06/08 16:10 2016/06/08 16:10
Simple Compare Challenge.

hint? you can see the title of this challenge.

 :D


type.. 사실 PHP같은 스크립트 기반 언어에서 type을 신경써본적이 '거의'없다. 무슨 문제일지 궁금하긴하다.

 <?php
 if (isset($_GET['view-source'])) {
     show_source(__FILE__);
    exit();
 }
 if (isset($_POST['json'])) {
     usleep(500000);
     require("../lib.php"); // include for auth_code function.
    $json = json_decode($_POST['json']);
    $key = gen_key();
    if ($json->key == $key) {
        $ret = ["code" => true, "flag" => auth_code("type confusion")];
    } else {
        $ret = ["code" => false];
    }
    die(json_encode($ret));
 }

 function gen_key(){
     $key = uniqid("welcome to wargame.kr!_", true);
    $key = sha1($key);
     return $key;
 }
?>

<html>
    <head>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
        <script src="./util.js"></script>
    </head>
    <body>
        <form onsubmit="return submit_check(this);">
            <input type="text" name="key" />
            <input type="submit" value="check" />
        </form>
        <a href="./?view-source">view-source</a>
    </body>
</html>



일단 gen_key는 uniqid기때문에 내가 어떤값을 넣어서 보낸다고 해도 별로 소용이 없다.
그래서 다른 방법을 찾아야 할 것 같아보였다. 무조건 값을 참으로 만들어야 하는데 $json->key를 그대로 사용하고 있다.
json은 true와 false의 경우 "true"나 "false"처럼 string으로 캐스팅하지 않고 그대로 사용하고, 형을 보존해서 보내기때문에

key에 true 값을 줘서 보내면 문제를 패스하게 된다
요컨데 이런식이다

json={"key":true}




2016/06/08 15:56 2016/06/08 15:56
if you can bypass the strcmp function, you get the flag.


strcmp는 문자열을 비교하는 함수인데 bypass를 어떻게 해야할것인가.

 <?php
    require("../lib.php"); // for auth_code function

    $password = sha1(md5(rand().file_get_contents("/var/lib/dummy_file")).rand());

    if (isset($_GET['view-source'])) {
        show_source(__FILE__);
        exit();
    }else if(isset($_POST['password'])){
        sleep(1); // do not brute force!
        if (strcmp($_POST['password'], $password) == 0) {
            echo "Congratulations! Flag is <b>" . auth_code("strcmp") ."</b>";
            exit();
        } else {
            echo "Wrong password..";
        }
    }

?>
<br />
<br />
<form method="POST">
    password : <input type="text" name="password" /> <input type="submit" value="chk">
</form>
<br />
<a href="?view-source">view-source</a>


일반적으론 패스할수 없다고 생각되지만 php strcmp 에 배열 취약점이 있다
DOM을 조작해도 좋고, 패킷을 그냥 생성해도 보내도 상관없다. password=가 아닌 password[]= 형태로 만들어 보내주자. 값은 상관없다.
가면갈수록 === 를 안쓰면 큰일나겠다는 생각이 든다.
2016/06/08 15:34 2016/06/08 15:34
Simple Reverse Engineering Challenge.


웹해킹이 아니라 리버싱이라고 선언해오고 있다. 리버싱은 경험이 거의 없기 때문에 걱정이 좀 된다. 얼마나 걸릴지도 잘 모르겠고...

문제에 들어가면 crackme를 받을 수 있다. crackme는 리버싱 초보들한테 어디 구간을 어떻게 해보라 하고 주는 튜토리얼 비슷한 느낌으로 알고 있는데, 나한테 딱 맞는것 같다.

프로그램은 심플한테 뭘 입력하던간에 패스코드로 인식하게 해서 점프하도록 만들어야할 것 같다.
그러기위해서는 무얼해야할까. 툴이 필요하다. OllyDbg를 사용하기로 하자.

나는 이벤트 원리 방식은 잘 모르겠지만 일단 string을 따라가면 뭐가 될 것 같았다.
참고로, 64비트에서는 2.00 이하는 잘 동작하지 않는다. 2.01 버전을 다운받아야 제대로 스트링이 보인다.


프로그램 자체에 http 주소가 있는걸 보니 제대로 키를 입력하면 서버에 키를 요청하는 방법인가보다.

문자열중에 _my_b 와 birth가 있는걸 보니 키에 얘네가 들어갈거라 생각해본다.
조금 더 비주얼하게 보기 위해서 IDA로 저 주소를 따라가서 봤다



밑엔 비슷하게 birth 가 있다. 대강 봐도 _my_bbirth 가 될순 없을것 같으니 뒤에 문장은 _my_birth 라고 생각하자.
그럼 앞이 문젠데

cmp eax, 45Ah

를 __wtoi 를 콜해서 위 값을 비교한다.
cmp는 compare이고 그럼 결국 앞에 붙은값과 45Ah를 비교한다는것 같은데 여기서 h는 hex를 의미한다고 한다.
즉, 0x45A와 일치해야되는 모양이다.

0x45A를 변환해보니까
>>> 0x45A
1114


1114라고 한다.

고로,

1114_my_birth
이거나
_my_birth1114

인데 둘중에 답이 있었다.

어째 제대로 한게 아니라 뛰어가다가 개구리 치인꼴이다.
리버싱은 꼭 제대로 공부하겠다고 스스로와 약속을 하며..

2016/06/08 14:29 2016/06/08 14:29
md5('value', true);


우리는 이 문제를 본적이 있다. 바로 이 문제 이다.

 <?php
 if (isset($_GET['view-source'])) {
  show_source(__FILE__);
  exit();
 }

 if(isset($_POST['ps'])){
  sleep(1);
  mysql_connect("localhost","md5_password","md5_password_pz");
  mysql_select_db("md5_password");
  mysql_query("set names utf8");
  /*
  
  create table admin_password(
   password char(64) unique
  );
  
  */

  include "../lib.php"; // include for auth_code function.
  $key=auth_code("md5 password");
  $ps = mysql_real_escape_string($_POST['ps']);
  $row=@mysql_fetch_array(mysql_query("select * from admin_password where password='".md5($ps,true)."'"));
  if(isset($row[0])){
   echo "hello admin!"."<br />";
   echo "Password : ".$key;
  }else{
   echo "wrong..";
  }
 }
?>
<style>
 input[type=text] {width:200px;}
</style>
<br />
<br />
<form method="post" action="./index.php">
password : <input type="text" name="ps" /><input type="submit" value="login" />
</form>
<div><a href='?view-source'>get source</a></div>


전체 쿼리가 나와 있지만, 사실 볼 필요는 없다. 우린 쿼리를 파괘하기 위해서 마법의 쓰레기 md5값을 넣어주면 해결 할 수 있다.
2016/06/08 14:09 2016/06/08 14:09
JUST COMPARE ONLY.

with the other value :D


소스를 보니 md5의 해쉬 충돌 취약점에 대해 말하고 싶은듯 하다. 그냥느낌이 그렇다


 <?php
    if (isset($_GET['view-source'])) {
         show_source(__FILE__);
         exit();
    }

    if (isset($_GET['v1']) && isset($_GET['v2'])) {
        sleep(3); // anti brute force

        $chk = true;
        $v1 = $_GET['v1'];
        $v2 = $_GET['v2'];

        if (!ctype_alpha($v1)) {$chk = false;}
        if (!is_numeric($v2) ) {$chk = false;}
        if (md5($v1) != md5($v2)) {$chk = false;}

        if ($chk){
            include("../lib.php");
            echo "Congratulations! FLAG is : ".auth_code("md5_compare");
        } else {
            echo "Wrong...";
        }
    }
?>
<br />
<form method="GET">
    VALUE 1 : <input type="text" name="v1" /><br />
    VALUE 2 : <input type="text" name="v2" /><br />
    <input type="submit" value="chk" />
</form>
<br />
<a href="?view-source">view-source</a>



ctype_alpha 는 좀 생소한 PHP function인데, 모두 알파벳인지 확인하는 함수라고 한다.
즉, v1은 전부 알파벳으로만 이루어져야하겠다.
그리고 v2는 전부 숫자여야만 하겠고..

해쉬 충돌은 바이너리 단위로 가야되기때문에 아닌것 같았고 결국 검색어를 다르게 해서,
php md5 vulnerability 로 검색해봤더니... 띠용..

0e 로 시작하게 될경우 hex로 취급되서 지수화 된다고 한다. 정확한 작동원리는 모르겠지만 아니 세상에 뭐 이런게 다 있지 하는 생각이 들었다.

2016/06/08 14:05 2016/06/08 14:05
javascript game.

can you clear with bypass prevent cheating system?


뭐 같은 게임하나 나온다.


게임 소스는 minify 및 난독화된 스크립트가 있는데 처음에 게임을 봤을때 든 생각은 벽 이미지를 다 없애버려서 충돌을 없애거나 점수를 조작하면 되지 않을까였다

그래서 right_wall 과 left_wall 의 width를 전부 0으로 바꿔버렸는데 충돌이 일어났다.
우주선 크기도 1로 했는데 충돌이 일어났다. 뭐지 도대체?
그래서 정상적으로 게임을 해보니까, 벽이 도저히 우주선이 피할 수 없을만큼 좁아져 온다. 에라이...

이것저것 클라이언트로 시도 해봤는데 안될것 같단 결론을 내리고 죽을때 보내는 패킷을 빠르게 낚아채서 점수를 보내보기로 했다
허무하다... 토큰이 지속적으로 바뀌는데 토큰이 바뀌기 전에 재빨리 스코어를 보내주면 그냥.. 키가 온다...

2016/06/07 21:37 2016/06/07 21:37
What kind of this Database?

you have to find correlation between user name and database.


들어가보면 휑한 화면이 있다. 소스를 보면

<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script text="javascript">
function fschk(f){
 if(f.user_id.value=="admin"){
  alert("dont access with 'admin'");
  return false;
 }
}
</script>
<style>
    body {width:100%; height:100%; padding:0; margin:0;}
</style>
</head>
<body>

<div style='width:400px; margin:50 auto; text-align:center;'>
 <h2>BLUEMEMO SYSTEM <sub>0.53 beta</sub></h2>
 <form method="post" action="memo.php" onsubmit="return fschk(this);">
 USER <input type='text' maxlength=16 size=16 name='user_id' /> <input type='submit' value='LOGIN' />
 </form>
</div>

</body>


이렇게 되어 있는데 admin + ' ' 이나 ' ' + admin 으로 들어가면 알아서 trim되기때문에 admin으로 들어갈 수 있다.
수많은 사람들의 흔적을 볼 수 있는데 이걸로 뭘 할 수 있을지 생각해야겠다.
이 문제가 웃긴게 다른 사람들이 한 수많은 삽질을 볼 수 있다는것이다 ㅋㅋ 생각이 다들 비슷비슷한듯하다...


아이디 시도로 요렇게 해봤다.

0x61646d696e
CHAR(97,100,109,105,110) //칸을 늘려야 했음

근데 애초에 뭐 다 처리를 해놨는지 안된다.

그래서 이제 기본적으로 가보기로 했다.
' " < / 를 넣어보기로 한것이다

"엔 반응이 없는데 ' 랑 / 때는 반응이 있었다.
Fatal error: Uncaught exception 'Exception' with message 'Unable to open database: unable to open database file' in /home/www/db_is_really_good/sqlite3.php:7 Stack trace: #0 /home/www/db_is_really_good/sqlite3.php(7): SQLite3->open('./db/wkrm_/.db') #1 /home/www/db_is_really_good/memo.php(14): MyDB->__construct('./db/wkrm_/.db') #2 {main} thrown in /home/www/db_is_really_good/sqlite3.php on line 7


sqlite3.php 를 열려는 와중에 에러가 난다고 하는데
./db/wkrm_/.db 를 찾을 수 없다고 하는것 같다. 확실하게 하기 위해서 슬래쉬 뒤에 a를 붙여서 /a로 시도 해보았다.

Fatal error: Uncaught exception 'Exception' with message 'Unable to open database: unable to open database file' in /home/www/db_is_really_good/sqlite3.php:7 Stack trace: #0 /home/www/db_is_really_good/sqlite3.php(7): SQLite3->open('./db/wkrm_/a.db') #1 /home/www/db_is_really_good/memo.php(14): MyDB->__construct('./db/wkrm_/a.db') #2 {main} thrown in /home/www/db_is_really_good/sqlite3.php on line 7


그러니까 즉 참조하는 주소는 ./db/wkrm_().db 라고 볼 수 있다. admin이 블럭되고 있는 아이디니까 여기에 admin을 넣어서 접근해본다.
php 주소가 하나 적혀있고 해당 주소에서 나오는 key를 입력하여 해결!
2016/06/07 21:14 2016/06/07 21:14
This is another programming language.

Can you read this source code?


문제에 들어가서 파일을 하나 다운받아보면 탭과 스페이스만으로 이루어진 진짜 별 또라이같은 파일을 다운로드할 수 있게 되어 있다.
뭔가 규칙은 있겠지만 그냥 병신같다는 말밖에 안나온다. 문제가 왜 WTF인지 알겠다.
hex로 읽어도, base64 encode해봐도 space, tab, lf밖에 안나온다.

혹시나해서 위 세개로 검색하니 ㅋㅋ brainfuck 마냥 저걸로만 이루어진 언어가 있단다. 진짜 지랄났다고밖에 말을 할수가 없다...
이곳에서 whitespace compiler(-_-)를 지원한다. 복사해서 돌려보면 답이 나온다.

세상에 병신같은건 oak 나 brainfuck 같은류만 있는줄 알았더니 정말 신세계가 따로 없다. 허참ㅋㅋㅋ

2016/06/07 20:50 2016/06/07 20:50
I have accounts. but, it's blocked.

can you login bypass filtering?


인젝션 느낌이 솔솔 난다.
소스를 보라고 권하기 때문에 소스를 보자면

 <?php

if (isset($_GET['view-source'])) {
    show_source(__FILE__);
    exit();
}

/*
create table user(
 idx int auto_increment primary key,
 id char(32),
 ps char(32)
);
*/

 if(isset($_POST['id']) && isset($_POST['ps'])){
  include("../lib.php"); # include for auth_code function.

  mysql_connect("localhost","login_filtering","login_filtering_pz");
  mysql_select_db ("login_filtering");
  mysql_query("set names utf8");

  $key = auth_code("login filtering");

  $id = mysql_real_escape_string(trim($_POST['id']));
  $ps = mysql_real_escape_string(trim($_POST['ps']));

  $row=mysql_fetch_array(mysql_query("select * from user where id='$id' and ps=md5('$ps')"));

  if(isset($row['id'])){
   if($id=='guest' || $id=='blueh4g'){
    echo "your account is blocked";
   }else{
    echo "login ok"."<br />";
    echo "Password : ".$key;
   }
  }else{
   echo "wrong..";
  }
 }
?>
<!DOCTYPE html>
<style>
 * {margin:0; padding:0;}
 body {background-color:#ddd;}
 #mdiv {width:200px; text-align:center; margin:50px auto;}
 input[type=text],input[type=[password] {width:100px;}
 td {text-align:center;}
</style>
<body>
<form method="post" action="./">
<div id="mdiv">
<table>
<tr><td>ID</td><td><input type="text" name="id" /></td></tr>
<tr><td>PW</td><td><input type="password" name="ps" /></td></tr>
<tr><td colspan="2"><input type="submit" value="login" /></td></tr>
</table>
 <div><a href='?view-source'>get source</a></div>
</form>
</div>
</body>
<!--

you have blocked accounts.

guest / guest
blueh4g / blueh4g1234ps

-->



blueh4g라는 아이디로 로그인을 해야되는데 로그인이 안되는 그런 느낌적인 느낌이다.
실제로 시도해봐도 블럭된다고 뜬다. 이제 우린 어떻게 해야할것인가? 특문같은것은 mysql_real_escape_string 덕에 시도할맛이 안나고..
그런데 마지막 주석이 의미심장하다.

가만보니 비교문도 === 가 아니라 == 이다. 이는 대소문자를 가리지 않는다는건데.
혹시나 하는마음에 Guest / guest를 시도하니 패스...

=== 를 써서 비교하는게 맞을 것 같다. 아니면 이상한 아이디랑 비밀번호 쓰지 말든지..
2016/06/07 20:35 2016/06/07 20:35