안경잡이개발자

728x90
반응형

  Type Confusion 문제는 PHP에서의 Type Confusion을 활용하여 Exploit을 해야 하는 웹 해킹 문제 유형입니다.

 

 

  문제를 확인하면 곧 바로 소스코드를 확인할 수 있는 페이지가 등장합니다. [view-source]를 눌러서 소스코드를 확인해 보도록 하겠습니다.

 

  소스코드를 확인해 본 결과 사용자로부터 json이라는 이름의 파라미터(Parameter)를 전달 받아서, 그 json 데이터의 'key'라는 데이터가 서버에서의 key 데이터와 동일한 경우 플래그(Flag)를 반환하는 것을 알 수 있습니다. 따라서 사용자가 입력한 데이터가 JSON 형식으로 서버에 전달이 되는 것으로 이해할 수 있을 것입니다.

 

 

  일단 소스코드를 확인해 본 결과, 접속자가 [check] 버튼을 누른 경우 submit_check() 함수가 수행되는 것을 알 수 있습니다. 따라서 이 함수가 정의되어 있는 util.js 파일을 확인해야 할 것입니다.

 

 

  확인 결과 단순히 사용자가 입력한 데이터를 JSON 형태로 담아서 서버로 전송하는 것을 알 수 있습니다. 자바스크립트(JavaScript) 소스코드가 난독화 되어 있지 않기 때문에 매우 간단히 소스코드를 분석할 수 있습니다. 굉장히 일반적인 형태의 매커니즘입니다.

 

 

  따라서 Type Confusion을 이용해서 Exploit하면 될 것입니다. 사실 PHP 소스코드를 보시면 느슨한 비교 연산자인 ==을 이용해서 사용자가 보낸 데이터와 서버의 Key 데이터를 검증하고 있는 것을 알 수 있습니다. 이 경우 한 쪽의 데이터가 True인 경우 전체가 참(True)가 되어 정답 처리가 될 것입니다.

 

 

  그러므로 {key: true}가 서버로 전달될 수 있도록 하면 됩니다. 저는 그래서 그냥 [Console] 탭을 열어서 함수를 재정의하여 무조건 true 값이 날아가도록 설정했습니다.

 

 

  결과적으로 다음과 같이 문제가 풀린 것을 알 수 있습니다.

 

 

728x90
반응형

728x90
반응형

  tmitter 문제는 일종의 웹 사이트를 해킹하는 문제입니다. 다시 말해 웹 해킹 유형이며, SQL Injection을 물어봅니다. 문제 사이트에 접속하자마자 데이터베이스 테이블 형태가 등장합니다. 테이블의 구조는 다음과 같습니다.

 

 

  확인 결과 테이블은 3개의 속성으로 구성되며 id와 ps는 각각 32자를 담을 수 있는 고정 길이 문자열로 선언된 것을 확인할 수 있습니다. 다만 여기에서 varchar() 대신에 char()를 쓰고 있다는 점을 이용하면 될 것 같습니다.

 

 

  [Sign Up] 버튼을 누르면 다음과 같이 회원가입 페이지로 이동하게 됩니다. 한 번 다음과 같이 아무런 정보나 넣어서 회원가입을 해보겠습니다.

 

 

  회원가입 이후에는 해당 정보로 로그인까지 해보겠습니다.

 

 

  로그인 결과 다음과 같이 특정한 글을 작성할 수 있는 메인 페이지가 등장합니다.

 

 

  그렇다면 이 문제의 해결 조건은 무엇일까요? 다시 회원가입 페이지로 이동해보았습니다. 확인 결과 주석에 적혀있는 바와 같이 admin 계정으로 회원가입을 하면 문제가 풀린다는 것 같습니다.

 

   

  따라서 일단 admin 계정으로 회원가입을 시도해보겠습니다. 하지만 당연히 회원가입에 실패합니다. 그렇다면 어떻게 해야 회원가입에 성공할 수 있을까요?

 

 

  이러한 문제는 SQL Injection부터 시작하여, 공격 벡터가 매우 다양합니다. 따라서 문제에서 힌트를 내포하고 있을 가능성이 높다고 생각합니다. 문제를 확인해 본 결과 회원가입 페이지에서 id와 ps의 길이를 제한하고 있는 것을 알 수 있습니다. 32자가 최대라고 하는데, 이것은 쉽게 우회할 수 있습니다.

 

 

  이 문제는 사실 데이터베이스 테이블을 설정할 때 이용했던 char() 자료형의 취약점을 이용하는 문제입니다. char() 자료형은 고정 문자열이기 때문에 사용자가 입력한 문자열을 제외한 빈 공간은 공백이 차지하게 됩니다.

 

  따라서 핸드폰 번호와 같이 길이가 거의 고정적인 데이터를 저장할 때가 아니라면 varchar() 자료형을 이용하는 것이 합리적입니다. 또한 MySQL에서 char() 자료형은 공간을 벗어나는 데이터를 입력하는 경우 수용량까지만 입력을 받습니다. 다시 말해서 32자를 넘어가는 데이터를 넣어버린다면 어떻게 될까요?

 

  따라서 'admin'이라는 데이터를 넣었을 때나 'admin                               '와 같이 뒤에 공백이 포함되어 있는 데이터를 넣었을 때나 모두 마찬가지로 동일한 데이터가 데이터베이스에 기록된다는 의미입니다. 따라서 'admin                               123'과 같은 문자열을 전송하는 경우 검증 단계에서 볼 때는 두 문자열은 서로 다른 문자열이지만 실제로 데이터베이스에 등록이 될 때는 동일한 id 값으로 등록이 됩니다. 결과적으로 32자를 넘으면서, admin과 공백을 포함하는 문자열을 전송하면 성공적으로 정답 처리를 받을 수 있습니다.

 

 

 

  따라서 개발자 도구(F12)를 실행하여 다음과 같이 32자를 넘어서 많은 글자가 들어갈 수 있도록 maxlength 속성의 값을 변경하고, 텍스트 창이 잘 보이도록 width 값을 조금 넓혀 보았습니다. 그리고 'admin + 공백 + 임의 문자열'을 입력하여 데이터베이스에 데이터를 등록하시면 됩니다.

 

 

  결과적으로 다음과 같이 admin으로 회원가입 된 정보로 로그인을 해보았습니다.

 

 

  회원가입에 성공했고, 결과적으로 플래그(Flag) 값을 얻게 되었습니다.

 

 

728x90
반응형

728x90
반응형

  md5_compare는 문제 이름에서부터 md5를 이용하여 두 개의 해시 값을 비교할 때의 취약점에 대해서 물어보는 것임을 알 수 있습니다.

 

 

  문제 풀이 페이지에 접속을 해보면 다음과 같이 [view-source] 버튼이 있고, 이를 눌러 PHP 소스코드를 확인할 수 있습니다.

 

 

  소스코드를 확인해 본 결과 총 3가지의 검증이 수행되는 것을 알 수 있습니다.

 

 

  ctype_alpha() 함수는 모두 알파벳으로 구성되어 있는지 확인합니다.

  is_numeric() 함수는 모두 숫자로 구성되어 있는지 확인합니다.

  md5() 함수는 말 그대로 MD5 해시 값을 구하는 함수입니다.

 

  다시 말해 알파벳으로만 구성된 문자열과 숫자로만 구성된 문자열의 MD5 해시값이 같은 경우를 찾으면 됩니다. 이러한 경우는 매우 흔치 않은 경우인데요. PHP의 취약점을 이용하면 쉽게 필터링을 우회할 수 있습니다. 사실 이러한 취약점에 대해서는 PHP 공식 매뉴얼에서 예시를 확인할 수 있습니다.

 

  PHP md5 매뉴얼 페이지: https://www.php.net/manual/en/function.md5.php

 

PHP: md5 - Manual

From the documentation on Digest::MD5:md5($data,...)This function will concatenate all arguments, calculate the MD5 digest of this "message", and return it in binary form.md5_hex($data,...)Same as md5(), but will return the digest in hexadecimal form. PHP'

www.php.net

 

  다음의 글을 보시면 '240610708'의 MD5 해시와 'QNKCDZO'의 MD5 해시를 단순히 == 연산자로 비교하는 경우 같다는 결과가 나온다고 합니다. 이는 PHP에서 == 연산자를 이용하는 경우 검증을 약하게 하기 때문이며, === 연산자를 이용하는 방식으로 보안을 강화할 수 있습니다.

 

 

  따라서 바로 한 번 입력 값을 대입하여 문제가 풀리는지 확인해보겠습니다.

 

 

  대입 결과 정상적으로 플래그(Flag) 값이 등장합니다.

 

 

 

728x90
반응형

728x90
반응형

  PHP에서 strcmp() 함수에 대한 문제인 것 같습니다. 마찬가지로 문제 유형은 웹 해킹이 되겠습니다.

 

 

  페이지에 접속하면 다음과 같이 소스코드를 확인할 수 있는 [view-source] 버튼이 보입니다.

 

 

  다음과 같이 소스코드를 확인할 수 있는데요. 한 번 소스코드를 분석해 보겠습니다.

 

 

  strcmp(A, B) 함수는 두 개의 문자열을 비교하는 대표적인 함수입니다. A가 B보다 작으면 음수 값, B가 작으면 양수 값, 그리고 같은 경우에 0을 반환합니다. 따라서 문제를 해결하기 위해서는 strcmp() 함수의 결과로 0이라는 값이 출력되어야 한다는 것을 알 수 있습니다.

 

  특정한 PHP 버전대에서는 strcmp()의 인자 값으로 배열을 넣는 경우 NULL 값이 반환된다고 합니다. 또한 PHP에서는 NULL과 0을 == 연산자를 이용하여 비교했을 때 같다(True) 값을 내뱉기 때문에 strcmp() 함수의 취약점을 이용하면 문제를 풀 수 있습니다. 이렇게 되는 이유는 == 연산자의 경우 느슨하게 검증을 수행하기 때문이라고 합니다.

 

  따라서 다음과 같이 개발자 도구(F12)를 실행하여 보내는 데이터의 형태를 password[]로 배열 형태로 변경하여 전송할 수 있습니다. 그러면 아무런 값이나 보내도 결과적으로 필터링을 우회할 수 있을 것입니다.

 

 

  사실 PHP에서도 === 연산자를 지원합니다. 이것을 이용하면 정확히 동일한 Type일 때에만 참(True) 값이 반환되기 때문에 이러한 취약점을 해결하기 위한 효과적인 방법이라고 할 수 있습니다.

 

 

 

728x90
반응형

728x90
반응형

  DB is really GOOD은 이름에서부터 알 수 있듯이 데이터베이스(Database) 관련 문제입니다.

 

 

  문제 풀이 사이트에 접속하면 다음과 같이 무언가 입력하여 접속하는 창이 등장합니다.

 

 

  공백 그대로 접속을 하면, 일종의 채팅방에 접속한 것과 같이 어떠한 내용을 기록하는 페이지가 등장합니다.

 

 

  이런 저런 방에 들어갈 수 있는 걸 확인할 수 있는데요. 다음과 같이 admin 채팅 방에 들어가려고 해보겠습니다.

 

 

  이 경우 admin 방으로는 접속할 수 없다고 합니다.

 

 

  이후에 정말 많은 값들을 대입해보았습니다. 퍼징(Fuzzing)을 하는 것은 반칙일 것 같아서 그럴싸한 것들을 많이 넣어 보았으며 그 중에서는 /를 넣어 보았습니다.

 

 

  그러자 다음과 같이 데이터베이스 관련 오류 메시지가 나오는 것을 확인할 수 있습니다. 사실 개발자 관점에서 웹 사이트를 배포할 때는 이러한 오류 로그가 클라이언트에게는 보이지 않도록 처리해야 하는데요. 그러한 처리의 부재로 인해 문제가 발생했다고 할 수 있습니다.

 

  오류 메시지를 확인해 보시면 다음과 같이 데이터베이스 파일을 열 수 없다고 하네요. 아무래도 SQL Lite을 이용하여 로컬 데이터베이스를 관리하고 있는 것 같고, 각 채팅방에 따른 DB 파일을 생성하여 거기에 기록하는 것 같습니다. 오류 메시지를 확인해 보시면 DB 파일의 경로는 ./db/wkrm_{채팅방 이름}.db이네요.

 

 

  실제로 특정 방의 데이터베이스 경로에 직접 접근을 해보니, 데이터베이스 파일이 다운로드 되는 것을 확인할 수 있습니다.

 

 

  파일을 에디터(Editor) 프로그램으로 열어 보니, 다음과 같이 임의의 문자열이 적혀 있습니다.

 

 

  따라서 같은 방법으로 ./db/wkrm_admin.db의 경로에 접속을 하니, 마찬가지로 admin 데이터베이스 정보 파일도 얻을 수 있었습니다. 해당 파일을 에디터 프로그램으로 열어 보니 다음과 같이 플래그(Flag)가 적혀 있는 주소가 등장합니다.

 

 

  해당 경로로 접속하여 플래그(Flag) 값을 얻을 수 있었습니다.

 

 

728x90
반응형

728x90
반응형

  md5 password 문제는 PHP에서 md5() 함수를 이용할 때의 주의사항에 대해서 알고 있는지 물어보는 문제입니다.

 

 

  문제 풀이 페이지에 접속하면 곧 바로 [get source] 버튼을 눌러 PHP 소스코드를 확인할 수 있습니다.

 

 

  본 문제는 md5() 함수가 취약하게 사용될 때에 대해서 물어보는 문제입니다. 이미 잘 알려진 취약점으로 md5({변수}, true)의 형태로 사용하게 될 때의 소스코드 오용에 대하여 물어보는 것입니다.

 

  아래 소스코드를 보시면 md5() 함수의 두 번째 파라미터에 true 값이 담기는 형태로 md5() 함수가 호출되었습니다. 두 번째 파라미터에 true 값이 담기게 되면 raw한 형태로 출력이 이루어집니다. 다시 말해 raw한 binary 형태로 출력이 되며, 이는 아스키(ASCII) 코드 형태로 처리될 수 있습니다. 이 때 MySQL 조건문의 특징을 이용하여 SQL Injection이 가능합니다.

 

 

  ▶ MySQL 온라인 컴파일러: https://paiza.io/en/projects/new?language=mysql

 

Online editor and compiler

Paiza.IO is online editor and compiler. Java, Ruby, Python, PHP, Perl, Swift, JavaScript... You can use for learning programming, scraping web sites, or writing batch

paiza.io

 

  다음의 MySQL 코드를 실습해보세요.

 

create table Test(id integer, password varchar(100));
insert into Test(id, password) values(1, "123123");
select * from Test where password = '' = '';

 

 

  MySQL에서는 데이터를 검색할 때 위와 같은 형태로 조건문을 작성하면 WHERE 조건절이 항상 참(True) 값을 가지게 되어 무조건 데이터를 조회하게 된다는 특징이 있습니다. 다시 말해 아래 소스코드에서 md5({사용자가 입력한 값}, true) 함수가 실행된 결과에서 '='라는 문자열이 포함된다면 조건문은 참 값을 가지게 되어 문제가 풀릴 수 있습니다.

 

 

  이 문제의 답은 직접 파이썬(Python) 소스코드를 작성하여 도출할 수 있습니다.

 

  파이썬(Python)에서의 md5() 함수는 바이트 형태의 데이터를 받아서 해시(Hash)화를 수행합니다. 그러한 해시 값에서 digest() 함수를 수행하면 해시 값이 바이트 데이터로 변환되어 출력됩니다.

 

  따라서 무작위 숫자를 대상으로 하여 해시 값을 만들어 낸 뒤에, 해당 해시 값에 '='의 바이트 값이 포함되어 있다면 이것을 정답으로 제시하여 플래그(Flag)를 얻을 수 있다는 의미입니다.

 

import hashlib

for i in range(0, 1000000):
    if b"'='" in hashlib.md5(str(i).encode()).digest():
        print('Found: {0}'.format(i))

 

  위 소스코드는 파이썬(Python) 개발환경이 없는 분들도 온라인 파이썬 컴파일러를 이용하여 실행하실 수 있습니다.

 

  ▶ 파이썬(Python) 온라인 컴파일러: https://www.onlinegdb.com/online_python_compiler

 

 

  따라서 얻어 낸 값 중에서 7201387을 골라서 넣어보겠습니다.

 

 

  플래그(Flag) 값을 찾았습니다.

 

 

 

 

728x90
반응형

728x90
반응형

  fly me to the moon 문제 또한 웹 해킹 문제 유형입니다. 자바스크립트(JavaScript) 클라이언트 단의 코드 분석을 통해 문제를 해결할 수 있습니다.

 

 

  [Start] 버튼을 누르면 간단한 형태의 오락실 게임이 등장합니다.

 

 

  게임을 대충 플레이한 뒤에 패배하시면, 다음과 같이 점수가 31337점이 되어야 한다고 합니다. 아무래도 고득점을 받아야 플래그(Flag) 값을 얻을 수 있을 것입니다. 어떻게 하면 플래그 값을 얻을 수 있을까요?

 

 

  난독화가 되어 있는 자바스크립트(JavaScript) 소스코드를 확인해야 합니다.

 

 

  이럴 때는 JS Beautifier를 이용할 수 있습니다. 매우 복잡한 난독화 기법이 사용되지 않은 경우, 간단한 형태의 난독화는 이러한 도구를 이용하면 풀리게 됩니다.

 

  ▶ JS Beautifier 홈페이지: https://beautifier.io/

 

  위 사이트에 접속하여 난독화 된 소스코드를 풀어 본 뒤에, 확인을 해보시면 this['getScore']라는 함수는 _0x8618x7() 함수와 동일합니다. 또한 _0x8618x7() 함수는 _0x8618x6이라는 변수의 값을 가져오는 함수입니다. 다시 말해 _0x8618x6이 점수(Score)를 의미하는 함수일 것이라고 예상할 수 있습니다.

 

 

  따라서 게임 페이지에서 개발자 도구(F12)를 실행하여, [Console] 탭으로 이동해서 다음과 같이 난독화가 풀린 소스코드를 통째로 복사한 뒤에 score에 해당하는 변수 값만 31,337로 변경하여 붙여넣기 할 수 있습니다.

 

 

  이후에 엔터(Enter)를 입력하여 적용한 뒤에 다시 게임을 플레이하면 정상적으로 Flag가 등장합니다.

 

 

 

728x90
반응형

728x90
반응형

  WTF_CODE 문제는 간단한 개발 관련 상식을 가지고 있는지, 혹은 모르는 내용을 인터넷에 적절히 검색하여 문제를 해결해 나갈 수 있는 능력이 있는지를 물어보는 문제 유형입니다.

 

 

  문제 풀이를 시작하면, 하나의 소스코드 파일을 제공합니다. 이를 다운로드 받아서 열어 볼 수 있습니다.

 

 

  실제로 에디터(Editor)나 브라우저를 하나 실행하여 이 파일을 열어 보면, 내부적으로 공백만 포함되어 있습니다.

 

 

  구글에서 .ws 확장자에 대해서 검색해 보면 Whitespace 프로그래밍 언어라고 나옵니다. 다시 말해 공백으로만 이루어진 프로그래밍 언어라는 의미인 것 같습니다. 온라인 IDE 중에서 이러한 프로그래밍 언어를 실행시켜주는 서비스가 있습니다.

 

  바로 ideone입니다. 홈페이지 주소: http://ideone.com/

 

  실제로 해당 온라인 IDE에 접속하여 소스코드 유형을 [Whitespace]로 설정한 뒤에 소스코드를 붙여넣기 하고, [Run] 버튼을 눌러 코드를 실행할 수 있습니다.

 

 

  실행 결과 다음과 같이 Key 값이 등장합니다.

 

 

 

728x90
반응형

728x90
반응형

  이 문제 또한 웹 해킹 유형의 문제입니다.

 

 

  문제 풀이를 시작하니 해당 페이지의 기능을 담당하는 PHP 소스코드를 보여주는 버튼이 등장합니다. [get source] 버튼을 눌러서 소스코드를 확인할 수 있습니다.

 

 

  소스코드를 확인합니다. 먼저 mysql_real_escape_string() 함수는 SQL Injection을 방어하기 위한 기본적인 함수입니다. trim() 함수는 사용자가 입력한 문자열에서 앞뒤 공백문자를 제거해주는 역할을 수행합니다.

 

  다시 말해 적절한 ID와 PW를 입력하여 로그인을 하면 플래그(Flag) 값이 나올 것 같습니다. 그렇다면 어떠한 아이디와 비밀번호를 입력해야 문제를 풀 수 있을까요? 이 문제는 문제 제목에서부터 볼 수 있듯이 필터링(Filtering)과 관련한 문제로 이해할 수 있습니다.

 

 

  이 문제는 SQL Injection 문제가 아닙니다. 페이지의 소스코드를 보면 다음과 같이 데이터베이스에 기록되어 있는 아이디 및 비밀번호 정보가 포함되어 있습니다. 따라서 SQL Injection 문제는 아니고, 인증에서의 필터링(Filtering) 우회 문제라고 할 수 있습니다.

 

  이 문제는 PHP는 문자열 비교에 있어서 대소문자를 구별하지만, MySQL은 기본적으로 대소문자를 구별하지 않는다는 점을 이용하면 풀 수 있습니다. (이는 MySQL을 이용하는 개발자들이 자주 간과하는 특징이기도 합니다.) 다시 말해 파라미터 $id 값의 문자열에 대문자를 끼워서 입력하면 문제를 풀 수 있습니다.

 

  예를 들어 아이디(ID) 값으로 GUEST라고 넣게 되면, 데이터베이스에 존재하는 guest라는 회원 정보 검색에 성공하기 때문에 GUEST라는 데이터를 얻습니다. 그렇기 때문에 필터링을 우회하여 블록(Block) 처리 된 사용자로 로그인을 할 수 있게 되는 것입니다.

 

 

  따라서 다음과 같이 아이디(ID)에 하나 이상의 대문자를 끼워서 ID 및 PW를 입력하면 문제가 풀립니다.

 

 

  다음과 같이 Password(Flag) 값이 등장합니다.

 

 

※ MySQL 대소문자 구별에 대하여 ※

 

  MySQL 온라인 컴파일러를 이용하면, 대소문자 구별을 정말 안 하는지 확인할 수 있습니다.

 

  https://paiza.io/en/projects/new?language=mysql

 

  위 사이트에 접속하여 다음과 같은 소스코드를 입력하여 실행해보세요.

 

create table Test(id integer, title varchar(100));
insert into Test(id, title) values(1, "Hello");
select * from Test where title = 'HELLO';

 

  실행 결과 정상적으로 데이터를 조회합니다.

 

 

728x90
반응형

728x90
반응형

  QR CODE PUZZLE 문제는 말 그대로 QR 코드를 찾아내는 문제입니다. 문제 유형은 웹 해킹입니다.

 

 

  문제 풀이 페이지로 이동하면 다음과 같이 QR 코드 퍼즐이 등장합니다. 다만 우리가 직접 퍼즐을 움직여서 QR 코드를 찾아내는 것은 쉽지 않을 것 같습니다.

 

 

  다만 개발자 도구(F12)를 실행하여 소스코드를 확인해 보면, #join_img라는 요소의 src 속성의 값을 변경하는 부분이 등장합니다. 이미지의 소스를 변경하겠다는 의미이므로, 이 소스 값이 원래 이미지를 나타내는 경로일 가능성이 높습니다.

 

 

  따라서 [Console] 탭으로 이동하여 해당 소스 부분의 문자열이 원래 어떤 것이었는지 확인합니다. 이렇게 콘솔 창에서 코드를 직접 실행하는 방식을 동적 분석 방식이라고 합니다.

 

 

  결과적으로 다음과 같이 해당 경로로 이동해보니, QR 코드 이미지가 등장했습니다.

 

 

  QR 코드는 온라인 디코더(Decoder) 서비스를 이용해서 직접 휴대폰으로 촬영하지 않아도 간단히 인식할 수 있습니다.

 

   ▶ ZXing Decoder 홈페이지: https://zxing.org/w/decode.jspx

 

 

  인식된 결과를 확인해 보니 다음과 같이 특정한 URL 주소가 등장했습니다.

 

 

  해당 URL 주소로 이동하니, 성공적으로 플래그(Flag) 값을 얻을 수 있었습니다.

 

728x90
반응형