[yummyCTF] 3rd. Router
이번 리버싱 문제 중 마지막 문제인 라우터 문제예요!!
백문이 불여일견!! 역시 문제를 먼저 짜잔 하고 만나야겠져!? (참 글쓰는 날짜인 18-09-01 을 기준으로)오늘 SUAx 컨퍼런스에 Security Plus 박형근 실장님과, Blackperl Security 심준보 CTO 님이 오시기로 되어있어여!! 포스터는 첨부 짜잔!
제가 왜 홍보를 하고있는지는 모르겠으나.. 자의적으로 홍보하고싶어서요!! Sua CTF 2회 결산이기도 하면서 블랙펄 기술이사님이 오신다구하니까연!! 전 꼭 감니다 꺄륵~
역시 야미의 문두는 잡담부터 시작이져!! 이제 고럼 실제로 문제쪽으로 넘어가볼까욧!?
3rd_router.zip 이라는 압축파일로 문제를 냈어요! 어휴 저 용량봐.. 14MB.. 요게 Qt Framework 를 필요한만큼 넣었는데에도 저렇게 많이먹더라구용 ㅜㅜ
그리고 .DS_Store 는 윈도우에서도 많이 보셨을테지만.. __MACOSX 라는 디렉터리는 맥에서 아카이브 압축하면 꼭 생기더군여!! 백업본으로 만들어놓는건지 잘은 모르겠지만영 히히
이렇게 3rd_router 디렉터리 내에 3rd_router.sh 스크립트 파일과, opt_yummy.tar 압축파일, router_ip 파일과 start_router.sh 스크립트 파일이 있어요! 뮤슨 파일인지 궁큼하면 역시 확인이 먼저 아니겠슴니까!!
오홍... start_router.sh 스크립트를 실행시키면 root 권한일 때 바이너리가 동작할 수 있도록 환경을 맞춰주는군녀!! 그리고 root일 때 3rd_router.sh 스크립트를 실행시키면 Qt 환경을 맞춰주구여! LD_LIBRARY_PATH 를 넣어서 이제 바이너리가 실행될 수 있도록 해주나봄니다!! 고럼 한 번 router_ip 바이너리를 실행시켜볼까욤?
현재 시스템의 NIC 를 이용해서 IP, MAC, Router IP 를 가져오는 프로그램이었네용!! 그런데.. 라우터 IP가 넘나 이상하네염? 왜 2.0.0.0 이징 최소한 192.168.X.X 일것가툰디.. 이 라우터의 값이 제대로 나와야 플래그값이 올바르게 나오나봐여!!
(ㅜㅠ 뭔 문제가 전부 플래그를 먼저 도출시켜가지고 혼란을 야기하는지 참.. 죄송함미당 ㅜㅠ리버싱 문제를 풀어본 적도 많지 않구 만들어 본 적도 없다보닝... 나중에 들어보니 요기조기 숨겨놓아서 꼭 가젯처럼 뭐 그로케 할 슈 있나보더군녀!! 잘 숙지해두겠슴미다 히히)
고럼 한 번 gdb로 열어봅씨다!!
오홍 메인함수에 뭐.. QByteArray, QMessageLogger, QDebug.. Qt 클래스들이 요곳조곳 있네욤! 그리고 사용자 정의함수인 get_gateway(), popen_usesd() 함수도 보이구여!! 이 똥멍충이 출제자(야미 본인)는 당연히 라이브러리를 건들 줄 몰랐을테니 저런 작명센스없는 함수들에 문제가있겠져!? 그리구 router ip 쪽이었으니 get_gateway() 쪽일 확률이 크군녀!!
음.. 우선 이 함수 전문을 보는게 낫겠어욤 처음 들어온 곳은 일반적인 함수같아욤. 변수 선언하구, socket 열구, memset 으로 초기화 해주구..
드디어 처음보는 함수를 호출하는 곳을 찾았어욤!! 무엇을 매개변수로 보내는지두 모르겠구.. 빨간 네모 아래에서도 malloc을 왜하는건지는 모르겠지만!! 현재 get_gateway() 함수에 뭐가 없다면 저 함수가 아무래도 수상하지 않을까 싶긴해요!! 우선 그 아래로 내려가봅씨다!!
ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ누가봐도 웃긴상황맞져!? ㅋㅋㅋㅋㅋㅋㅋㅋ파라미터가 저런 함수가 있다구여..!? 지저-분한데요!? 여태까지 저런함수 없었으면서!!!!
세상세상 "나 수상하오~" 하는 함수가 떡하니 있으니 그냥 쟤는 범인임이 확실해보여요!! 뒤에 볼 필요도 없이 저길로 이동해도 괜찮겠네요! ㅋㅋㅋㅋ
함수에 파라미터가 많으니 참 길어지네욤 ㅜㅜ보기 불-편함니당 히히 역시 불-편할땐 화사의 50000상!!
ㅋㅋㅋ요즘 오픈채팅방에서 자주 보고 있슴미다 50000상!
어참 제가 말씀드렸던가욤? 요즘 야미가 여기저기 오픈채팅에 들어가있다는 소식이... 일하기 싫어서 카톡만 주구장창 하려고...
아 아닙니다 절대 그렇지 않아욤!! 일이 얼마나많은데 제가 감히 그럴슈가 있어욤!! 기획도하랴, 문서관리 및 보고서작성, 에이전트 PM하랴, 서버-클라 통신맞추랴, 외근나가랴 버그패치하랴 담당자 응대하랴.. 일하는 직무 무엇? ㅜㅜ
보안에 관한 톡방, C언어 개발 톡방에만 딱 담그고이씀니다!! 제가 관심있는쪽은 이쪽이니깐욤!! 히히 :P
또 길이 새부렀네용!! 저 기나긴 파라미터의 parseRoutes 함수를 보니 초반에 변수 세팅한 후에 오오.. parseRouter+591 로 넘겨버리는 jg, jb 인스트럭션쪽 있지여!? 각각 +153, +173 부분이네여!! 이거 아무리봐도 조건에따른 loop 탈출구멍이잖아여!? 이거 for 문일 것 같네여!
과연 이 for loop 안에서는 무엇을 하는걸까욤.. 욤욤욤... jmp instruction 쪽이 와르르 있는 +198 부터 +251 까지 아무래도 if ~ else if 이거나 switch ~ case 와 같은 조건분기인 것 같지않나욤?
아!! 이거 그르믄 for 반복문 안에 if 조건문으로 무슨 값일 경우에 실행되는 값 세팅 및 or, and, xor 연산을 통한 비트연산할 경우일 것 같은 느낌이예요!
여기서 하나 알아보고 가져!! 라우터 네트워크에 관한 열거형 변수가 존재해요! rtnetlink.h 헤더파일에 있는 rtattr_type_t 인데 이걸 한 번 알아보자면
/usr/local/include/rtnetlink.h
enum rtattr_type_t {
RTA_UNSPEC,
RTA_DST,
RTA_SRC,
RTA_IIF,
RTA_OIF,
RTA_GATEWAY,
RTA_PRIORITY,
RTA_PREFSRC,
...
}
이렇게 존재하는데, 갑자기 이 열거형 변수를 말하는 이유는 parseRoutes 라는 함수가 router ip 를 가져오는 함수라면 이 변수를 사용할 것이고, 이 변수에 따라 switch ~ case 를 통해서 값을 넣어주도록 되어있을테니까요!
아무래도 이쪽을 잘 보면 될 것 같아요! 아까의 readNlSock 함수는 무슨함수인지는 모르겠으나, 이런 수상한것이 함정이 아닌 이상 답이 될테니까 파고들어봅씨다!!(야미는 함정을 낼 만큼 똑똑하지 않숨니다 ㅜㅜ)
0x4032e5<+256> 부분으로 오는 곳은 case 조건의 첫 번째인 0x4032b9<+212> 에서 cmp eax, 0x4 --> je 로 넘어오도록 되어있네용!! 그리고 이 첫 번째 case가 끝나는 곳에 두 번째 case가 존재하지 않을까여? 0x4032be<+217> 부분을 보면, cmp eax, 0x4 --> jg 를 통해 0x4032ce<+233> 으로 넘어가도록 되어있는데, 이것은 꼭
if(cmp_value == 4) 0x4032e5;
else if(cmp_value > 4) 0x4032be;
와 동일하지 않나요? 그럼 0x4032e5<+256> 부분이 끝나는 지점은 0x4032ce<+233> 부분에 위치한 0x4032d1<236> 의 je 가 가리키는 0x403357<+370> 부분이 되겠네요!
참 참고로!! 0x4032e0<+251> 부분을 보면 jmp 인스트럭션이 사용되었는데, 이것은 switch ~ case 에서 default: 혹은 if ~ else 에서 else 부분과 같아여! 위 조건이 전부 아니면, 결국 빠지는 곳이 이곳이니깐여! 그래서 따로 조건없이 jmp 해버리는 것이구, 그 부분이 break; 가 되겠네여!! 얘가 가리키는 0x4033ff<+538> 이 break; 를 의미한다는 것을 알게되었습니다!!
그런데 이 구문이 분명 switch ~ case 라고 하였는데, 왜 0x403357<+370> 바로 이전에 break; 가 보이지 않을까요? case 4: 지점에서 선수행 후 case > 4: 지점으로 넘어가나봅니다!!
그런가봅니다... 하고 보니 0x403342<+349> ~ 0x403354<+367> 의 instruction을 보세욤!! 같은 위치, 같은 변수, 같은 포인터 대입을 수행하고 있네여?! 같은 코드를 3줄 넣었다는 말인디... 어느 연산도 없이 같은 코드를 연속 3번 넣은 것을 보면 아주 단순한 대입식일거예욤 like “test = 1;” 과 같은 대입이요!!
쓸모없는 대입은 출제자의 힌트이거나.. 아니믄 그냥 써놓고 안지운 쓸데없는 코드이겠져!? 무슨 getchar() 같은 버퍼를 위한 함수콜도 아니구여!! 이쪽이쪽 아주 수상함니다 히히
그리고 다음 case 문은 <+461>에 있는 주소가 되겠네욤. switch ~ case 문의 범위 내에 다른 주소로 점프하는 구문은 총 6개이고, 가장 첫 번째에 나와있는 0x4032a5 주소의 <+591> 부분은 아래에서 보면 알겠지만 <+591> 부분 바로 이전의 주소가 jmp <+145> 를 하기 때문에 for 반복문임이 확실해졌슴미다!! 즉 아까 찾은것처럼 for 반복문 안에 switch ~ case 문이 있는 형태가 되는 거져!!
그리고 다음으로 있는 것이 동일한 대입식 3개가 있던 case 4: 이며 그 다음은 다른 case 문이네욤 ㅎㅎ 0x4033e4<+511> 로 간 후 break; 로 향하는 것을 알 수 있습니당.
그 다음 case는 case > 4: 부분이 되며 마지막 case문도 아직 알 지 못하는 0x4033b2<+461> 로 향한 후에 break; 로 가는 것을 알 수 있습니당. cmp 구문을 보면 cmp eax, 0x4 를 시작으로 0x1, 0x5, 0x7 이렇게 세 가지가 있는데, case 4:, case 1:, case 5:, case 7 이렇게 4가지가 있다는게 되네욤!! 이야 핸드레이인지 뭐시긴지는 못하겠눈데 어셈블이 요로케 구성되어있겠거니는 보이네욤!! 저만 보이는거 아니져?! 이해되시는거 맞져?!
0x403357<+370> 부분부터 다음 case 문인 0x4033b2<+461> 부분 전까지가 case > 4 라고 말씀드리던 case 5: 부분이 되겠군녀!!
고럼... case 1: 이랑 case 7: 은 바로 jmp break; 를 해주는뎅.. case 4: 랑 case 5: 는 아직 못봤어염!! case 4: 가 있는 +256 ~ +367 까지는 jmp break; 가 없네염!! 그 다음 case 5: 부분인 +370 ~ +459 에는 break; 가 있어여!! 오홍.. 왜 case 4: 는 break; 를 안해주는 걸까여? 바로 case 5: 로 넘어갈 이유가 있눈건감...
이라고 생각하고 보다보니 case 4: 부분에 수상한게 있지 않았나여!? 단순 대입 3연속!!! 얘가 수상하니 한 번 변조를 시켜봐야겠어욤 ㅎㅎ우선 nop으로 쭈우욱 채워버리쥬!!
음 이제 nop 으로 다 채워놓았으니 이렇게 실행해도 문제없나 확인!
처음이랑 별다른 변화가 없이 2.0.0.0 이 출력되지만 그래도 문제없다는것은 확인되었네욤!! 그 3연속 코드는 정말 쓸모없는 코드가 맞았어염!!
그럼 이제 break; 문을 한 번 넣어볼까여? 왠지 이거 넣으면 될 것 같지 않아여?
요로케 이제 jmp break; 를 넣어주씨고!! 이제 다시 돌려주쎼여!!
오홍!! 정상적인 router IP 같은게 나오면서 플래그가 바꼈어여!! Let's Develope SUA! 와 비슷하게 생긴 플래그는
L3t5_D3vE10p3_SL1A!
였군녀!! 흐흐 요문제를 승표님께서 엄청 힘들어했숩니다 재밌더라구여 꺄륵~
이상 이번 SUA CTF 2회 Write up 을 마침미당!!
어 참 작년 1회 SUA CTF 를 제가 우승했었는디.. 그땐 문제 푼사람이 롸업을 내야하는 것도 없었구 그래서 안썼었눈뎁... 지금 바이너리두 없는뎁.. 제가 리버싱 2문제랑 misc 2문제 풀구(으엉 안드로이드 답찾았는데 그게 플래그처럼 안생겨서 답 아닌줄알구 안냈다가 나중에 들어보니 답이었다고 하더라구욤 ㅜㅠ) 저 말구 다른 팀원 1명이 웹 2문제 풀어가지구 1등했었눈데 ㅜㅠ 최근에 찾아보닝 다른 팀이 Write up 을 딱 올린게 왜 뺏겨부렀다 싶은지ㅜㅠㅜ
오늘 행사에서 뵐 수 있는 분들 마니 뵐 수 있으면 좋겠어욤 히히 고럼 다들 눈동자 굴리면서 나중에 또 뵈어용!! 자주오도록 해볼게욤!!
Check out the yummyhit’s website for more info on who am i. If you have questions, you can ask them on E-mail.
댓글남기기