CodeGate 2010 - yboy ( xbox pwned )

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

CodeGate 2015 Quals - Mashed Potato

Posted by ORANG ORANG(오랑)
2015.06.24 04:30 System Hacking/CTF

CodeGate 2015 Quals - Pwnable 600pt, Mashed Potato



메모리 보호기법은 SSP와 NX, ASLR만 걸려있는 상황이고,

비슷한 환경으로 구성하고 다시 풀어봤다. ( 로컬 환경 구성 : Ubuntu Linux 14.04 x86_64 )



먼저 취약점으로 보이는 부분은 바로 보인다. leave_plain() 함수 내부에서 fgets 입력을 2번 받는데, 첫번째로 입력받은 값만큼 2번째 입력을 받는다. 이 부분에서 BOF가 발생하는데, SSP가 걸려있기 때문에 canary 값을 알아내야 했다.


사실 바이너리 자체는 로그를 남기는 기능만 했는데, 선택지가 2개밖에 없기 때문에 ( 1. 암호화 // 2. 평문 // 3. 종료 )

그냥 바로 암호화 부분의 함수를 보면..



입력받을 최대 길이를 지정하고, 메세지를 입력받는다. (이 부분에서도 BOF 발생)

그리고 encrypt_data 함수를 통해 암호화하는데, 

사용자로부터 '입력받은 메세지의 길이'가 아니라 사용자가 지정한 '입력받을 길이'를 전달한다.


일단 먼저 encrypt_data 함수의 내용을 확인해보면..


deflate 라는 함수와 xor 연산을 통해서 암호화를 진행하는데, deflate 함수에 대해서 찾아보니

암호화 함수가 아니라 zlib에서 사용하는 압축 함수 였다. 찾아보니 deflate 함수는 LZ77 알고리즘과 Huffman 알고리즘 2가지를 섞어 사용하고, 이 문제에서는 최종적으로 압축된 데이터의 크기를 결과값(msg.log에 쓰여진 메세지 크기)으로 출력해준다.

이 문제의 경우, 위에서 확인한것처럼 압축되는 데이터의 길이를 조절할 수 있기 때문에, 압축되는 데이터의 범위를 조절하고, 압축되는 데이터값을 조절하여 출력값을 비교한다면 원하는 데이터값들을 알아낼 수 있다.


다시 LZ77 알고리즘과 Huffman 알고리즘에 대하여 보면.. (허프만 코드는 너무 유명해서 생략)

LZ77 알고리즘에 대한 정보는 아래 링크에서 자세히 볼 수 있는데, 내가 이해한대로는..

압축하려는 데이터가 이전에도 존재했었는지 확인하여 반복적으로 나타나는 데이터를 압축하는 알고리즘 같다.

이때 데이터의 기준은 최소 3바이트 이상이고 1바이트 단위로 중복되는 부분들을 모두 찾는다.


 - LZ77 알고리즘 관련 자료 : http://egloos.zum.com/studyfoss/v/5355158

 - Huffman 알고리즘 관련 자료 : http://studyfoss.egloos.com/5356876


이제 이 점을 이용해서 Canary를 찾은 방법을 확인해보자면..


canary는 브루트포싱을 통해서 알아냈다. 먼저 3바이트 이상이고, 중복되는 부분들은 압축된다는 점을 이용했다.

이 때 중요한 점은, 압축률을 통해 canary 값을 알아내려면 1바이트만큼 더 압축이 되었는지 그렇지 않은지를 확인해야 한다.

(브루트 포싱 값을 1바이트씩 증가시킬 때, 만약 canary값이랑 일치한다면 -> 1바이트만큼 더 압축이 될 것이다.)

최대한 압축해야하는게 아니고 canary 값만을 찾아내면 되므로, 이 부분을 주의하며 압축 범위와 데이터를 조절해야한다.


여러번 삽질해본 결과.. 저런 식으로 8바이트 중복되는부분("\x00"*8) + canary(1바이트~ 8바이트)를 늘려가면서 브루트 포싱하는게 가장 깔끔하게 나오는 것 같다. 어떤 부분이 문제인지는 모르겠는데 가끔 안됨..





대회 당시에 라이브러리 파일이 주어졌기 때문에 익스플로잇 자체는 쉽게 짤 수 있었다. 사실 이 문제의 경우 꽈배기처럼 익스플로잇을 짜면 스테이지를 2개 정도 더 추가하여 GOT 테이블에 적힌 라이브러리 함수들간의 오프셋을 통해 라이브러리 파일을 알아낼 수도 있다.


익스플로잇 흐름은 -> GOT에서 라이브러리 함수 주소를 읽어온 후 이 값을 베이스로 system 함수의 주소와 라이브러리 내부의 "/bin/sh" 문자열의 주소를 계산했다. 이를 통해 쉘을 띄움




mashed.zip


mashed.py




'System Hacking > CTF' 카테고리의 다른 글

CodeGate 2015 Quals - Mashed Potato  (0) 2015.06.24
DEFCON 2015 prequals - wwtw  (2) 2015.05.19
CodeGate 2015 Quals - Sokoban  (0) 2015.05.15
Codegate 2015 - Bookstore  (2) 2015.03.21
B-Sides Vancouver 2015 - Ownable 400  (0) 2015.03.18
CSAW 2014 pwn_500 xorcise  (0) 2015.01.07
이 댓글을 비밀 댓글로

DEFCON 2015 prequals - wwtw

Posted by ORANG ORANG(오랑)
2015.05.19 16:49 System Hacking/CTF

DEFCON 2015 prequals, wwtw


FSB 문제, 라이브러리 정보 없음.



[# 2015.06.22 -> 이해하기 쉽게 헷갈리는 변수명 수정]


메모리 보호기법은 PIE까지 다 걸려있다. 아래와 같이 게임? 하는 부분으로 시작한다.

 20x20 맵 상에서 움직여서 E까지 움직이면 되는데, 스테이지를 5개 깨면 게임은 끝나고 인증부분으로 넘어간다.

게임 자체에는 공격벡터가 없다. 이 부분을 자동화해서 코딩해야 좀 더 분석이 편해졌을텐데, 게임 부분은 직접 움직이는 쪽으로 코딩해서 분석에 오래걸렸다. 나중에 자동화 코드도 짜봐야겠다.




게임이 끝나면 위와 같은 인증함수로 넘어가는데, Key값을 얻어내는건 어렵지않다. Key값은 "UeSlhCAGEp" 이다.


문제로 주어진 바이너리에는 FSB 취약점이 존재하는데, 해당 함수까지 접근하는 과정이 까다로웠다.(자동화 코드 + Tradiskey + 인증 변조)

해당 함수에 접근하기 위해서는 아래 함수 sub_E08() 이 가장 핵심적인 부분이 된다. 0x50A4에 저장되는 값은 일종의 시간 정보로 생각되는데, 아래 범위에 있어야만 FSB() 함수에 접근이 가능해진다.



0x50A4에 저장되는 값을 변조하려면 먼저 아래 함수들을 봐야한다. 

먼저 소켓을 생성해서 fd를 dword_50b0[2] 에 저장한다, 그리고 127.0.0.1 에 1234 포트로 연결한다.


그리고 dword_50b0[2]에 저장된 fd를 이용하여 4바이트 값을 받아오는데, 이걸 0x50A4에 저장하게 된다.

그리고 이 값을 통해서 인증을 하게 된다. 이 값을 통해 결과적으로 FSB()함수에 접근이 가능해지므로 이 값을 변조해야한다.


signal(14, FD로부터 읽어오는 함수())로 시그널 핸들러를 새로 세팅하고 alarm(2) 한다. 그리고 아래 선택지를 입력받는 부분인

if( read(0, dword_b0B0, 9) <= 0 ) 에서 9바이트 값을 입력받는데, 근데 fd가 저장된 위치가 dword_b050[2]이므로 여기서 dword_bo50[2]를 조작하고, 시그널 핸들러가 호출되면 0x50A4에 원하는 값을 입력할 수 있게 된다.



이제 FSB가 존재하는 함수에 접근할 수 있는데, 스택상에 s가 존재하므로 더블 스테이지 없이 값을 바로 변조할 수 있다.

EIP를 컨트롤하는건 어렵지 않는데, 라이브러리 정보가 주어지지 않아 라이브러리 함수간의 오프셋을 알 방법이 없었다.




평소에 문제 풀 때, 라이브러리 정보가 주어지지 않는 경우를 생각해보지 못해서 삽질만 엄청 했다.

라이브러리 함수간의 오프셋을 구하기 위해 여러가지 삽질을 했는데, 결과적으로 사용한 방법은 아래 익스플로잇과 같다.

먼저 SFP에 저장된 ebp 값을 fake-ebp를 사용하여 Stack-pivoting 했다. fake-ebp는 GOT 테이블의 주소 + 0x40c위치로 지정했다.

그리고 print(s) 가 호출되는 시점으로 RET를 변조하여 s = ebp - 0x40c 이므로 결과적으로 GOT 테이블의 값들을 출력하게 된다.

그리고 읽어낸 함수들의 오프셋을 이용하여 라이브러리 정보를 알아냈고, system함수 까지의 오프셋을 추가로 계산했다.





익스플로잇은 간단하게 system("/bin/sh").



익스플로잇은 리눅스에서만 사용 가능



wwtw_c3722e23150e1d5abbc1c248d99d718d


[exploit.py & leak.py]

wwtw.tar.gz

[변수명 등 편의상 약간 수정한 익스플로잇(2015.06.22)]

wwtw2.tar.gz



'System Hacking > CTF' 카테고리의 다른 글

CodeGate 2015 Quals - Mashed Potato  (0) 2015.06.24
DEFCON 2015 prequals - wwtw  (2) 2015.05.19
CodeGate 2015 Quals - Sokoban  (0) 2015.05.15
Codegate 2015 - Bookstore  (2) 2015.03.21
B-Sides Vancouver 2015 - Ownable 400  (0) 2015.03.18
CSAW 2014 pwn_500 xorcise  (0) 2015.01.07
    • 2015.05.31 22:14
    비밀댓글입니다
    • 2015.06.04 23:12
    비밀댓글입니다
이 댓글을 비밀 댓글로

Plaid_CTF 2014 - ezhp

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

CodeGate 2015 Quals - Sokoban

Posted by ORANG ORANG(오랑)
2015.05.15 00:25 System Hacking/CTF


CodeGate 2015 Quals - Pwnable 1000pt, sokoban


로컬 환경 구성 -> Ubuntu Linux 14.04 x86_64 ( 라이브러리 : libc-2.19.so )


코드게이트 예선 때 못 푼 문제였는데, 롸업이 올라왔길래 정독해보고 다시 풀어보았다.



바이너리로 주어진 파일을 실행시켜보니 위와 같이 "[]"를 골인 지점으로 옮기는 게임 형식이다.

소스 분석 중, 가장 먼저 눈에 띈 부분은 아래 그림과 같이 stage 6 에서 게임 모드를 선택하는 부분이 있다.





랜덤-무한 모드를 선택할 경우, 낮은 확률로 아래와 같이 히든 맵(공간이 막혀있지 않은 맵)이 나온다.

코드게이트 때는 저 부분도 발견하지 못했었는데, 롸업을 보고 발견하니 허탈했다. 이걸 발견했어도 풀진 못했을 것 같긴 하지만..



코드 상에는 FLAG를 출력해주는 함수가 존재한다. 하지만 PRINT_FLAG() 함수가 실행되려면, GAME()의 반환값이 1이어야 하는데, 소스 상으로 분석해보면 GAME()의 반환값은 0 아니면 2이므로 일반적인 방법으로는 PRINT_FLAG()함수를 호출할 수 없다.



getch 외에 다른 입력 부분이 없어서, 공격벡터를 찾기 까다로웠다. 이 문제에 존재하는 벡터는 아래 그림과 같다. USER_INPUT을 받는 함수 내부중 일부인데, 조건에 따라 입력받은 방향(H, J, K, L)으로 메모리 상의 값을 옮길 수 있다. 먼저 메모리 상의 위치를 계산하는 방식을 보면 생각보다 간단하다. [0x60c8e0 + 32 * 세로 + 가로]으로 계산하면 된다.


먼저, USER_INPUT 에 따라 변하는 값은

H    -> 가로 -1

L    -> 가로 +1

J    -> 세로 +1

K    -> 세로 -1        이 된다.


 src_ptr, dst_ptr 이라고 생각해보면 이해하기 쉽다. dst_ptr이 1일 경우 5값을 넣어주고, 0일 경우에는 src_ptr 로부터 값을 옮기게 된다. 아까 그림처럼 히든 맵?의 경우 가로-세로 움직이는데 제한이 없기 때문에, 데이터 영역의 값을 조작하는게 가능하다.





데이터 영역에서 조작 가능한 부분으로 GOT-테이블을 살펴보면, 위와 같다. ptr을 통해 데이터를 옮기는 조건들 때문에 접근할 수 있는 부분은 werase@GOT나 rand@GOT 뿐이다. 롸업 보다가 이 부분에서 좀 컬쳐쇼크였는데, ASLR이 걸린다는 점을 역으로 이용한다는 발상 때문이다. 메모리를 보호하기 위해 적용된 ASLR을 이용해 공격을 한다는 것 자체가 충격이었다. 라이브러리가 로딩되는 주소가 항상 바뀌기 때문에, 낮은 확률로 rand의 주소값이 (하위 2바이트 값만 쓰자면) 0x0060인 경우가 나타난다. 이 때, 아래와 같은 gadget의 주소로 rand@GOT를 조작하게 된다면, 프로그램의 흐름을 바꿀 수 있다. 아래 gadget을 통해 GAME()함수를 바로 종료시킬 수 있다. 이 때 RAX는 따로 세팅되지 않음.


라이브러리 상의 rand@LIBC = 0x3d060 이고 gadget@LIBC = 0x3e260 이므로 두 값의 차이는 정확히 0x1200이다.



USER_INPUT() 함수의 스위치 문을 보면, "v" 인풋의 경우 0x60c121에 18(0x12) 값을 더해준다. 이 부분을 이용하면 된다.



0x60c121 에 세팅된 0x12 값을 rand@GOT의 2번째 바이트로 옮겨주면 된다. ( ASLR이 정확히 맞아떨어져 \x00이 될 경우 익스플로잇 성공 )



반환 값으로 세팅되는 부분은 아래의 getch 이다.



익스플로잇 코드를 짜는데 생각보다 많이 헤맸다. 랜덤-무한 모드에서 히든 맵을 발견할 수 있게끔 하고 싶었는데, 맵을 리셋하는 과정에서 USER_GARO, USER_SERO 값이 계속 변했기 때문에 ptr의 정확한 계산을 할 수 없었다. 색을 추가하는 부분들 때문에 같은 위치인데도 받아온 문자열의 길이를 보면 다르게 나오는 것 같길래 그냥 브루트 포싱 쪽으로 했다. 생각보다 확률이 너무 낮아서 오래 걸림..






공부한 롸업 - https://github.com/ctfs/write-ups-2015/tree/master/codegate-ctf-2015/pwnable/sokoban

'System Hacking > CTF' 카테고리의 다른 글

CodeGate 2015 Quals - Mashed Potato  (0) 2015.06.24
DEFCON 2015 prequals - wwtw  (2) 2015.05.19
CodeGate 2015 Quals - Sokoban  (0) 2015.05.15
Codegate 2015 - Bookstore  (2) 2015.03.21
B-Sides Vancouver 2015 - Ownable 400  (0) 2015.03.18
CSAW 2014 pwn_500 xorcise  (0) 2015.01.07
이 댓글을 비밀 댓글로

Codegate 2015 - Bookstore

Posted by ORANG ORANG(오랑)
2015.03.21 03:05 System Hacking/CTF


메모리 보호기법이 있는대로 다 걸려있다. 이런 문제는 처음이라 당황스러웠는데

eip를 컨트롤하기 위해 주소값을 알아내야 하고, 이를 위해

메모리릭이 필요한 점 외에 다른 부분은 크게 신경쓰지 않고 풀었다.


책 정보에대한 구조체.

특이한점은 alloca함수에 의해 스택에 메모리가 할당된다는 점과 함수포인터를 2개 가지고 있다는 점.

전체적인 흐름을 보면 구조체가 스택을 통해서 복붙하는 방식으로 진행된다.

아래 함수를 보면..


이 부분을 통해 스택에 스프레이식으로 임의의 값을 뿌릴 수 있는데, 특정 조건에 따라 eip컨트롤이 가능하다.


과정이 살짝 복잡한데 UAF 유형 문제와 비슷하게 생각하면 쉽다. 변수 free_ship에 대한 세팅 (위 그림에서 v14변수)이 0일경우

구조체 내부에 존재하는 함수포인터를 초기화하지 않고 진행한다.

이후 memcpy를 통해 구조체가 통째로 복사되면, 스택에 존재하던 메모리가 함수포인터 위치에 존재한채로

 그대로 복사되어져 함수 포인터를 조작할 수 있다. -> 스프레이식으로 뿌려둔 메모리값을 이용함.


그리고 해당 구조체를 출력하는 함수를 진행하는 도중에 함수포인터(변수 a12)가 실행된다 ( free-ship이 1로 세팅되어 있을경우)

이때 인자로 넘어가는 값은 구조체의 book_name값이다(변수 a3)

flag를 읽어오기위해 사용한 open_func함수


익스플로잇 과정 설명은 생략하고 간단하게 흐름만 적자면


구조체의 생김새를 보면 중간에 bookname-price-stock-함수포인터1 이런 형식으로 되어있다.

bookname을 20바이트 가득채우고, price와 stock을 모두 0x11111111로 세팅하여

bookname부터 함수포인터까지 NULL바이트 없이 쭉 이어지게 했다. 그리고 bookname을 출력하게 해주어

함수포인터의 주소(binary의 주소값)을 메모리 릭해서 바이너리 영역의 주소를 구했다.


다른 주소에는 접근할수있는 부분이 보이지않았기 때문에, 바이너리영역에 존재하는 부분만 접근이 가능함..

프로그램의 초반에 사용된 open_Func(인자로 전달된 파일을 open하여 read, 출력해준다.)을 이용하면 될것같아서

메모리릭한 주소값에다가 오프셋을 계산하여 open_Func의 주소값을 얻어낸후 스택에 스프레이식으로 뿌려 함수포인터에 세팅하였다.


그리고 인자로 전달될값 rdi 레지스터(구조체의 bookname이 들어감)를 &("/home/bookstore/key")로 세팅해주고 함수포인터 실행




...생략...



'System Hacking > CTF' 카테고리의 다른 글

DEFCON 2015 prequals - wwtw  (2) 2015.05.19
CodeGate 2015 Quals - Sokoban  (0) 2015.05.15
Codegate 2015 - Bookstore  (2) 2015.03.21
B-Sides Vancouver 2015 - Ownable 400  (0) 2015.03.18
CSAW 2014 pwn_500 xorcise  (0) 2015.01.07
[CodeGate_2013] pwn500 kpop_music  (0) 2015.01.05
  1. modify description 을 통해 stack에 spray 해봤자 저 함수가 종료되면 스택프레임이 정리되고 spray한 부분을 못쓰게 되는것이 아닌가요? 어떻게 저게 구조체의 함수포인터에 들어간다는건지 설명좀 해주실수 있으신가요..
    • 음 일반적인 함수 에필로그 과정을 생각해보시면 됩니다ㅎㅎ 함수 종료 과정시 스택에 남아있는 (사용중이던) 메모리를 따로 초기화하지 않고 mov esp, ebp; pop ebp; ret; 해서 이전 함수의 호출 시점으로 돌아가게 됩니다.
      그러므로 스택에 존재하는 메모리는 함수가 종료하게 되더라도 스택 상에는 그대로 남게 되는거죠ㅎㅎ.. 이후 다른 함수들이 호출되어서 해당 메모리를 다시 사용하게 될 경우, 초기화 후 사용하게 된다면 문제가 생기지 않지만 Bookstore의 경우 조건에 따라 초기화가 되지 않아 문제가 생기게 됩니다!!
이 댓글을 비밀 댓글로

B-Sides Vancouver 2015 - Ownable 400

Posted by ORANG ORANG(오랑)
2015.03.18 12:35 System Hacking/CTF


왜 Ownable 이라고 되있는건지는 모르겠다

NX만 적용되어있다.



Character를 재설정하는 과정에서, read_data 함수 내부에서 오버플로가 발생한다.


하지만 아래와 같이 \n, \x0 ~ \x1f, \x7f 은 필터링 되는 부분이므로 이부분을 피해서 입력이 가능하다.


필터링을 우회하는 부분은 이부분을 통해 해결헀다.

먼저 위 그림(Generate_dungeon함수 내부)에 보면, 던전의 레벨을 입력하는 부분이 있는데

unsigned __int8 자료형인 v6 변수에 입력을 받는다, 하지만 다음 조건절에서는 (char)형으로 형변환되므로

255(0xFF)를 입력해주면 조건절을 통과할수 있다.

그리고 mmap을 통해 할당되는 메모리는 0x2015000 + 255 * 0x1000 이 된다. 


0x2015000 ~ 0x226A000 까지 범위가 되므로 필터링되는 범위를 벗어날 수 있다.

게다가 이부분에 대한 권한은 7로 rwx, 읽기, 쓰기, 실행 권한까지 모두 설정된다.


이부분에 쉘코드와, 쉘코드의 주소를 올려두고 아까봐둔 오버플로가 발생하는 함수를 이용하여

오버플로를 발생시키고 진행시켜보면 시작함수로 보이는 함수의 에필로그가 보인다.

일반적인 함수의 에필로그 과정과는 다르게 생겼다.



쉘코드를 통하여 공격할 것이므로 ret를 조작하기 위한 값을보면


mov ecx, [ebp-4]    -> lea esp, [ecx-4]     ->   ret로 이어진다.

일종의 더블포인터와 비슷하게 진행된다.

그러므로 쉘코드를 올릴때 쉘코드도 같이 올려둔 후에 익스플로잇








wby-23859086c3e87a4beb04b4f920b7ed49d407326e.idb


wby-23859086c3e87a4beb04b4f920b7ed49d407326e


'System Hacking > CTF' 카테고리의 다른 글

CodeGate 2015 Quals - Sokoban  (0) 2015.05.15
Codegate 2015 - Bookstore  (2) 2015.03.21
B-Sides Vancouver 2015 - Ownable 400  (0) 2015.03.18
CSAW 2014 pwn_500 xorcise  (0) 2015.01.07
[CodeGate_2013] pwn500 kpop_music  (0) 2015.01.05
Volga CTF - exploitation 100 (Timing attack)  (0) 2014.12.14
이 댓글을 비밀 댓글로

Codegate 2015 푼거 + 풀다만거 정리

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

CSAW 2014 pwn_500 xorcise

Posted by ORANG ORANG(오랑)
2015.01.07 15:49 System Hacking/CTF




문제 소스 보기



로컬에서 환경을 구성하고 풀었다.


uint32_t decipher(cipher_data *data, uint8_t *output)

{

    uint8_t buf[MAX_BLOCKS * BLOCK_SIZE];    

    uint32_t loop;

    uint32_t block_index;

    uint8_t xor_mask = 0x8F;


    memcpy(buf, data->bytes, sizeof(buf));

    if ((data->length / BLOCK_SIZE) > MAX_BLOCKS)

    {

        data->length = BLOCK_SIZE * MAX_BLOCKS;

    }


    for (loop = 0; loop < data->length; loop += 8)

    {

        for (block_index = 0; block_index < 8; ++block_index)

        {

            buf[loop+block_index]^=(xor_mask^data->key[block_index]);

        }

    }

    memcpy(output, buf, sizeof(buf));

}

decipher함수에 취약점이 존재한다. MAX_BLOCKS 는 16, BLOCK_SIZE 는 8 이므로

buf의 크기는 16*8 = 128이다.


if 조건절을 보면 (data->length/BLCOK_SIZE) > MAX_BLOCKS 일때 length를 128로 맞춰준다.

하지만 정수형을 나누는 것이므로..

length가 135라면 -> 135/8 = 16이 되므로 조건절을 통과하게 되어 7바이트 오버플로가 발생한다.


이 때 스택의 구조를 보면..



오버플로로 접근할 수 있는 부분은 0xbffff433~0xbffff439 까지이다.

RET는 0xbffff44c에 있으므로 RET를 접근하려면 변수를 이용해야 한다.


디스어셈블 코드를 분석해보면

스택은 buf(128바이트) - xor_mask(0x8f 1바이트) - block_index(4바이트) - loop(4바이트)로 되어있다.

7바이트 오버플로로 접근할 수 있는 부분은 loop의 2번째 바이트까지인데 뒤의 연산과정을 보면


buf[loop+block_index]^=(xor_mask^data->key[block_index])


이렇게 연산이 진행된다.

접근할 수 있는 loop나 block_index를 조작한다면 특정 위치의 값에 접근이 가능할 것이다.


그리고 반복문에서 연산이 8바이트 단위로 진행되므로

xor_mask 1바이트, block_index 4바이트, loop 첫번쨰 바이트, 조작된 loop값을 통해 특정위치의 값에 2번 xor연산이 가능하다.

(2바이트 조작가능)


gdb에서 스택의 메모리를 찾아내, xor연산을 통해 조작할 값을 계산해 넣어주면 된다.


system으로 리턴시켰다가 잘안되길래 readfile()함수로 리턴시킴






이제 password.txt를 로컬에 만들어주고,

로컬파일으로부터 hash_checksumd을 얻어내 서버에 명령을 내린다고 가정해보면..










xorcise


xorcise.c




'System Hacking > CTF' 카테고리의 다른 글

Codegate 2015 - Bookstore  (2) 2015.03.21
B-Sides Vancouver 2015 - Ownable 400  (0) 2015.03.18
CSAW 2014 pwn_500 xorcise  (0) 2015.01.07
[CodeGate_2013] pwn500 kpop_music  (0) 2015.01.05
Volga CTF - exploitation 100 (Timing attack)  (0) 2014.12.14
Plaid_CTF_2013 ropasaurusrex  (0) 2014.11.19
이 댓글을 비밀 댓글로

[CodeGate_2013] pwn500 kpop_music

Posted by ORANG ORANG(오랑)
2015.01.05 12:57 System Hacking/CTF

UAF 문제를 공부하려고 풀어본 문제



헥스레이로 흐름을 확인해보니.. 2종류의 구조체가 정의되어있는듯했다.

첫번째 구조체는 구조체 배열의 주소와 갯수를 나타내고

두번째 구조체는 함수포인터, 제목(문자열), url 길이, url 의 주소를 나타낸다.

함수 포인터가 존재하는 구조체 -> 이런경우 대개 UAF문제인듯


문제를 풀면서 여러가지로 이상한 부분이 많았다.



2번째 구조체의 초기화부분



함수 포인터 주소 밑에는 공격가능한 함수






이 문제의 취약점은 저부분이다

unsinged int를 signed int로 형변환하므로 음수값을 넣으면 조건절이 참이된다.

그리고, song_info의 주소를 계산하는과정에서 4*number + a1->song_info_addr 으로 계산한다.

아무리봐도 계산하는 방식이 이상하다.

만약 number가 0x100000000 / 4 의 값이라면 -1073741824가 된다.

4*number + a1->song_info_addr 결과, Integer-Overflow가 일어나므로 0번째 song_info가 지워지게 된다.


그냥 number에 0을 입력해 지우는것과의 차이는 그 밑부분에 난다.

삭제 이후 for문에서 원래는 song_info 배열을 재배치해주지만

number가 (unsinged int) 0x40000000 이므로 재배치되지 않는다.


결과적으로 0번 song_info는 free되었지만 논리적으로는 아직 존재하게된다.


이제 이부분을 사용하면된다. 0번 song_info의 함수포인터 주소를 바꿀 수 있다면 원하는 함수를 호출시킬 수 있다.




modify 함수과정을 보면 함수포인터를 통해 title과 url을 재설정하는걸 볼 수 있다.

이 때 주의깊게 봐야하는건 url부분 -> 함수포인터가 가리키는 함수를 보면 위에 나타낸 0x8048c00이다.

malloc 이후 strcpy 로 진행된다. 이 때, 0번 song_info에 할당되어있던 메모리는 이미 free되었으므로

이부분에 메모리가 할당되게 된다. 이부분을 조작할 수 있다.

논리적으로는 0번 song_info가 아직 존재하므로, 조작된 메모리를 통해 함수포인터를 찾을 것이다.






kpop_music


kpop_music.id0


kpop_music.id1


kpop_music.idb


kpop_music.nam


kpop_music.til


'System Hacking > CTF' 카테고리의 다른 글

B-Sides Vancouver 2015 - Ownable 400  (0) 2015.03.18
CSAW 2014 pwn_500 xorcise  (0) 2015.01.07
[CodeGate_2013] pwn500 kpop_music  (0) 2015.01.05
Volga CTF - exploitation 100 (Timing attack)  (0) 2014.12.14
Plaid_CTF_2013 ropasaurusrex  (0) 2014.11.19
CSAW_2012 exploitation 500  (0) 2014.11.19
이 댓글을 비밀 댓글로