728x90

문제바이너리중 취약점이 존재하는 함수이다.

buf의 위치는 ebp-6c에 있다. 그러나 read함수를 통해 받아올수 있는 값은 0x82만큼이다 여기서 overflow가 발생한다.

ret값을 system함수로 덮어주고 안에 인자값으로 /bin/sh을 넣어주면 될 거 같다.


system주소는 0x080848310이고, /bin/sh의 주소는 0x0804a020이다.


페이로드는 Dummy값 112byte + system 주소 + dummy 4byte + /bin/sh 로 넣어주면 될것이다.

위 소스를 실행시키면

쉘을 획득할 수 있다.

728x90

'CTF_writeup > 2018' 카테고리의 다른 글

Noote_ver0  (0) 2018.12.22
PCTF_2013_ropasaurusrex  (0) 2018.12.22
MMA-CTF-2-greeting  (0) 2018.12.22
ISITDTU_CTF_dead_note_lv1  (0) 2018.12.22
ISITDTU CTF_xoxopwn  (0) 2018.12.22
728x90

프로그램을 실행하면 위처럼 1번 옵션인 add_note를 했을 때 index, number of note, content를 입력할 수 있다.

2번 옵션인 del note를 실행하면 index값을 입력해주고, 해당 index에 노트가 존재하면 지우고 없으면 없다고 출력해준다.


위 바이너리를 ida로 열어본다.

메인 소스코드이다. 각 옵션들에 따라 해당 함수를 실행시키는 것을 알 수 있다.


2번옵션인 delete_note 함수 소스이다.

get num으로 값을 받아서 해당 인덱스에 해당하는 부분을 free해주는것으로 보인다.


1번 옵션인 add_note 함수이다.

for문안을 보면 qword_2020e0[v2+i] 를 보면 note의 index로 입력해주는 v2 값을 배열의 인덱스로 사용한다.


qword_2020e0에 들어가면 bss영역임을 확인 할 수 있다. 해당 주소에서 조금더 올라가면


Got영역이 나온다. V2 입력값을 음수로 입력 및 조절해서 got영역으로 이동시킬 수 있고 content를 입력해주는 함수를 통해 got overwrite가 가능하다.


exploit을 하기 위해서 

stlen 함수에 의해서 content의 길이가 3byte 보다 작아야하기 때문에 strlen got overwrite를 통해 strlen 길이 제한을 없애준다.

if문을 정상적으로 통과해야 got overwrite가 가능하기 때문에 3byte 크기로 overwrite해줘야 한다.


어떤식으로 overwrite를 해주냐면 strlen의 반환값인 eax를 0으로 고정시켜주는 asm을 짜야한다.

xor eax,eax

ret

을 기계어로 디스어셈블 해준다.

\x31\xc0\xc3 -> 3byte가 나온다.

위 기계어를 strlen함수의 got에 overwrite해주고

이후에 exploit을 계획하면된다.

content를 입력하는 부분을 보면 길이제한이 8바이트로 제한되어있다. 그렇기 때문에 바로 쉘코드를 삽입하지 못하고

system_exec를 디스어셈블해서 atoi 함수에 넣어준다.


atoi 함수는 note옵션을 입력할 떄 사용된다.

해당 코드는 system_exec함수를 호출하기 위한 코드이다. 64bit syscall에서는 인자순서에따라 들어가는 레지스터들이 정해져있다.

2번째, 3번째인자로 들어가는 esi 와 edx를 0으로 초기화해주고 system_exec에 해당하는 syscall number를 al에 넣고 syscall을 실행해준다.


위 코드를 통해 argv, envp를 0으로 초기화해줬다. 이후 atoi함수가 실행될때 filename을 /bin/sh로 입력해주면 실행이 될것이다.

위 코드는 \x31\xf6\x31\xd2\xb0\x3b\x0f\x05로 8byte이다.


atoi함수가 실행되는 옵션 번호를 받아오는 함수이다.

해당 입력값은 &nptr로 들어가는데 이값이 sys_execve가 되면 rdi값으로 들어가게 된다.

그렇기 때문에 overwrite이후 입력값이 rdi 즉 실행시키는 파일주소로 들어가 sys_call을 실행시킨다.

우리는 rdi -> &nptr에 /bin/sh을 넣어주면 될것이다.


========================흐름 정리=======================

1. qword_2020e0[v2+i] = strdup(&s)를 보면 content에 입력한 값이 bss영역을 참조하는 배열의 인덱스로 들어가는데, index값에 음수를 넣어 줌으로써 got영역에 접근이 가능하고 content_input 함수를 통해 그 주소에 입력이 가능하다. -> got overwrite가 가능하다.

그리고 qword 단위로 들어가기때문에 주소는 8byte단위로 잘라준다.


2. 위부분의 if문을 우회하기 위해 strlen 함수의 got를 overwrite 해야한다. strlen의 반환값은 eax에 저장되므로 우회하기 위해서 eax를 0으로 고정시켜주는 어셈블리어를 기계어로 변환하여 넣어준다.  => \x31\xc0\xc3

ret은 프로그램을 계속 실행시켜주기위해 저장해둔 eip를 pop하는 것이다.


3.이후 쉘 코드를 넣어야 하지만 contant_input의 크기가 8byte로 되어있기 때문에 8byte에 맞춰서 exploit을 계획해야한다. 여기서 get_num함수에 있는 atoi함수를 이용한다. 이유는 atoi에 입력한 값이 & 즉 주소로 들어가기 때문이다. sys_execv의 함수의 첫번쨰 인자도 파일의 주소를 넣어줘야하기 때문에 atoi의 &인자가 들어가면 편하다.


4. atoi 함수를 got overwrite하기 위해 sys_execve을 함수 호출 규약에 맞게 어셈코드를 짜준다.

xor esi, esi

xor edx,edx

mov al,0x3b

syscall

위 코드를 기계어 코드로 변환하면 \x31\xf6\x31\xd2\xb0\x3b\x0f\x05 총 8바이트이다.

위 기계어로 got overwrite를 해주고 실행시키고 싶은 /bin/sh을 입력하면 쉘을 실행시킬 수 있다.


페이로드이다.




32-bit와 64-bit system 함수 호출 규약의 차이를 잘알아야한다.

기계어를 입력해주기 위해선 python프로그램을 통해 입력해줘야한다.



contant_input 은 변수명을 왜저렇게 설정했는지 모르겠다 bob중이라 뇌가 이상해졌었나보다

728x90

'CTF_writeup > 2018' 카테고리의 다른 글

Noote_ver0  (0) 2018.12.22
PCTF_2013_ropasaurusrex  (0) 2018.12.22
MMA-CTF-2-greeting  (0) 2018.12.22
Trustealth CTF easy  (0) 2018.12.22
ISITDTU CTF_xoxopwn  (0) 2018.12.22
728x90

서버에 접속했을 때 이다. This is function x()>>>가 출력되며 자유롭게 입력이 가능하다.

여러가지 testcase들을 통해 접근한다.

test들을 통해 계산을 해주고 입력이 길면 Big size~를 출력해주는 것을 알 수 있다.

__file__는 파이썬 심볼로 현재 실행중인 파일의 위치와 이름을 반환해준다.

__file__을 통해 py 즉 파이썬 파일이라는 것을 알 수 있다.

open(__file__)은 현재 실행중인 파일의 주소와 정보를 출력해준다.

Mode 'r' 을 통해 읽기 모드를 지원한다는것을 알 수 있다.


open(__file__).read()를 입력하면 소스코드가 출력된다.

소스를 분석해보면

ThreadTCPServer(host,port), TreadTCPRequestHandler)     //목적지 호스트와 포트에 들어오는 request에 대해 해당 클래스에 있는 handler을 실행시킨다.


프로그램을 실행시키면

위 함수가 실행된다.

recv함수를 통해 입력을 받으면 self.data로 입력한 값이 들어가고 self.data를 x함수에 인자로 넣어준다.

입력한 데이터가 들어가는 곳이다.

지금까지는 플래그와 관련없는 프로그램이 동작하는 소스를 분석한것이다.


플래그와 관련이있는 부분은 o함수이다.

위 함수의 조건문을 충족하면 flag를 보여준다.

a는 우리가 입력할 문자열이다. 

플래그를 얻으려면 우리가 입력한 문자열과 key데이터들을 xor연산한값이 secret값과 일치해야한다.

그러므로 secret값을 hex디코딩 한 값과 key의 값을 xor연산하면 플래그가 나온다.


문제해결 소스

플래그


728x90

'CTF_writeup > 2018' 카테고리의 다른 글

Noote_ver0  (0) 2018.12.22
PCTF_2013_ropasaurusrex  (0) 2018.12.22
MMA-CTF-2-greeting  (0) 2018.12.22
Trustealth CTF easy  (0) 2018.12.22
ISITDTU_CTF_dead_note_lv1  (0) 2018.12.22

728x90

서버에 접속했을때


readme를 먼저 읽어본다.


readme를 보면 asm파일이 asm_pwn권한으로 9026포트에서 돌아가고있다고한다. nc 0 9026에 연결해서 플래그를 얻을 수 있다.

플래그는 플래그파일의 이름은 여기 디렉토리에 있는 이름과 같다.


문제소스를 보자.


메인을 보면 출력해주는 문장들이 있다. shellcode를 만들 때 open(), read(), write() syscall 만을 사용해서 만들라고한다.


sandbox 함수를 실행시키는 밑부분을 보면 sh를 실행시키는 것을 알 수 있다. 

sh는 처음에 0x90 * 0x1000 으로 초기화 시키고 stub 를 포함시키며, read함수를 통해 sh에 원하는 데이터를 1000byte만큼 입력할 수 있다. 

sh에 포함되는 stub[] 가 뭔지 알아내자.


해당 기계어코드를 디스어셈블 한다.

모든 레지스터들을 0으로 초기화 시키는 것이다. syscall하기가 편해졌다.




chroot는 '프로세스 고립' 이라고 보면 된다. 주석을 보면 symlink 를 사용하지 못하게 하기위해 사용했다고 적혀있다.



Seccomp란 secure computing mode의 약자이다. Scmp_act_allow를 통해 syscall 가능한 함수들의 화이트 리스트를 뽑아주는 함수이다.

소스를 보면 open, read, write, exit, exit_group가 syscall 가능하다.


위 문제를 푸는 방법은 open을 통해 플래그 파일의 fd를 받아오고, read를 통해 flag파일의 데이터를 rsp에 저장, write함수를 호출하여

rsp에 저장된 데이터를 출력하게 만들어야한다.


쉘코드를 만드는 소스이다.

아키텍쳐를 arch 에 넣어주고 os도 설정해준다.

아키텍쳐나 os의 정보는 uname -a 명령을 통해서 확인 가능하다.

shellcraft함수를 통해 open,read,write 함수의 인자들을 설정해주어 기계를 출력할 수 있다.


open에 fd를 받아와야하는 파일의 이름을 넣어주고, read함수에 해당 fd가 저장되어있는 rax와 저장할 주소인 rsp, 그리고 사이즈를 넣어준다.

이후 write를 통해서 fd를 1로 설정하고 flag데이터가 저장되어있는 rsp와 size 100을 인자로 넣어주어 flag가 출력되게 해준다.


해당 쉘코드를 기계어 형태로 출력하면 문자들이 깨지기때문에 hexencode를 통해 출력해주고

페이로드 삽입시 hexdecode를 해준다.

flag가 출력된다. 이후 readme에 나와있는 포트주소에 데이터를 보내어 실제 flag를 받아온다.





쉘크래프트 좋다.

728x90

'Wargame_writeup > Pwnable.kr' 카테고리의 다른 글

fsb  (0) 2018.12.21
brainfuck  (0) 2018.12.21
passcode  (0) 2018.12.21
horcruxes  (0) 2018.12.21
cmd1  (0) 2018.12.21
728x90

main함수를 보면 welcome함수를 호출한다. welcome함수에서는 100byte만큼 name값을 할당해 줄 수 있다.

login함수에서는 passcode1과 passcode2를 해당 값들과 비교하여 플래그를 출력시켜 준다.

scanf함수를 잘보면 해당 변수의 주소를 가리켜 주는 &가 빠져있다. 

그로므로 해당 scanf함수는 인자로들어간 변수들의 주소값을 입력시킬 수 있는것이다.


welcome 함수를 잘보면 name변수의 시작주소가 ebp-0x70인것을 알 수 있다.

ebp-0x70부터 100을 더하면 ebp-0xc가 된다. name변수를 통해 입력해줄 수 있는 구간은 ebp-70x ~ ebp-0xc이다.


login함수에서 passcode 입력하는 부분이다.

passcode의 시작이 ebp-0x10이다. 이것을 통해 name변수와 입력하는 passcode의 주소가 ebp-0x10 ~ ebp-0xc로 4byte 겹친다는 것을 알 수 있다.


또한 scanf함수에서 &passcode1이 아니라 passcode1 를 사용한다.


정리를 해보면 name에서 name[96], name[97], name[98], name[99] 즉 마지막 4바이트는 passcode1이 가리킬 주소로 설정이 가능하며, 이후 scanf를 통해 해당 주소값을 변경 시켜줄 수 있다.    ==> got overwrite가 가능하다.


name에 96bytes 는 아무값이나 넣어주고 마지막 4바이트는 scanf다음에 호출하는 함수인 fflush 함수의 got를 넣어준다. passcode1의 주소가 fflush함수의 got를 가리키고 있는 상황에서 scanf함수를 통해 플래그를 출력해주는 if문 안의 주소로 변경해준다.


그러면 fflush함수를 실행시킬때 plt를 통해 정상적으로 got를 호출하지만 변경된 got를 통해 if문안의 주소를 호출하게 될것이다.


페이로드 작성을 위해 필요한것

fflush got

fflush의 got는 0x804a0080이다.


이동시킬 주소

이동시킬 주소는 0x080485e3이다. system함수의 인자가 들어가야하기 때문이다.


scanf에서 passcode1의 값을 %d 즉 10진수 정수형으로 받기 때문에 0x080485e3을 10진수인 134514147로 입력시켜준다.



입력받는 데이터의 길이를 잘 파악 해야한다.

원하는 주소값을 변경할 수 있으면 got overwrite가 가능해진다.

728x90

'Wargame_writeup > Pwnable.kr' 카테고리의 다른 글

brainfuck  (0) 2018.12.21
asm  (0) 2018.12.21
horcruxes  (0) 2018.12.21
cmd1  (0) 2018.12.21
leg  (0) 2018.12.19
728x90


Hint함수

int_ABCDEFG 함수


랜덤한 값의 a,b,c,d,e,f,g이다. 그리고 모두 합한 값을 sum에 넣는다.



Ropme 함수

입력한 알파벳에 해당하는 함수를 호출하고  a~g까지의 알파벳이아닌 값을 입력한후 sum과 같은값을 입력하면 flag를 출력해준다.

a를 입력했을 때 A함수를 실행시키는데 이때 랜덤한 a의 값을 출력시켜준다.



해당 문제에서 취약점은 gets함수에서 발생한다.

gets함수를 통해 overflow가 가능하다. 이것을 활용하여 if문안으로 접근해서 바로 플래그를 얻으려고 했으나

ropme함수의 주소가 0x080axxxx 이다. gets함수에서 0a값이 들어가면 개행문자로 인식하여 gets함수가 끝난다.

이 때문에 바로 ropme함수로 접근할 수 없다. 

그렇기 때문에 rop를 통하여 A~G까지의 함수호출을 통해 값을 추출해 내고 sum을 구하여 입력하는 방법으로 접근해야한다.


gets함수의 인자인 input2이다. ebp-0x74 위치에서 시작하므로 ebp까지덮으면 0x78이다. 0x78까지 덮고 ret주소를 A함수부터 G함수까지 차례대로 넣어주고 출력된값을 모두 더하여 입력시켜주면 flag를 얻을 수 있다.


페이로드이다.

recvuntil을 통해서 출력되는 문자열을 필요한부분만 잘라내어 정수값만 추출해 낸다. 이후 정수값들을 모두 더한뒤 8byte만큼 잘라주고 

비트 and 연산을 통해 부호를 살려주어 sum의 값으로 보낸다.

이것을 실행하면 플래그가 나온다.



문자열에서 원하는 값만 추출할 수 있다. recvuntil 활용


728x90

'Wargame_writeup > Pwnable.kr' 카테고리의 다른 글

asm  (0) 2018.12.21
passcode  (0) 2018.12.21
cmd1  (0) 2018.12.21
leg  (0) 2018.12.19
lotto  (0) 2018.12.19

+ Recent posts