[H3X0R CTF 2016]

Misc_20

is_this_real_hex



대회 시작부터 공개되었던 20점짜리 misc문제입니다. 초반에 다들 이 문제만 푸셨었더라구요..

무슨 문제인지 확인 해 봅시다.



문제를 다운받으면 26바이트짜리 파일이 있습니다.



출력 해 보니 깨진 문자를 포함한 스트링이 출력됩니다.



문제가 hex가 관련되어있으니 hexdump로 hex값을 뽑아봅니다.



python으로 해당 hex값을 1부터 더해주는 스크립트를 작성해봤습니다.



더하는 결과값으로는 플래그에 관련된 값을 찾을 수 없었습니다.



이제 빼봅시다.



모든 hex값에서 10을 뺐을 때

 

fl[g iy ^ong\in iy yo \}z_ 


라는 문자열이 출력되었습니다.

뭔가 flag 관련된 문자열인듯 하여 이 값을 파보았습니다.



[는 a가 될 것이고, y는 s가 되는 것 같습니다.

그리고 원래의 hex값이 95일 때 _가 됩니다.(문제 힌트에 format is FLAG_IS_THIS_FLAG 와 같이 주어졌습니다.)

확인 해 본 결과, 3, 7, 9, 13, 18, 20, 23, 24, 25, 26번째 자리가 변환되어있었으며, 각각 -10 한 결과에서 +6이나 -6만큼 해줄 때 알파벳으로 출력이 되었습니다.

위 코드처럼 직접 인덱스를 박아줘도 되지만, +6, -6 한 결과가 알파벳의 범위에 있을 경우 출력하는 코드로 작성해도 무방합니다.



위 플래그 값을 대문자로 입력 해주면 됩니다.


FLAG_IS_DONGBIN_IS_SO_CUTE

[H3X0R CTF 2016]

Web_63

php_encrypt



대회 중반에 공개된 63점짜리 Web 문제입니다. 파일을 다운 받은 후 압축을 풀면 php_encrpyt.php라는 파일이 나타납니다. 이 파일을 열어보면 아래 그림과 같은 소스가 나타납니다.



대회 이름에 맞게 변수명이 약간 복잡하게 되어 있습니다. 직접 계산해서 돌려도 되지만, 편하게 php 서버를 돌려 값을 찾아내도록 하겠습니다.

먼저, 알아 낼 수 있는 것들을 알아내보죠.


$_b는 ord

$_는 ?

두 번째 $__는 $_GET['?']입니다.

그렇다면 11번째 라인의 $__[0]은 $_GET['?'][0]으로 볼 수 있겠네요. 1, 2, 3도 마찬가지로 생각 할 수 있습니다.



해당 php소스를 돌려보면 위와 같은 결과 값이 나옵니다. 소스대로, 일정 조건을 만족하지 않으면 ?와 !를 출력하게 됩니다.

이 조건을 만족하는 4자리의 값이 flag일 것 같네요.



해당하는 값을 echo로 바로 때려줍시다.



4번째 자리는 'z'로 이미 명시되어 있기 때문에 출력하지 않았습니다.

이를 이어보면 f9!z가 되겠네요.



flag is f9!z



[H3X0R CTF 2016]

Web_10

cmp



대회 초중반쯤 공개 된 10점짜리 web 문제입니다. 친구들이랑 저녁밥 먹고 다시 들어와 보니 공개 되어 있었죠.. 확인 해 봅시다.


패스워드를 입력하는 text box와 submit 버튼 하나가 있습니다.

여기에 아무 문자나 입력을 하고 submit 해 봅시다.




A를 submit 해 보았더니 2라는 결과값을 뱉어냈습니다.



d를 입력 했을 때는 -33이 나왔습니다.


PHP strcmp() 함수의 반환값의 특성을 이용한 문제인 것 같습니다. 이 문제에서 str1은 flag, str2는 string을 가리키고 있는 것 같습니다.

아스키 코드 상으로 A보다 2만큼 위에 있는 문자는 C입니다. 



C를 입력해주니 15라는 값을 반환 해 주었습니다. C에 이어 다른 글자를 입력 해 주었을 때 위와 같이 양/음수로 나누어 출력을 해 주었습니다.



다른 문자들을 집어 넣어 2번째 문자는 0임을 알 수 있었습니다. 올바른 문자를 입력 했을 때 반환하는 숫자 값이 1씩 줄어드는 것을 보니, 이 값은 남은 string의 길이 같습니다. flag의 총 글자 수는 16인 것을 여기서 알 수 있었습니다.



사실 python으로 스크립트를 작성하여 브포를 돌려볼까도 생각 해 봤지만, 음수도 있고, 반환하는 숫자 값도 일정하지 않아 직접 손으로 브포를 했습니다...

(저 숫자가 남은 글자 수인 것을 알아 낸 타이밍이 4자 이상 찾았을 때라... 귀찮기도 했습니다.)



flag is C0MP4R3_15_900D!



[H3X0R CTF 2016]

Misc_1

mic_no_check



대회 초반에 공개 됐던 misc 1점짜리 문제입니다.



nc로 주어진 ip, port로 접속하면 echo : 라는 문구가 나옵니다. string 값을 입력 받는 것 같네요.



;sh를 입력해주면 shell이 떨어지게 됩니다.

id를 입력 해 보니 mic_no_check_solved 권한으로 로그인 되어 있는 것을 확인 할 수 있습니다.



아마 flag라는 이름으로 flag가 있을 것이니, 검색을 해 줍시다. 

find / -name flag 2>/dev/null 로 결과값만 빠르게 확인 할 수 있습니다.

Write Up을 쓰고 있는 현재, 서버 응답이 상당히 느리기 때문에 대회 당시에 찾았던 경로를 바로 사용하겠습니다.



해당 경로로 이동해 flag 값을 읽어주면 flag를 찾을 수 있습니다.


flag is RESPECT_CODEGATE





대회가 끝나서 하는 말이지만... vim은 터미널이 아니라 사용 할 수 없었지만 /tmp 경로에서


echo "#include<stdio.h>

int main(int argc, char *argv[]){

printf("Hello World!\n");

return 0;

}" > test.c


gcc -o test test.c


./test


위와 같은 형식으로 컴파일 및 파일 구동까지 모두 가능했었습니다. 물론 gdb와 파이썬도 돌아갔구요.

해당 id의 권한을 제한하지 않은 것이 큰 문제였던 것 같습니다.

[H3X0R CTF 2016]

Reversing_200

RPG Game


코드게이트 대학생 세션을 제외하고는 2016년에 처음 참가하는 CTF입니다.

디미고 H3X0R 팀에서 주최하는 CTF인데, 초반 대회 운영 및 문제마다 자잘한 버그/취약점이 하나,둘씩 있어 약간 아쉬웠던 대회였습니다.

이 문제는 대회 초반에 공개된 RPG Game 문제입니다.



바이너리를 실행했을 때의 화면입니다.

Stage1부터 30까지 이루어져있으며 아무 키나 입력하면 HP가 1씩 줄어듭니다. HP를 모두 소진시키면 다음 스테이지로 자동으로 넘어갑니다. 하지만 스테이지가 다음으로 넘어가면 넘어갈수록 기하급수적으로 HP가 늘어나기 때문에 직접 HP를 깎기엔 힘드니 디버거를 통해 값을 바꿔줘야합니다. 일단 이뮤니티로 해당 바이너리를 열어보았습니다.



스트링 값을 확인 해 봤더니 위에서 언급한대로 30까지의 스테이지가 있다는 것을 유추 해 볼 수 있고, WSAStartup() 함수와 hSocketet() 함수, connect() 함수의 존재로 보아 소켓 통신을 한다는 사실을 알 수 있습니다.



conncet() 부분으로 이동 해 보니 send 함수가 있습니다. 여기로 어떤 값을 보내고, recv로 응답값을 수신하는 것 같습니다. 아마 이 부분에서 flag를 받아올 것 같습니다.



HP와 스테이지 값을 손쉽게 바꾸기 위해 Cheat Engine을 추가로 붙여주었습니다.

HP 값과 스테이지 값을 찾아 값을 변경 후, FIX 해 줍시다.



HP값을 왼쪽의 Active 버튼을 눌러 FIX 한 후, 이뮤니티에서 send 부분에 브포를 걸고 어떤 값을 송/수신 하는지 확인 해 보았습니다.



처음 봤을땐 Base64 인코딩인 줄 알았지만, 중간중간에 섞인 특수문자로 보아, 암호화 된 스트링인 것 같습니다.



recv 부분을 보니 받아온 값이 CRACKED! 라는 응답값이었습니다. 아마도 send 부분에서 올바른 값을 보내지 않으면 CRACKED!라는 문구를 뱉어내는 것 같습니다. 여기서 생각 해 볼 수 있는 것은 1에서 바로 30단계로 갔기 때문에 송신 값이 제대로 복호화 되지 않은 채로 넘어갔기 때문이라고 볼 수 있습니다. 그렇다면 1 -> 30이 아닌, 차례대로 30단계까지 가는 방법을 이용해보죠.



스테이지 값을 찾을 필요가 없으니, HP값만 찾아 FIX해줍시다.



10단계까지 왔을 때 HP 양입니다.

1410065408로, 여기서 2배가 된다면 4Byte INT형 변수의 최대 값인 2147483647을 넘어가게 됩니다.



그래서 11단계로 왔을 때 -값에서 더이상 다음 스테이지로 넘어가지 않습니다.



따라서 Cheat Engine에서 값의 Type를 4Byte에서 8Byte로 확장해줍시다.



그러면 값의 제한이 없어 30단계까지 정상적으로 클리어 할 수 있습니다.



다시 이뮤니티로 넘어와 send하는 값을 보니, flag같은 값이 넘어갑니다. 하지만 여기는 send하는 부분이니 recv 값까지 확인 해 봅시다.



위와 같이 base64로 인코딩 된 것 같은 스트링 값을 뱉어냈습니다.



notepad로 복사 해두고, 디코딩 해 봅시다.


Flag is RpG_G@mE_CraCk!

Webhacking.kr

Prob40



웹케얄 40번 문제입니다. 500점짜리 문제라 고생을 많이 한 것 같습니다.

일단 문제에 접속하면 위와 같은 로그인 폼이 나옵니다. no, id, pw 값에 1, guest, guest가 자동으로 입력되어있습니다.



그대로 로그인을 해주면 "Success - guest" 라는 메시지를 출력해줍니다.



만약 이 값들 중 하나라도 틀리게 된다면



이와 같은 "Failure" 메시지를 뱉어냅니다.



계속된 삽질 가운데, no 부분이 integer로 값을 받는다는 것을 알아냈습니다. 그래서 &&을 이용하여 select문을 사용해봤더니



정상적으로 로그인이 됩니다.

이를 이용하여 admin이 담겨있는 row로 추정되는 no=2에 해당하는 값을 빼오기 위해 아래와 같이 입력해줍니다.



위 쿼리는 no가 2일때 1을, 아닐 때 0을 출력해주는데, no=2가 admin이라고 가정하고 사용한 쿼리입니다.



로그인을 하면 admin의 패스워드를 요구하는 웹페이지가 나타납니다.



이제 admin의 패스워드를 알아내야하는데, 간단하게 "pw like %"와 같은 쿼리를 이용하여 패스워드를 찾아내도록 합시다.



python으로 pw 값을 찾아내는 스크립트를 작성하였습니다.



찾아낸 admin의 pw 값은 LUCK_ADMIN입니다.



애초에 mysql에서 대/소문자 구분이 없기 때문에 대문자로만 찾아냈습니다. 하지만 LUCK_ADMIN을 입력했을 때 Wrong!을 뱉어내기에 소문자로 luck_admin을 입력해주었습니다.



짠!




References

- THX to Zairo!!(http://zairo.tistory.com)

'Wargame > Webhacking.kr' 카테고리의 다른 글

Webhacking.kr old-02(500)  (0) 2019.09.22
Webhacking.kr old-01(200)  (0) 2019.09.22
Webhacking.kr Prob53  (0) 2016.05.11
Webhacking.kr Prob48  (0) 2016.05.11
Webhacking.kr Prob60  (0) 2016.05.11

Webhacking.kr

Prob53


53번 문제입니다. 들어가자마자 hello wolrd로 우릴 반겨줍니다.

index.phps가 될 것 같으니 한번 들어가보죠.




소스를 보니 sql injection인 것 같습니다. 예전에 풀다 포기했던것까지 포함하면 2일 넘게 삽질을 했었는데... 후

결론부터 말하자면 함수를 모르면 풀 수 없는 문제입니다.

table name을 찾는 것이 목표인데 select와 from, union 모두 필터링이 걸려있어 information_schema에서 table_name을 추출 해 올 수가 없습니다. 여기서는 procedure analyse() 함수를 이용해서 table_name을 가져 올 수 있습니다.



소스에서 확인 한 대로 val 변수에 1을 집어넣어봅시다. test라는 값이 나오네요.



여기에 위에서 언급한 procedure analyse() 함수를 사용하면 db.table_name.value의 포맷으로 값이 나옵니다.

여기서는 db_name이 oldzombie, table_name이 Chal12NGe_53_TabLE_zz가 되겠습니다.


짠!




References

- THX to Zairo(http://zairo.tistory.com)

http://hyunmini.tistory.com/46

'Wargame > Webhacking.kr' 카테고리의 다른 글

Webhacking.kr old-01(200)  (0) 2019.09.22
Webhacking.kr Prob40  (0) 2016.05.13
Webhacking.kr Prob48  (0) 2016.05.11
Webhacking.kr Prob60  (0) 2016.05.11
Webhacking.kr prob59  (0) 2016.05.11

Webhacking.kr

Prob48



웹케얄 48번 문제입니다. 350점짜리 문제인데 풀고 나니 생각보다 쉬운 것 같습니다.

문제를 접속하면 위와 같은 화면이 나오는데, 파일 업로드를 할 수 있는 메모장을 구현 해 놓았습니다.

소스를 한번 확인 해 보겠습니다.



사실 처음 접근한 방법은 파일 업로드 취약점 또는 다운로드 취약점으로 생각하고 업로드 위주로 공격을 해 보았지만 실패하였고, filename으로 소스코드 자체를 바꿀 수 있기 때문에 시도해봤지만 파일 이름의 길이가 3자 이내로 제한되어 있어 실패하였습니다. 풀어본 결과, 이 문제는 파일 업/다운로드 취약점이 아니었습니다.

본론으로 돌아와서, 소스를 보고 알 수 있는 것은 현재 디렉토리에서 *.jpg 파일에 접근이 가능하다는 것입니다.



3.jpg는 초록색 슬라임 그림입니다. 글쓴이들의 프로필사진에도 있는 그림입니다. 귀엽네요.

1부터 모두 접근 해 본 결과, jpg파일은 1~8까지의 숫자로 이루어져 있었습니다.

하나하나 받기 귀찮으니 파이썬으로 코드를 짜서 실행해보죠.



wget으로 jpg 파일을 받는 코드를 작성해봅니다.



모두 받아주고



ls로 정보를 떠보니 유독 1.jpg만 파일의 크기가 크다는 것을 알 수 있습니다.

cat으로 파일을 읽어보니 아니나 다를까, php 코드가 숨어있었습니다.



아래 소스가 해당 코드입니다.



별다른 내용이 없는데, 21라인을 보면 zwitter_admin.php가 있는 것을 확인 할 수 있습니다.

수상하지 않나요? 질러봅시다.



짠!

'Wargame > Webhacking.kr' 카테고리의 다른 글

Webhacking.kr old-01(200)  (0) 2019.09.22
Webhacking.kr Prob40  (0) 2016.05.13
Webhacking.kr Prob53  (0) 2016.05.11
Webhacking.kr Prob60  (0) 2016.05.11
Webhacking.kr prob59  (0) 2016.05.11

Webhacking.kr

Prob60




60번 문제입니다. 들어가자마자 Access Denied를 뱉어내면서 우릴 밀어냅니다.

소스를 한번 확인해보도록 하죠.




PHPSESSID 값에 숫자가 들어있을 때 해당 문구를 뱉으면서 종료시키는 소스였네요.

그리고 아래 부분을 보면 세션id의 이름으로 파일을 하나 생성하는데, 내용 역시 세션id입니다.

그런데 접속하는 주소가 127.0.0.1일 경우 1초간 슬립 후 해당 파일을 삭제시킵니다.

중요한 점은 가운데 if문인데, mode 변수가 auth로 들어올 경우 해당 파일을 읽어 이름과 내용의 일치 여부 파악 후 일치할 경우 클리어 되는 부분입니다.

하지만 파일은 만들어지고 1초 뒤에 삭제가 되기 때문에 그 사이에 파일을 읽어줄 필요가 있습니다.

이 때 알아야 되는 개념이 레이스 컨디션입니다.

레이스 컨디션이란 말 그대로 경주, 경쟁자 상태를 말합니다. 서로 경쟁하는 사람들처럼 2개 이상의 프로그램이 동시에 돌아가며 서로 영향을 끼치는 상태를 의미합니다.

웹 해킹에서의 레이스 컨디션 뿐만 아니라 시스템 해킹에서도 사용되는 개념입니다.

그럼 차례대로 문제를 해결해보도록 하겠습니다.



크롬의 확장프로그램인 EditThisCookie를 이용하여 PHPSESSID를 변조시키겠습니다. 현재 PHPSESSID의 값에는 숫자가 포함되어있기 때문에 이를 없애줘야합니다.



숫자만 제거하고 영문은 그대로 놔두고 적용시키겠습니다.



세션에 해당하는 쿠키 값을 변조했기 때문에 이 바꾼 쿠키 값을 서버에 다시 저장해줄 필요가 있습니다. 다시 로그인 해 줍시다.



숫자를 제거한 세션ID로 로그인 되었습니다. Access Denied 메시지가 뜨지 않고 정상적으로 웹페이지에 접속 된 것을 확인 할 수 있습니다.



문제를 해결하기 위해 mode 변수를 auth로 GET요청을 통해 날려줍시다. 하지만 앞서 말했듯이, 1초 뒤에 파일은 삭제되기 때문에 레이스컨디션을 이용해 동시에 접속할 필요가 있습니다. 이를 위해 시크릿모드로 새 세션을 열어주었습니다.



새 세션에서도 위와 동일하게 쿠키 값을 바꾼 후 로그인 해줍니다. 그 후 두 윈도우에서 연속으로 refresh를 해주면 생성되는 파일을 read하면서 문제가 클리어됩니다.



이번 문제는 레이스컨디션에 대한 사전지식이 없을 경우 풀이하기 어려움이 있었던 문제입니다.

레이스컨디션에 대한 상세한 정보는 구글링을 통해 알아보시면 될 것 같습니다.

'Wargame > Webhacking.kr' 카테고리의 다른 글

Webhacking.kr old-01(200)  (0) 2019.09.22
Webhacking.kr Prob40  (0) 2016.05.13
Webhacking.kr Prob53  (0) 2016.05.11
Webhacking.kr Prob48  (0) 2016.05.11
Webhacking.kr prob59  (0) 2016.05.11

Webhacking.kr

prob59





Webhacking.kr 59번 문제입니다.

딱 보니 sql injection을 위한 문제인 것 같습니다.

소스를 한번 확인해 보도록 하죠.



get이 아닌 post로 요청을 하네요.

id와 phone이 join에 필요한 파라미터, lid와 lphone이 로그인에 필요한 파라미터입니다.

만약 로그인 했을때 결과값의 lv이 admin일 때 클리어 할 수 있는 조건이 붙어있습니다.

join을 할 때는 여러가지 필터링이 걸려있는데, id와 phone 모두 admin이라는 단어를 필터링하고 sql injection을 위한 핵심 키워드들이 필터링 되어있습니다.

여기서 저는 id 부분에서 SQLi를 시도해보았지만 결국 모두 실패했습니다. Single Quotation으로 묶여있기 때문에 문자열 취급을 받아 정상적인 쿼리로 날아가는게 원인이었습니다. 이 문제에서는 id가 아닌 phone 부분을 공격 벡터로 이용하여 injection을 해야합니다.



위와 같이 쿼리를 작성했습니다. id에는 quotation이 먹히지 않기 때문에 단순히 참조하기 위한 수단으로만 사용합니다.

우리는 phone에서 reverse(id)를 이용해 admin을 입력해주기 위해 id의 값에 admin의 반대인 nimda를 입력해줍니다.

그리고 위와 같이 입력할 때 완성되는 쿼리문은 아래와 같습니다.


insert into c59 values('nimda',1,reverse(id)),(1,1,'guest');


(이 쿼리문은 insert문을 이용할때 insert into table values('A', 'A'),('B', 'B')와 같은 쿼리를 날려줄 때 한번에 여러 값을 동시에 넣을 수 있는 것을 이용한 쿼리문입니다.)

그렇다면 db에 들어갈 때는 reverse(id)에 의해 admin으로 변환되어 nimda/1 계정의 lv은 admin으로 들어갑니다.



로그인 해 봅시다.



짠!





-thx to Zairo(http://zairo.tistory.com)

'Wargame > Webhacking.kr' 카테고리의 다른 글

Webhacking.kr old-01(200)  (0) 2019.09.22
Webhacking.kr Prob40  (0) 2016.05.13
Webhacking.kr Prob53  (0) 2016.05.11
Webhacking.kr Prob48  (0) 2016.05.11
Webhacking.kr Prob60  (0) 2016.05.11

+ Recent posts