소스코드를 읽을 수 있는가??

실행을 시켜 보았다. 

 

 

소스코드 파일이 보여서 다운로드를 해서 보기로 했다.

아무것도 안보여서 확인 해보니 공백으로 구분되어있다.

 

 

???? -> 일단 확장자가 ws라서 = 처음보는 확장자 

그래서 확장자명으로 어떤 프로그램인지 찾아보기로 하고 구글링을 했더니

 

 

Whitespace Programming Language라고한다. 

아마도 이것의 줄임말로 확장자를 ws라고 하지 않았을까

블로그를 들어가보니 온라인으로 컴파일이 가능한곳이 있다고 한다.

ideone.com/

 

Ideone.com

Ideone is something more than a pastebin; it's an online compiler and debugging tool which allows to compile and run code online in more than 40 programming languages.

ideone.com

 

여기서 아까 봤었던 공백문자 == ws 파일을 컴파일 해보면??

 

wow key is 31b25937d25e(생략)e 

 

'CTF > WebHacking' 카테고리의 다른 글

Wargame.kr - strcmp  (0) 2021.02.26
Wargame.kr - fly me to the moon  (0) 2021.02.16
Wargame.kr - login filtering  (0) 2021.02.12
Wargame.kr - QR CODE PUZZLE  (0) 2021.02.11
Wargame.kr - flee button  (0) 2021.02.11

 

by-pass를 하는 문제인것 같은데 우회하라는 뜻인가?

일단 들어가보았다.

 

 

아무런 표시 없이 로그인 창이 나오게 되는데

ID 와 PW를 알아보기 위해서 get_source를 들어가서 페이지 소스를 보았다.

 

 

소스파일을 볼 수 있는데 여기서 봐야될것이 몇가지 있다.

 

you have blocked accounts.

guest / guest
blueh4g / blueh4g1234ps

 

block이 되어있는 것 같지만 한번 로그인을 시도해봤다.

 

 

예상했지만 block되었다고 메세지를 표시해준다.

그럼 소스코드를 다시 살펴보자 

 

 <?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

 

mysql구문을 이야기하는것 같다. (mysql은 한번도 공부해본적이 없어서 잘은 모른다.)

 

1. POST 방식으로 입력받은 id ,ps 값이 존재하는지 확인

2. mysql_real_escape_string_trim 함수를 이용해서 공백문자와 특수문자를 제외하여 SQL injection을 방지한다.

3. id 값을 확인하고 guest or blue4g이면 block 

4. id 값이 3이 아니면 OK를 출력하고 MD5으로 인코딩된 FLAG를 보여준다.  

5. id 값이 아무것도 없으면 Worng을 출력 

 

guest / guest
blueh4g / blueh4g1234ps

 

 

분명히 else문을 이용해서 다른 값을 입력했는데도 wrong이 출력된다.

그럼 소스코드안의 if문의 필터링을 우회해보기로 했다.

$key를 사용해서 로그인 필터링으로 값을 구분했던것 같다.

 

if($id=='guest' || $id=='blueh4g'){                   /* id 값이 guest or blueh4g 이면 블락된 상태 */
    echo "your account is blocked";
 }else{
    echo "login ok"."<br />";                               /* id 값이 guest or blueh4g 만 아니면 성공 */
    echo "Password : ".$key;
 }

 

 

쿼리 자체는 대소문자를 구별하지 않는다.

그래서 Guest로 로그인을 해보았다. -> 나중에 알았지만 PHP는 대소문자를 구분하지 않는다고 한다.

 

 

필터링은 php에서 하고있다. 

그래서 Guest를 입력하고 pw = guest를 입력하면 쿼리에서는 대소문자를 구분하지 않기 때문에

서로 같은 값이라고 인식을 하여 key를 내어준다.

 

'CTF > WebHacking' 카테고리의 다른 글

Wargame.kr - fly me to the moon  (0) 2021.02.16
Wargame.kr - WTF_CODE  (0) 2021.02.13
Wargame.kr - QR CODE PUZZLE  (0) 2021.02.11
Wargame.kr - flee button  (0) 2021.02.11
Wargame.kr - already got  (0) 2021.02.11

접속을 해보니 QR코드가 나왔다.

어떠한 정보를 담고 있는듯 한데 하나 하나 맟추는것도 방법이겠다. (어느세월에...???)

개발자도구를 사용해서 소스코드를 분석 해보았다.

보통 웹에서 어떠한 동작이나 이벤트들은 자바스크립트로 작성된 경우가 많다고 한다.

 

/*<![CDATA[*/
 $(function(){ $('#join_img').attr('src',unescape('.%2f%69%6d%67%2f%71%72%2e%70%6e%67'));
  $('#join_img').jqPuzzle({rows:6,cols:6,shuffle:true,numbers:false,control:false,style:{overlap:false}});
  hide_pz();});
 function hide_pz(){
  var pz=$('#join_img div'); if(pz[pz.length-2]){$(pz[1]).remove();$(pz[pz.length-2]).remove();}else{setTimeout("hide_pz()",5);}
 }
/*]]>*/

 

이미지의 id 값을 src로 사용을 하는것 처럼 보이는데 unescape가 뭔지 모르겠다 .

구글링을 하는것도 방법이겠지만 직접 콘솔에 입력을 해보았다.

 

$unescape('.%2f%69%6d%67%2f%71%72%2e%70%6e%67');
"./img/qr.png"

 

이미지를 사용하는것을 확인 할 수 있다.

unescape를 이용해서 QR코드의 정보를 해독하는것 같다.

 

QR 코드(영어: QR code, Quick Response code)은 흑백 격자무늬 패턴으로 정보를 나타내는 매트릭스 형식의 이차원 코드이다. 비슷한 용도로 먼저 사용된 이 차원 코드로는 바코드가 있다. 바코드는 이름 그대로 단순한 막대기 모양의 바를 이차원으로 나열한 것이다 - Wiki pedia

 

Url에 해당 이미지를 입력하면 온전한 QR코드가 나오지 않을까? 

 

 

정상적으로 나오는데 이 QR코드의 내용을 확인 할 수 있다면??

휴대폰으로 찍어도 되지 않을까 -> 사실 이 방법도 있긴한데 안해봤다.

 

온라인 디코더를 이용해서 QR코드를 확인을 했다.

 

 

해당 URL 주소로 이동을 해보니 플래그가 나왔다.

 

성공!!

'CTF > WebHacking' 카테고리의 다른 글

Wargame.kr - fly me to the moon  (0) 2021.02.16
Wargame.kr - WTF_CODE  (0) 2021.02.13
Wargame.kr - login filtering  (0) 2021.02.12
Wargame.kr - flee button  (0) 2021.02.11
Wargame.kr - already got  (0) 2021.02.11

flee button = 도망가는 버튼??

일단 시작을 해보았다.

 

 

버튼을 클릭하기위해서 마우스를 움직여보면 버튼도 같이 움직인다 

결국 클릭을 못하게 해두었다는건데 그래서 개발자도구를 켜서 안의 소스코드를 확인해 보았다.

 

 

버튼의 클릭과 관련된 소스코드를 찾았다.

그래서 이걸 콘솔에서 실행을 시켜주면???

 

window.location='?key=7263';

 

성공

'CTF > WebHacking' 카테고리의 다른 글

Wargame.kr - fly me to the moon  (0) 2021.02.16
Wargame.kr - WTF_CODE  (0) 2021.02.13
Wargame.kr - login filtering  (0) 2021.02.12
Wargame.kr - QR CODE PUZZLE  (0) 2021.02.11
Wargame.kr - already got  (0) 2021.02.11

 

Start 버튼을 클릭해서 시작을 해보니 

 

 

이미 키를 받았다고 한다. (????)

개발자 도구를 사용하기로 했다.

 

 

플래그를 쉽게 확인할 수 있었다.

 

 

성공

'CTF > WebHacking' 카테고리의 다른 글

Wargame.kr - fly me to the moon  (0) 2021.02.16
Wargame.kr - WTF_CODE  (0) 2021.02.13
Wargame.kr - login filtering  (0) 2021.02.12
Wargame.kr - QR CODE PUZZLE  (0) 2021.02.11
Wargame.kr - flee button  (0) 2021.02.11

 

파일을 다운로드해서 실행을 해보면 다른것들과 비슷하게 암호를 입력하는 창이 나온다

문제의 답은 OEP를 구한 후 '등록성공' 으로 가는 분기점의 OPCODE를 구하시오.
정답인증은 OEP + OPCODE

 

 

패킹의 유무를 확인해보았는데 UPX 패킹이 아니라 ASPack 패킹인것 같다 그래서 ASPack이 무엇인지 검색을 해보니

UPX와 같은 패커이다. 새로운 패커가 나왔는데 계속 자동화 패커만 의존할 수 없으니 패킹의 원리가 어떻게 되는지 알아보기로 했다.

 

Packing 원리 

 

저번에 9에서도 비슷한것을 보았지만 PUSHAD로 레지스터 값을 스택에 저장하고 나중에 원본코드가 다 복구되면 메모리에 POPAD 명령을 통해서 다시 레지스터 값을 참조하게 될것이다. 그래서 PUSHAD를 수행한후의 ESP 값에 BP를 설정해주면 쉽게 OEP로 분기가 가능하지 않을까 생각을 해보았다.

 

Break Point

 

레지스터 상태에서도 볼수있듯이 PUSHAD명령을 수행하고 나서 레지스터의 모든 값을 스택에 넣고 시작한다.

 

 

???? : 아무리 찾아도 안나온다 -> 오류가 있는지 확인해보자 

 

 

에러의 내용을 확인해보니 entry point가 다른곳에 있다고하는데 원인을 분석해보면  

1. 패킹이 잘되어 있다.

2. ollydbg가 64bit와 호환이 되지 않는다. -> 둘중에 하나 

패킹은 한마디로 실행 압축을 말한다.

일반 압축파일과 차이점은 일반 파일은 zip으로 확장자가 바뀌지만 패킹은 확장자가 바뀌지 않는다.

  

 

Search for ->Find All commands  

 

 

POPAD를 검색해주면 사용된 모든 POPAD가 나오는데 제일먼저 나온 POPAD안으로 들어가 보았다.

 

 

BP를 걸고 실행을 해보니 바로 실행이 되버려서 (패킹이 여기서 안풀린거 같음)

다시 두번째 POPAD로 들어가보았다.

 

 

 

POPAD 이후로도 실행을 해보았지만 레지스터 값이 변하지 않았다

아마도 지금보는 POPAD이후로 패킹이 풀린듯 하다.

위에서 볼 수 있지만 실행하기전에는 PUSH 0이었다가 실행을 해보면 00445834라고 뜬다.

계속 실행을 시켜보았다.

 

 

return이 나오게 되는데 RETN함수가 실행되면 그 후에 프로그램이 실행된다.

그러면 최근에 적재된 00445834가 OEP 주소인것을 알 수 있다.

 

 

그래서 해당 OEP로 이동을 했다. 

->Follow immediate constant

그럼 이제 성공메세지 확인을 위해서 text string으로 검색을 해보았다.

 

 

well done 이라는 문자열이 성공메세지를 출력해준다는것을 알수있다.

문제에서 말한 OEP는 찾았는데 OPCODE는 무엇인가

 

컴퓨터 과학에서 명령 코드(opcode←operation code, instruction syllable, instruction parcel, opstring[1][2][3][4][5][6][7])는 기계어의 일부이며 수행할 명령어를 나타내는 부호를 말한다. -> Wiki pedia

 

수행할 명령어를 나타내는 부호를 말하는 말한다고 하는데 이 프로그램에서는 조건에 따라서

성공과 실패를 구분하는 지점이 아닌가 생각해보았다.

 

 

JNZ SHORT 0044552B이가 OPCODE인것을 볼 수 있는데 JNZ는 조건 점프라서 zero flag

즉, 두개의 값을 비교했을때 값이 같으면 1이고 다르면 0을 반환 해준다 .

하지만 지금은 zero flag가 0을 반환할것이기 때문에 well done이라는 문자열을 출력하지 않고, 점프도 하지않을것이다.

값이 1이면 0044552B로 점프를해서 well done 이라는 문자열을 보여준다.

 

OEP + OPCODE 이므로 00445834 와 JNZ의 분기점인 75 55가 된다.

 

 

 

 

 

 

'CTF > Reversing' 카테고리의 다른 글

Code Engn Basic RCE Level 12  (0) 2021.05.14
Code Engn Basic RCE Level 11  (0) 2021.05.12
Code Engn Basic RCE level 9  (0) 2021.01.25
Code Engn Basic RCE level 8  (0) 2020.12.04
Code Engn Basic RCE level 7  (0) 2020.12.03

클릭하면 키 파일을 체크한다고 한다.

 

그냥 확인을 해보면 에러메세지를 출력을 하는데 ollydbg로 확인을 해보았다.

 

PUSHAD

PUSHAD라는 명령어를 통해서 레지스터 값을 모두 스택에 적재함을 알 수있다.

패킹의 가능성이 보이기 때문에 패킹의 유무를 확인하고 언패킹을 진행하였다.

upacking
잘못된 언패킹

첫번째 MessageBoxA의 인자 값이 잘못된것을 볼 수 있다.

함수에 전달할 인자가 부족한거 같다. 문제에서 말한 StolenByte와 연관성이 있어보인다.

StolenByte

▶ 패킹된 바이너리를 언패킹할때,  이러한 과정을 방해하기위한 방법으로 프로그램의 일부 바이트를 별도의 영역에서 실행시킴으로써 OEP를 다른 위치로 가장하고 덤프를 쉽게 하지 못하도록 구현한 기법이다. 

올바른 프로그램을 얻기위해서는 StolenByte도 같이 복원해줘야 덤프가 성공적으로 이루어진다.

 

언패킹을 하기전으로 돌아가서 다시 열어보았다.

POPAD

PUSHAD가 레지스터 값을 모두 스택에 적재하는 명령어인데 반대로 스택에서 값을 가져오는 명령어는 POPAD가 아닐까 추측을 해보았다 그리고 POPAD에서 PUSHAD로 스택에 적재된 값들이 PUSH되고 있는것을 확인했다.

 

upx패킹은 코드의 마지막에 있는 JMP명령어를 통해서 원래의 OEP로 가야하는데 원래의 OEP는 0040100C는 OEP가 아니다 원래의 OEP는 00401000이 되어야 한다. 왜냐하면 언패킹을 하고나서 열었을때의 시작주소였기 때문이다.

NOP로 되어있는것으로 해당 부분이 다른 특정 영역에서 실행되고 있음을 알 수 있다.

 

그래서 StolenByte는 POPAD다음에 오는 PUSH 명령어이다.

그리하여 StolenByte는 0040736E의 6A00 과 00407370의 6800204000이다 

따라서 StolenByte는 6A006800204000

노트북이 맛이가서 PC방에서 풀어서 그런가 가독성이 좀 안좋은것 같다.

'CTF > Reversing' 카테고리의 다른 글

Code Engn Basic RCE Level 11  (0) 2021.05.12
Code Engn Basic RCE level 10  (0) 2021.01.28
Code Engn Basic RCE level 8  (0) 2020.12.04
Code Engn Basic RCE level 7  (0) 2020.12.03
Code Engn Basic RCE level 6  (0) 2020.12.02

기본적인 계산기 프로그램인것 같다.

하지만 문제에서 OEP를 찾으라고 했다.

그래서 일단 OllyDBG로 열기 전에 패킹의 유무를 확인해보았다.

UPX로 패킹이 되어있는것을 확인하고 언패킹을 진행해보았다.

용량이 늘어난것으로 보아 언패킹이 진행된것을 알 수 있다.

그 다음 Olly DBG로 열어보았다.

 

01012475의 주소가 OEP이다 

OEP : 패킹된 파일의 실제 프로그램 시작 부분 

'CTF > Reversing' 카테고리의 다른 글

Code Engn Basic RCE level 10  (0) 2021.01.28
Code Engn Basic RCE level 9  (0) 2021.01.25
Code Engn Basic RCE level 7  (0) 2020.12.03
Code Engn Basic RCE level 6  (0) 2020.12.02
Code Engn Basic RCE level 5  (0) 2020.08.16

첫번째로 패킹의 유무를 확인 해보았다.

보아하니 패킹이 되어있지는 않은것 같다. 

문제에서 하드디스크의 이름을 CodeEngn으로 바꾸면 나오는 시리얼값을 입력하라고 하였다.

그래서 하드디스크의 이름을 관리자 권한으로 변경해주었다.

그리고 나서 Olly DBG로 실행을 해보았다.

패킹이 되어 있지 않아서 시리얼 값을 비교하는 함수가 있을것이라고 추측을 해보았다

IstrcmpiA 함수가 있었다. 이 함수가 서로서로 시리얼 값을 비교해서 성공과 에러 메세지를 띄어주는 곳으로 점프 시키는것 같다. 

함수의 위치로 이동해보았다.

4562-ABEX가 아직 무엇인지는 모르겠으나, 밑의 주소에 CodeEngn이라는 문자열을 PUSH하고 있다.

아마도 하드디스크의 이름을 바꿨을때 이곳으로 PUSH 되는것 같다.

계속 실행을 해보았다.

기존의 CodeEngn 문자열에 4562-ABEX 문자열이 뒤에 추가되었다. 아마 이런식으로 시리얼 값이 정해지는것 같다.

게속 실행해보았다.

 

Code라는 문자가 1글자씩 뒤로 밀리는것을 볼수있는데, 분기가 2번도는것을 보아 2글자씩 뒤로 밀리는것 같다 

그래서 CodeEngn -> EqfgEngn으로 2글자가 밀려서 시리얼값이 생성된다.

L2C-5781이라는 새로운 문자열이 또 보인다 아직은 잘모르겠지만 게속 실행해보았다.

새로 시리얼 값이 생성된것을 볼 수 있다. 

아까 2글자씩 밀렸던 EqfgEngn4562-ABEX의 앞에 L2C-5781이라는 문자열이 추가되었다 

따라서 07.exe의 Serial 값은 L2C-5781EqfgEngn4562-ABEX인것을 알 수있다.

그래서 입력을 해보았다.

성공 메세지가 출력되는것을 확인할 수 있다.

그리고 하드디스크 이름은 원래대로 해주었다.

'CTF > Reversing' 카테고리의 다른 글

Code Engn Basic RCE level 9  (0) 2021.01.25
Code Engn Basic RCE level 8  (0) 2020.12.04
Code Engn Basic RCE level 6  (0) 2020.12.02
Code Engn Basic RCE level 5  (0) 2020.08.16
Code Engn Basic RCE level4  (0) 2020.08.16

프로그램을 실행시켜 보면 Serial 값을 입력하라고 한다 

아마 값을 입력하면 비교후에 일치 불일치 메세지를 띄어주는것 같다.

그래서 OllyDBG로 열어보았다.

현재 사용되고 있는 함수를 검색하기 위해 Search for에 Intermodularcalls를 들어가서 확인 해보았으나 무언가 이상하다. 패킹이 되어있는거 같아서 PEID로 패킹의 유무를 확인한 후 UPX로 언패킹을 진행하였다.

언패킹을 진행한 후에 문자열을 비교하는곳을 찾아보기 위해서 Text String을 검색해보았다.

성공 문자열과 실패 문자열이 눈에 보인다.

그래서 해당 문자열이 실행되는 함수 내부로 들어가 보았다.

0040106E 주소를 보면  "AD46DFS547" 이라는 문자열을 PUSH하고 있다.

EDX에 AD46DF547라는 문자열이 들어간다.

따라서 한번 실행시키고 난 후에 AD46DF5S47를 넣어보았다.

성공문자열을 보여준다.

하지만 문제에서 OEP + 시리얼 값이라고 했으니까

OEP를 찾아줘야 한다. 

OEP는 언패킹을하고 나서의 시작주소를 의미한다.

'CTF > Reversing' 카테고리의 다른 글

Code Engn Basic RCE level 8  (0) 2020.12.04
Code Engn Basic RCE level 7  (0) 2020.12.03
Code Engn Basic RCE level 5  (0) 2020.08.16
Code Engn Basic RCE level4  (0) 2020.08.16
Code Engn Basic RCE level3  (0) 2020.08.12

+ Recent posts