overthewire :: Vortex level9 by ORANG

Posted by ORANG ORANG(오랑)
2014.10.30 19:45 System Hacking/vortex




이 댓글을 비밀 댓글로

overthewire :: Vortex level8 by ORANG

Posted by ORANG(오랑)
2014.10.30 19:39
보호되어 있는 글입니다.
내용을 보시려면 비밀번호를 입력하세요.

overthewire :: Vortex level7 by ORANG

Posted by ORANG ORANG(오랑)
2014.10.25 03:49 System Hacking/vortex



CRC32의 취약점을 이용한 문제


코딩자체보다는 CRC32 알고리즘을 이해하는데 시간이 더 들었다..


http://anch0vy.tistory.com/60 -> anch0vy님이 쓴 글이 도움이 많이 되었다.


내가 이해한대로 기록해두자면..

CRC32(cyclic redundancy check)는 데이터에 오류가 있는지를 확인하기 위한 체크값을 결정하는 방식이다.

미리 만들어진 256개의 테이블을 통해 1바이트 단위로 계산하는데,

'>>8' 과정에서 최상위 바이트가 0이 되므로, 테이블의 최상위값 바이트가 남게된다.

이를 통해 해당 테이블을 알아낼 수 있다.


또, 1바이트 단위로 시프트 연산이 진행되므로

CRC32 는 4바이트(32bit), CRC64 는 8바이트(64bit)만 조작할 수 있다 면

역연산 과정을 통해

이전까지 계산된 crc값을 내가 원하는 특정 crc 값으로 조작할 수 있다.


crc 알고리즘 -> (crc>>8)^table[idx] // idx는 상위 1byte


이해하고 보니 알고리즘 자체는 단순하다. 테이블이 주어져있다면 특히 쉬워지는 듯..

(주어진 vortex 문제를 보면, 문제에서 crc_table를 얻어야 한다는데 이부분은 더 생각 필요)


먼저 조작에 필요한 테이블 값을 얻기 위해

'현재 가진 crc 값 -> 이전 테이블 유추 -> 역연산을 통해 이전 crc값 획득' 으로 접근했다.

그리고, 이전 문자열들에 대한 crc값과 결과적으로 목표 crc값을 연산해

crc값을 조작하기 위한 값을 알아냈다.

역연산 중에는 상위 1바이트로 테이블 값을 유추해 이전 crc값에 접근했지만,

CRC연산 중에는 index를 통해 다음 테이블에 접근하게 된다. 이 점을 유의해야한다.



<참고>

http://anch0vy.tistory.com/60

http://ko.wikipedia.org/wiki/순환_중복_검사

http://truthtilltheend.tistory.com/33






"(1바이트 연산 -> table[index] xor 연산) 반복" -> 을 생각하면 생각만큼 복잡하지 않다. 

 

환경변수로 nop+쉘코드를 올리고 공격했다.



ebp - buf = 70






vortex7.c


Reversing_crc32.py


이 댓글을 비밀 댓글로

overthewire :: Vortex level6 by ORANG

Posted by ORANG ORANG(오랑)
2014.10.23 22:51 System Hacking/vortex



헥스 레이로 보면..



if(*(_DWORD *)a3) 일경우 restart(*argv)함수가 호출된다.

restart함수에서는 *argv에서 그대로

execlp(argv[0], argv[0], 0)으로 이어지므로, argv[0]에 실행시킬 파일명을 넣어주면 된다.




일반적으로 main(int argc, char **argv, char **env)이면

ebp       -> SFP

ebp+4    -> RET

ebp+8    -> argc

ebp+12   -> argv

ebp+16   -> env

인자 전달시 이런식으로 진행된다.



gdb로 간단하게 분석해보자면..


<main함수>


   0x0804846f <+9>: mov    0x10(%ebp),%eax

   0x08048472 <+12>: mov    (%eax),%eax

   0x08048474 <+14>: test   %eax,%eax

   0x08048476 <+16>: je     0x8048485 <main+31>


ebp+0x10, env 부분이 NULL인지 확인한다. NULL이 아닐 경우 restart로 그대로 진행


   0x08048478 <+18>: mov    0xc(%ebp),%eax

   0x0804847b <+21>: mov    (%eax),%eax

   0x0804847d <+23>: mov    %eax,(%esp)

   0x08048480 <+26>: call   0x8048444 <restart> 


ebp+0xc, **argv를 eax에 저장 // main+18


*argv 다시 eax에 저장 // main+21


eax값을 현재의 esp에 저장하고 restart 호출 //main+23, main+26


<restart함수>


   0x08048452 <+14>: mov    0x8(%ebp),%eax

   0x08048455 <+17>: mov    %eax,0x4(%esp)

   0x08048459 <+21>: mov    0x8(%ebp),%eax

   0x0804845c <+24>: mov    %eax,(%esp)

   0x0804845f <+27>: call   0x8048360 <execlp@plt>


execlp 호출



간단하지만 익스플로잇을 보면..





 vortex6.bin




이 댓글을 비밀 댓글로

overthewire :: Vortex level5 by ORANG

Posted by ORANG ORANG(오랑)
2014.10.23 02:27 System Hacking/vortex


글자수는 5글자, 브루트 포싱을 통해 패스워드를 알아내야한다.


주어진 소스를 수정해, 브루트 포싱을 위한 코드를 작성했다.



수정된 main함수 부분

브루트 포싱하는데 속도가 느려..

아스키 코드에서 특수문자+문자 부분인 0x21~0x7E 부분으로 제한했다.




계속 buf 출력이 바뀌어서 헤맸는데.. 아주 사소한 부분이 문제가 되었다.

시행착오 끝에 코드 완성


삽질의 끝은 역시 개뿌듯..!!





vortex5.zip



이 댓글을 비밀 댓글로

overthewire :: Vortex level4 by ORANG

Posted by ORANG ORANG(오랑)
2014.10.20 05:46 System Hacking/vortex



if(argc) exit(0); 의 조건을 우회하는 방법을 몰라서 한참 헤맸다

 

execve함수를 통해, args는 NULL로 전달하고 env를 전달

 

arr[idx] 는 arr base + datatype*idx 로 계산 되기때문에

 

argv가 없으면 argv[3]을 env[3]으로 받아들이게 된다.



환경변수를 통해 전달하기 때문에, 메모리 값이 뒤죽박죽? 그냥 조금만 바꿔도 크게 바뀌었다

 

정확한 FSB 공격을 하기 힘들었던 부분.. 밑도 끝도 없는 삽질로 공격에 성공했다.

 

쉘코드를 환경변수에 올리고, 그 주소를 exit@got에 덮어씌우는 방법 사용

 

메모리가 계속 섞이길래 그냥 쉘코드 앞에 nop을 화끈하게 10만개 넣어줬다, 그리고 그냥 삽질해서 성공시킴..


이 댓글을 비밀 댓글로

overthewire :: Vortex level3 by ORANG

Posted by ORANG ORANG(오랑)
2014.10.20 05:43 System Hacking/vortex




%esp+0x9c -> lpp

%esp+0x98 -> tmp

%esp+0x18 -> buf

 

[nop+shellcode+nop] [*(exit@got)]

   0x9c-0x18 바이트


더블 포인터 문제 -> lp에 *(exit@got)로 덮어씌워 exit@got에 buf(쉘코드)의 주소가 들어가게끔 한다.

gdb 상에서 find 명령어를 통해 특정 메모리 주소를 찾는 방법이 있었음

-> find 시작범위, 끝범위, 찾을 메모리 패턴


이 댓글을 비밀 댓글로

overthewire :: Vortex level2 by ORANG

Posted by ORANG ORANG(오랑)
2014.10.20 05:41 System Hacking/vortex




이 댓글을 비밀 댓글로

overthewire :: Vortex level1 by ORANG

Posted by ORANG ORANG(오랑)
2014.10.20 05:41 System Hacking/vortex


먼저 스택의 구조를 그려보면

ptr이 buf[256]의 주소를 가리킵니다.

 

이후 소스를 보면..

 

while((x = getchar()) != EOF) { switch(x) { case '\n': print(buf, sizeof(buf)); continue; break; case '\\': ptr--; break; default: e(); if(ptr > buf + sizeof(buf)) continue; ptr++[0] = x; break; } }

 

이 부분을 통해 ptr의 값을 조절할 수 있겠네요

'\\' 을 입력할 때마다 ptr-- 이고 ,

default의 ptr++[0]=x; 부분을 통해 메모리 입력이 가능하네요

 

 #define e(); if(((unsigned int)ptr & 0xff000000)==0xca000000) 

{ setresuid(geteuid(), geteuid(), geteuid()); execlp("/bin/sh", "sh", "-i", NULL); }

 

또, ptr의 값을 변조한다면 이부분을 통해 쉘을 띄울 수 있습니다 

 

 

0xffffd51c -> buf 의 시작 주소

0xffffd514 -> ptr 의 시작 주소

 

buf와 ptr 사이에 4바이트 만큼 dummy가 존재하므로,

ptr이 가리키는 주소값( buf[256] )으로부터 -264 에 ptr이 존재하겠네요

 

리틀 에디안 방식임을 고려해서, -261에 '\xca' 으로 덮어준후 e()를 한번 더 실행시키겠습니다.

는 성공!!

이 댓글을 비밀 댓글로

overthewire :: Vortex level0 by ORANG

Posted by ORANG ORANG(오랑)
2014.10.20 05:38 System Hacking/vortex



vortex.labs.overthewire.org : 5842에 연결한 후, 4개의 unsigned integer를 입력받아 합을 입력하면

 

vortex1의 패스워드를 획득할 수 있다.


이 댓글을 비밀 댓글로