write up

제 18회 하계 해킹캠프 What is END?

slyfizz 2018. 9. 2. 10:38

이번에도 리버싱 1문제만 잡았지만 2%부족한 플래그로 인해서 정답을 인증하지 못했다.그래서 풀이가 공개되기 전에 플래그가 무엇인지만 알아내고 내가 먼저 write-up을 쓴다그래도 이번에는 ctf가 끝날즈음에 단 1명밖에 풀지못한 문제여서 시간이 조금만 더 있었다면 나도 풀 수 있었을거라고 생각한다


 


main함수에 들어가면 이런게 보인다!!

16진수 배열을 내가 입력한 문자열과 xor해서 나온값이 내가입력한 문자열의 다음인덱스가 아니면 v50으로 만들어서

플래그가 아닌 NOPE을 출력하고 맞으면 내가 입력한 그 값이 플래그이다.


1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h >
int  main() {
int  encoded[30 = { 0x43 ,0x5F ,0x30 ,0x2B ,0x1C ,0x0D ,0x3A ,0x3A ,0x0B ,0x0A ,0x3B ,0x36 ,0x1A ,0x2C ,0x25 ,0x1F ,0x17 ,0x1D ,0x30 ,0x30 ,0x1D ,0x2D ,0x31 ,0x1B ,0x19 ,0x53 ,0x3F };
char  flag[31 ];
flag[= 's';
int  i;
for  (i = 0 ; i <= 29 ; i ++) {
flag[i + 1 ] = flag[i] ^ encoded[i];
}
printf ("%s", flag);
}
cs

16진수 인덱스를 긁어와서 encoded라는 배열을 만들고 flag[0]에만 값을 넣어놓고 flag[1]부터는 flagencoded의 같은 번째 인덱스와 xor을 해서 나온 값을 다음 flag의 다음 인덱스에다가 넣는 코드이다.이때 flag[0= 's'; flag[0]에 여러가지 알파벳을 넣어보다가 

 

s를 넣으니 이렇게 그럴듯한 플래그가 출력되어서 코드에 추가하였다.


그리고 저걸 theend 프로그램에 넣으면 nope를 출력하므로

뭐가 문제일까 생각해보다가 코드를 다시 봐보니 놓친 부분이 있었다.

1
2
3
4
5
6
7
8
9
10
11
12
// input your code here#include <stdio.h >
int  main() {
int  encoded[30 = { 0x43 ,0x5F ,0x00 ,0x30 ,0x2B ,0x1C ,0x0D ,0x3A ,0x3A ,0x0B ,0x0A ,0x3B ,0x36 ,0x1A ,0x2C ,0x25 ,0x1F ,0x17 ,0x1D ,0x30 ,0x30 ,0x1D ,0x2D ,0x31 ,0x1B ,0x19 ,0x00 ,0x53 ,0x3F };
char  flag[31 ];
flag[= 's';
int  i;
for  (i = 0 ; i <= 29 ; i ++) {
flag[i + 1 ] = flag[i] ^ encoded[i];
}
printf ("%s\n", flag);
}
 
cs

V6과 V10에 0을 넣어주므로 배열명은 배열의 첫번째 인덱스를 나타내므로 v6과 v10의 첫번째 인덱스에0X00을 각각 추가시켜줘야 한다.

그러면 이런 문자열이 나오게 되고

 

이 문자열을 theend 프로그램에 넣으니 플래그가 나왔다.

The Flag is HCAMP{s0oo_the_end_is_zero_or_null?}

 

 

-------------------------------------------------------------------------------

추가수정:2018/10/09

파이썬을 공부하고 난 뒤에 브루트포스 코드를 파이썬으로 짜보았다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
encoded= [0x43,0x5F,0x00,0x30,0x2B,0x1C,0x0D,0x3A,0x3A,0x0B,0x0A,0x3B,0x36,0x1A,0x2C,0x25,0x1F,0x17,0x1D,0x30,0x30,0x1D,0x2D,0x31,0x1B,0x19,0x00,0x53,0x3F]
flag=[i for i in [0]*29]
for i in range(97,123):
    print(chr(i),':',end="")
    flag[0]=i
    print(chr(i),end="")
    for j in range(1,29):
        flag[j] = flag[j-1] ^ encoded[j-1]
        print(chr(flag[j]),end="")
    print("\n")
    
 
 
    
 
cs

 


---------------------------------------------------------------------------------------------------------------------------------------------------------

추가:2018/11/08

해킹캠프때 what is end를 푸는 방법이2가지가 있다고 하셨는데 파이썬 코드를 짜던중 2번째 방법을 이해하게되었다.

1번째방법은 위에서 한 것처럼 브루트포스코드를 짜는것이고

2번째 방법은 문자열의 끝은"\0"인것을 감안하여서 테이블의 맨 끝부터 역으로 xor해서 플래그를 알아내는 방법이다.

출제자이신 김승환님은 2번째방법이 의도한 풀이방법이라고 하셨다.

1
2
3
4
5
6
7
table=[0x43,0x5F,0x00,0x30,0x2B,0x1C,0x0D,0x3A,0x3A,0x0B,0x0A,0x3B,0x36,0x1A,0x2C,0x25,0x1F,0x17,0x1D,0x30,0x30,0x1D,0x2D,0x31,0x1B,0x19,0x00,0x53,0x3F]
s="\0"
flag=""
for i in table[::-1]:
    s=chr(i^ord(s))
    flag+=s
print(flag[::-1])
cs

flag:s0oo_the_end_is_zero_or_null?


역시 리버싱은 새벽에 가장 잘되는 것 같다.