오..! 그동안 손 못대던 리버싱 문제를 하나씩 손대고 있다! (기분이 좋다)

이번에는 Wargame.kr 의 리버싱 문제를 풀었다.
여기도 웹문제만 많이 풀었던 사이트였는데! ㅎㅎ

EASY_CrackMe 문제다!



(문제)



문제 프로그램을 받으면 키를 입력하라고 나온다.




(프로그램 실행)



역시! 여기에 알맞은 키를 찾는 것이다.

이 문제는 좀 오래걸렸다... 그것도 마지막에 운이 좋아서?...

일단 코드를 큰그림으로 보면 처음에 BL에 1을 넣어준다.



(BL에 1 대입)



자.. 이제부터 이 EBX 레지스터의 1을 지키는 험난한 과정이 시작된다.

처음에는 너무 이해가 안가서 코드 한줄한줄 분석하면서 흐름을 손으로 직접 그려보았다.



(흐름도)



이렇게 흐름도를 손으로 그려보니 내가 어떤 일을 해야하는 지 이해가 간다.
EBX 레지스터를 보호하는 여정이라는 사실도 그려보고 이해했다.

그런데 중간에 이해가 안가는 함수가 있었다... 

005024A9 함수인데... 바로 이녀석을 따라들어가면 또 거기서 함수를 호출하고
또 그안에서 함수를 호출한다.
분석이 너무 안되던 참에..

그 동안 알아낸 사실들을 정리해보았다.

입력값이 13글자 이상이여야한다. 
_my_b , birth 요 문자들이 들어가야한다.

그러고 보니 _my_birth  앞에 4글자 생일을 넣으면 14자리인거다...
혹시나 해서 생일을 어떤 연산을 하나 내 생을 집어넣고 돌려보았다. 




(내 생일)



005024A9 함수가 호출된 후 리턴된 EAX값을 보니 3FA....
내가 내 생일 16진수로 표현한 3FA를 아이디로 많이 사용해서 단번에 알아보았다...
16진수 표현이구나!



(16진수 표현)



그렇다면 리턴값 eax가 45A 여야한다는 뜻은
45A -> 1114(10) 으로 집어넣어야한다는 뜻...



(45A 비교)



즉 이 문제를 만든 사람 생일이 11월 14일인가보다..

이렇게 문자열을 조합하고 프로그램에 입력해보니!




(잘했다!)



잘했다고 인증키를 알려주었다.




(문제 해결!)


'WarGame > 500 Project' 카테고리의 다른 글

(42/500) - Lena's Tutorial 01  (0) 2017.07.05
(41/500) Wargame.kr - Crypto Crackme Basic  (0) 2017.06.28
(39/500) Suninatas - Binary(11)  (0) 2017.06.27
(38/500) Suninatas - Binary(10)  (0) 2017.06.27
(37/500) Suninatas - Binary(9)  (0) 2017.06.27


16번째로 푼 문제이다.! 
바로 blind sql injection! 음 정확히 말하면 블라인드?라고는 아무튼 인젝션 문제이다!

ip log table!


(ip log table)



문제 진입 전에 설명에 Ascii를 Date로 사용할 수 있다는 문구가 있다.
나는 오래 헤맨 뒤에야 이 문구의 의미를 깨달을 수있었다.



(힌트)



문제 페이지


(문제 페이지)



문제 페이지는 위와 같다.
아이피 가보이고 클릭해보면 해당 아이피의 접속 시간? 시간정보가 나온다.

소스코드를 열어서 확인해보니 hidden 값으로 몰래 값이 전달되고있었다.



(form)



idx에 값을 넣어 쿼리가 전달될 것이라고 생각해볼 수 있다.

즉 이 form문을 이용해 쿼리를 보낼 것이다.



(사용할 form문)



(사용할 form문 개조)



이 form을 이용하여 내 예상이지만 where idx=$_POST['idx']
요론 식으로 되어있지 않을까 예상이 된다.
idx니까 numeric이 겠지? 라는 기대를 가지고 1 or 1을 날려본다.



(1 or 1 injection)





(실행결과)



실행결과가 나온다.
사실 이 정보만으로 numeric이야 라고 섣불리 판단할 수 있지는 않다.
이유는 1 or 1 이렇게 전달했지만 웹 페이지 내에서 int만 parse 해서 사용하고 있을 수도 있고
그 외에 문자가 들어와서 디폴트로 줄수도 있고 다양한 변수들이 존재하지만

나의 수많은 쿼리들을 이 곳에 다 담을 수 없기에 정리한다 여기는 numeric으로 쿼터 없이 입력이 가능하다!

그 후 1 or 1 union select 77 limit 15,1 을 인젝션하다가 발견한 것이 있다.
여기서 limit 15,1 을 한 이유는 앞의 쿼리에서 14개의 행이 나오고 그 다음 내가 union 한 결과가 15행 부터 나오기에 15행 하나만 꺼내서 보기위해 그랬다.



(특이점 발견)





(특이점)



무심코 지나칠 뻔 했는데,
원래 없는 값은 1970-01-01 09:00:00 으로 나오다가
왠걸 조금 다른 값이 나온다.

불현듯 든 생각이 앞의 그 힌트였다. 혹시 데이터에 저장되고 있는것이 유닉스 타임 스탬프이고
그 값에 따라서 이 페이지에서 날짜 형태로 출력되는 걸까?
나는 유니온을 해서 77을 select 했다. 그 결과 01:17...
초로 따지면 77 !
다른 값으로 더 해보아 확인해보았다.

이제 정보를 알아낼 차례이다.!
나는 1 or 1 union select (숫자형태로 나오게 select 한글자) limit 15,1
요것을 이용하여 알아낼 것이다.

먼저 table 이름을 알아야한다.




(테이블 이름)





(테이블 이름 알아가는 중)



내가 알아낸 테이블 이름은 (기본적인거 빼고)
admin_table (누가봐도 수상하다.)
ip_    (여기까지 알아봤다. ip_table일거 같고 본 페이지에서 사용하는 테이블일 것이다.)
그 외의 테이블은 없었다.

문제 페이지에서 관리자로 로그인하는 페이지가 있었는데, 바로 관리자의 계정과 패스워드를 알아내라는 뜻인거 같다.

그렇다면 컬럼 이름을 알아내자!
컬럼이름을 쓰려면 ' ' 쿼터를 사용해야하는데, 확인은 안됬지만 왠지 쿼터정도는 막혀있을 예상이 들어 아싸라하게 char을 이용하여 컬럼이름을 검색해주었다.



(admin_table 다른 표현)



컬럼이름 알아내기 시작!



(컬럼이름 injection)





(찾아가는 중)



그 결과
id, ps
라는 2개의 컬럼만 있다는 사실을 알았다.

사실 이 정보는 관리자 로그인 페이지에서 form문에서 눈치 챌수 있었지만 확실히 하기 위해 찾아보았다.

그 다음은 id의 값을 알아낼 것이다!



(id injection)





(찾는 중)


찾아낸 아이디는 공개하지 않겠다! :)

그 다음은 비밀번호 찾기!



(비밀번호 injection)




(찾는 중)



비밀번호까지 찾았으니 관리자로 로그인 해본다!



(관리자로 로그인)





(문제 해결)



로그인 하니 바로 플래그가 나오고 문제를 해결할 수 있었다! :)




'WarGame > 500 Project' 카테고리의 다른 글

(18/500) Lord of the BOF - cobolt  (0) 2017.05.05
(17/500) Lord of the BOF - gremlin  (0) 2017.05.05
(15/500) Wargame.kr - lonely guys  (0) 2017.04.18
(14/500) Wargame.kr - strcmp  (0) 2017.04.16
(13/500) Wargame.kr - SimpleBoard  (0) 2017.04.16


14번째 푼 문제이다.!

문제이름은 strcmp!
strcmp의 취약점을 이용한 문제이다.



(strcmp 문제)



문제 페이지이다.




(문제 페이지)



패스워드를 입력 칸이 하나있고 체크 버튼이 있다.

소스코드를 확인해보겠다.



(소스코드)



소스코드를 보니 POST방식으로 값을 전달한 것이 password와 비교하여 같으면 flag를 보여준다.

이것은 strcmp 함수의 취약점을 이용했다.
구글에 strcmp 까지 입력하니까 취약점이 연관검색어로 나왔다.
으음..

확인해보니 입력해보니 입력 인자로 배열이 들어가면 0을 반환하게 되어있다. 혹은 버젼에 따라 NULL을 리턴하는데 0이든 NULL이든 우리 문제에서는 == 로 비교하기 때문에 참이 되게 된다.

즉 입력으로 배열을 넣어주면된다.
POST방식이므로 버프슈트로 값을 변조해서 보내줄 것이다.




(값 변조)



password[] 배열을 보내주었다.




(문제 해결)



Flag를 얻을 수 있었다. ! :)


'WarGame > 500 Project' 카테고리의 다른 글

(16/500) Wargame.kr - ip log table  (0) 2017.04.20
(15/500) Wargame.kr - lonely guys  (0) 2017.04.18
(13/500) Wargame.kr - SimpleBoard  (0) 2017.04.16
(12/500) Wargame.kr - tmitter  (0) 2017.04.15
(11/500) Wargame.kr - type confusion  (0) 2017.04.15



13번째로 푼 문제이다. :)
인젝션 문제이다.

문제 이름! SimpleBoard




(SimpleBoard)



문제 페이지이다.



(문제 페이지)



게시판 형식의 페이지이다.

소스코드를 확인 해보자!




(소스코드)



소스코드를 보니 완전한 소스코드가 아니라 클래스 부분만 따로 때어낸 코드를 주었다.

코드 안에서는 우리가 공략할 수 있는 쿼리문을 보여준다.
여기에 사용된 쿼리는 update와 select 쿼리가 사용되었다. update 쿼리는 조회수 정보를 저장할 때 사용되었고 select 쿼리는 게시글을 클릭하였을 때 게시물을 보여주기 위해 사용되었다.

그렇다면 이러한 쿼리들은 어떤 인자를 받아들여 쿼리를 실행할까?
게시글 아무거나 클릭해보았다.



(게시글 클릭)



클릭해보니 GET방식으로 idx를 넘겨주고 있다.

또 소스코드를 보면 idx를 통해 select를 하고 update를 한다.
정확히 GET으로 받은 idx를 사용하는지는 안나왔지만 클래스 코드를 보고 유추하자면 그렇다.

그렇다면 idx 변수에 injection을 담아 보내보자!
4 and 1 을 보내본다.



(4 and 1)



4번 글이 실행되었다.
이와 비교해서
4 and 0
을 Injection해보았다.




(4 and 0)



화면에 아무것도 나오지 않는다.
즉 이말은 4 and 0의 쿼리가 잘 전달되어 게시글을 가져오지 못했다는 것이다.

그렇다면 제일먼저 이 테이블의 컬럼수를 알아보기 위해
order by를 이용할 것이다.




(order by 1)



쿼리 에러

여기서 당황했지만 코드를 다시 잘 살펴보게 되는 계기가 되었다.




(소스코드)



여기서 idx값이 전달되면 쿼리가 2개가 실행되는데
update 쿼리를 잘보면 우리가 보낸 4 and 1 order by 1을 하게 되면 여기서 에러가 난다는 것을 알 수 있다. 즉 update 쿼리가 실행되지 않게 해야하는데 쿠키값으로 view를 관리하는 것을 볼 수 있다.
이 값에 봤다고 설정이 되있다면 update쿼리는 실행되지 않는다.

매번 쿠키를 설정해서 보내기 귀찮으므로 파이썬을 이용해 코드를 작성해보겠다.



(작성한 코드)



이 코드를 보면 4 or 1 order by 1 를 보낸다.



(결과)



결과를 보니 잘 나오는 듯했다.
하지만 잘나온것은 아니다 왜냐! 4번글이 출력되었기 때문에
정상적이라면 1번글이 나왔어야한다.

이유를 헤메다 보니 쿠키에 저장되는 값을 url 인코딩으로 해줘야한다.!
그렇기에 url 인코딩해서 보내주면



(url 인코딩 injection)



(실행결과)



실행 결과를 보면 1번 글이 출력된 것을 확인 할 수 있다.

이제 order by를 이용해 컬럼의 수를 찾아보겠다.



(order by 5 injection)




(쿼리 에러)



1,2,3 이렇게 늘려가다보니 5에서 에러가 났다.
컬럼의 수는 4개라는 것을 알 수 있었다.

이젠 4개의 컬럼이 맞는지 union select 를 이용해 확인해 보겠다.
원래 안에 글의 개수가 4개이므로 출력해줘야하는 글의 위치는 4 (0부터시작하므로)
limit 4,1 을 붙여주었다.




(확인 injection)




(실행결과)



실행결과를 보니 1,2,3,4 가 출력되는 것을 확인 할 수 있었다.

이제 테이블 이름을 알아야했다.
테이블 이름을 알기위해
select table_name,2,3,4 from information_schema.tables 를 이용할 것이다.



(테이블 이름 injection)



(실행결과)



실행 결과를 보니 CHARACTER_SETS이 나왔다.
나는 이게 지금 내가 검색하고 있는 테이블 이름인줄 착각했었다.. 하지만 여러 테이블 이름 중 하나였다.

즉 테이블 이름을 쭉 전부 검색해서 확인할 필요가 있었다.



(테이블 이름 injection)




(실행결과)



실행결과 쭉 보니 의심갈만한 테이블 이름이 있었다.
SimpleBoard 와 README 였다.

SimpleBoard을 살펴보니 우리가 문제 페이지에서 확인할 수 있는 페이지가 전부였다.

남은건 README!

하지만 컬럼 이름은 모르는데.. 컬럼이름을 찾을까 하다가
그래도 flag라는 컬럼이 있지 않겠어? 라는 심정으로 찍어봤는데



(flag injection)




(실행 결과)


flag가 정말 나왔다...
문제해결..!! :)


'WarGame > 500 Project' 카테고리의 다른 글

(15/500) Wargame.kr - lonely guys  (0) 2017.04.18
(14/500) Wargame.kr - strcmp  (0) 2017.04.16
(12/500) Wargame.kr - tmitter  (0) 2017.04.15
(11/500) Wargame.kr - type confusion  (0) 2017.04.15
(10/500) Wargame.kr - md5 password  (0) 2017.04.14


12번째로 푼 문제이다!

tmitter


(tmitter)



아래는 문제 페이지이다.


(문제 페이지)



문제 페이지 보니 로그인하는 버튼과 회원가입하는 버튼이 있다.

회원가입 페이지에 들어가서 이것저것 해보다가 소스코드를 보니 힌트가 있었다.



(힌트)



개인적으로 나에게 이 힌트가 매우 컸다.
이곳저곳 쑤시지 않고 여기만 공략하면 됬기에!! ㅎㅎ

admin 으로 회원가입을 하라는 말이다.
그렇다면 해보자!



(거부)



admin 계정이 이미 있다고 나온다.
역시..

그렇다면 분명 select 쿼리가 날라가서 db를 검색하여 자료가 있으면 이미 존재한다고 나오는거겠지??
라는 생각이 들었다.

흠 우선 admin' # 을 넣어 오류를 내보자!



(sql injection)



응??
' 앞에 역슬래쉬가 붙었다.
이 워게임 사이트 앞에서 php 코드를 살펴보니 그 injection 방지용으로 어떤 함수를 잘 쓰던데 그거 썻나보다. ' 앞에 이스케이프 된다.

그렇다면 널바이트는 어떻게 될까? 널바이트는 포스트로 전달 못하니
버프슈트를 이용해서 널바이트를 추가해서 보내보자!



(널바이트 삽입)



결과는...




(결과)



널바이트앞에도 이스케이프 문자가 붙는다.

역시..! 그 mysql_real_escape_string()을 쓰는거 같다.
아그러면 or나 이런거도 붙을텐데... 고민이 들었다.

일단 이 함수의 우회법은 안다.
바로 싱글 쿼터 앞에%bf를 넣어주면 %bf가 이스케이프 문자와 합쳐져서 싱글쿼터가 살아남는다.
그 뒤에 && 0 을 추가시켜주어 select 문에 아무것도 안나오게하고
그래서 회원가입이 되게 하는게 나의 전략이다.



(sql injection)



실행결과 회원가입이 되었다.!

정한 비밀번호로 로그인을 해보면




(로그인)



로그인이 되고 flag를 찾을 수 있다.!



(문제 해결)

'WarGame > 500 Project' 카테고리의 다른 글

(14/500) Wargame.kr - strcmp  (0) 2017.04.16
(13/500) Wargame.kr - SimpleBoard  (0) 2017.04.16
(11/500) Wargame.kr - type confusion  (0) 2017.04.15
(10/500) Wargame.kr - md5 password  (0) 2017.04.14
(9/500) Wargame.kr - md5_compare  (0) 2017.04.13



11번째로 푼 문제이다.

제목은 타입 혼란??
type confusion



(type confusion)



문제 페이지는 아래와 같다.



(문제 페이지)




체크박스 하나있고 소스코드를 볼 수 있는 링크가 있다.

소스코드를 살펴보겠다.




(소스코드 분석)



소스코드를 정리하자면
POST방식으로 json 변수에 값을 넣어 전달해야하고
그 값의 key값이 페이지 내 생성된 key값과 같으면 flag가 나온다.

여기서 key값은 임의로 생성되므로 알아낼 길이 없다.
다만 비교연산자를 == 로 쓰는것을 보아 이 취약점을 이용하면 풀릴거라는 생각이 들었다.

전에 비교연산자로 인해 며칠을 고민했던 터라 이번 문제는 쉽게 풀 수 있었다.

바로 ==로 비교할때 문자는 0으로 변환되기 때문에 숫자 0과 비교하면 참이 나온다.


(비교 참)



그렇다면 나는 key에 0을 넣어 json 인코딩해서 넣어주면 된다!



(json 인코딩)



그런데 POST라면서 보낼 폼이 없다... 저기 체크박스도 name이 다르게 설정되어 안된다..

그래서 내가 만들어서 보냈다.




(son 값 보내기 폼)



만든 폼을
관리자모드에서 적어주어 폼을 보내준다.



(폼 작성)





(보내기)



보내면 flag가 나오고 문제가 풀린다! :)



(문제 해결)


'WarGame > 500 Project' 카테고리의 다른 글

(13/500) Wargame.kr - SimpleBoard  (0) 2017.04.16
(12/500) Wargame.kr - tmitter  (0) 2017.04.15
(10/500) Wargame.kr - md5 password  (0) 2017.04.14
(9/500) Wargame.kr - md5_compare  (0) 2017.04.13
(8/500) Wargame.kr - fly me to the moon  (0) 2017.04.13


10번째 푼 문제이다! 

이름은 md5 password 이다.


(md5 password)



아래는 문제 페이지이다.




(문제 페이지)



비밀번호를 입력하는 칸이 하나 나온다.

소스코드를 보면 해시된 값을 넣어 테이블에서 select 검색을 한다.
그런데 조금 이상한 점이 있다.



(소스코드)



바로 md5 해시 함수에서 2번째 인자로 true를 주었다는 것이다.

기본적으로 디폴트 값은 default 이다.
이 값이 true로 넘어가게 되면 출력이 바이너리로 출력되게 된다. 근데 이게 바로 취약할 수 있다는 것이다. 해시 되는 과정에서 ' (싱글쿼터) 등 공격자가 필요한 특수문자를 만들어낼 수 있기 때문이다.

우리가 원하는 값은 '=' 이 값이 있으면 된다. 왜냐?
쿼리문장에서 where password='sdfds'='gfgfg' 
이런식으로 만들어주어 이렇게 되면 참으로 출력이되어 모든 값이 출력되기 때문이다.

예를들어 아래와 같이


(원하는 해시값)



우리가 원하는 해시값이다.

이렇게 나오는 저 값을 입력하게 되면 로그인이 되고 플래그가 나오게 된다.



(문제 해결)


'WarGame > 500 Project' 카테고리의 다른 글

(12/500) Wargame.kr - tmitter  (0) 2017.04.15
(11/500) Wargame.kr - type confusion  (0) 2017.04.15
(9/500) Wargame.kr - md5_compare  (0) 2017.04.13
(8/500) Wargame.kr - fly me to the moon  (0) 2017.04.13
(7/500) Wargame.kr - WTF_CODE  (0) 2017.04.12

+ Recent posts