이번에 풀이할 문제는 HackCTF의 RTL_Core 문제다. 문제 파일로는 바이너리와 libc가 주어져 있다. 문제 파일을 실행해보면 Passcode를 입력 받는다. 입력 값을 검증해서 성공, 실패 여부를 결정하는 것 같다. 보호 기법은 nx bit만 걸려 있는 것을 알 수 있다. ida로 main 함수를 확인해보면 입력 값을 bof에 취약한 함수 gets로 받고, 입력 값을 check_passcode 함수의 인자로 전달한 후 리턴 값과 hashcode라는 값과 비교한다. ida에서는 한글이 깨져서 이상하게 나와 있지만, 어쨌든 hashcode와 일치한다면 무언가를 출력해준 뒤, core 함수를 호출해준다. 일치하지 않을 경우 위에서 봤던 "실패!" 문구를 출력해주는 것 같다. 잠만 깨진 문구가 이상하..
Wargame
HackCTF의 Random Key 문제다. 전에 참여했던 ctf에서 비슷한 유형의 문제를 풀어봤기(삽질했기) 때문에 굉장히 쉽게 풀 수 있었다. 문제 바이너리를 실행해보면 다음과 같이 인증 프로그램이라는 문구가 출력되고 input key 입력을 받는다. 그 후 어떠한 로직을 통해 입력한 키 값이 올바른지 검증 후 결과를 출력해주는 것 같다. 코드는 간단하다. 문구들을 출력하고 scanf로 입력을 받는데(%d로 입력 받는다. 취약점 없다 ㅋㅋ), 입력 받은 값이 rand 함수를 통해 랜덤으로 생성한 값과 일치하다면 flag를 준다. 참고로 이 srand(time(NULL));를 써줬기 때문에 매번 생성되는 값은 랜덤하다. 겉보기에는 취약해보이지 않지만, 들으면 아!하고 무릎을 탁 칠만큼 기발한 공격 방법..
이번에 풀이할 문제는 HackCTF의 g++ pwn 문제다. 문제 이름이 g++걸 봐서 c++ 소스 코드를 컴파일해주는 g++ 컴파일러가 생각난다. 문제 파일을 실행해보니 입력을 받고, 입력을 받은 값을 출력해주는 동작을 한다. 혹시하고 입력 값으로 많은 1 값을 줬지만 Segment fault 오류는 터지지 않는 것을 알 수 있다. bof 문제가 아닐 수도 있는 것 같다. 보호기법은 nx만 걸려있는 것을 알 수 있다. ida는 제대로 해석을 못하는 것 같아서 ghidra로 main 함수를 확인해봤다. main 함수는 vuln 함수만 호출한다. vuln 함수를 확인해보면 fgets 함수를 이용해 local_40에 32byte만큼 입력을 받는 것을 알 수 있다. local_40의 크기는 32byte인데, ..
이번에 풀이할 문제는 HackCTF의 RTL_World 문제다. 요즘 HackCTF 문제를 잘 안풀고 있었는데, 갑자기 HackCTF 포너블 문제를 올클해보자는 욕구가 생겨 풀이하게 됐다. 일단 문제 명만 봤을 때는 rtl 공격 기법이 쓰일 것 같다. 문제 파일을 실행해본다면 다음과 같은 문구가 출력된다. 신박해보인다. 저기 나온 선택지를 다 선택해봤지만 딱히 얻을 수 있는 정보는 없었다. 다만 3, 4번은 어느정도의 자본(gold)이 필요하다는 것을 알게됐고, 이 파일의 목적은 binary boss를 죽이는, 즉 exploit하는 것임을 알 수 있었다.(1번 선택지를 선택하면 문제 파일의 보호기법이 출력된다.) 일단 ghidra로 열어봐야겠다. undefined4 main(void) { int iVar..
cobolt로 로그인하면 goblin 문제를 볼 수 있다. goblin 문제를 실행해본다면 입력을 받은 뒤, 입력을 받은 값을 똑같이 출력해준다. 소스코드를 확인해보면 bof에 취약한 대표적인 함수인 gets 함수로 입력을 받는다. 이 gets 함수는 입력 값의 길이에 제한을 두지 않기 때문에, 입력 값이 저장되는 buffer 변수의 크기인 16byte 이상 입력을 한다면 overflow가 발생한다. 딱봐도 쉘 코드를 buffer에 삽입하기에는 공간이 부족하기 때문에 환경변수를 이용해야 될 것 같다고 생각했다. 일단 buffer가 16byte 크기고 다른 변수들은 존재하지 않기 때문에 굳이 gdb로 열어볼 필요 없이 blind 상태로도 exploit이 가능할 것 같았다. buffer의 크기가 16byte..
gate 문제를 풀 때 wsl telnet을 이용해 접속했다가 쉘이 얻어지지 않는 문제가 생겨, 이번에는 putty로 접속했다. 문제 파일 cobolt와 소스코드 cobolt.c가 주어져 있다. 문제 파일을 실행해보니 인자를 받는 것을 알 수 있었다. 많은 '1'을 인자로 주니 Segmentation fault가 터진 것을 보아 bof 취약점이 있을 가능성이 높다. 소스코드를 확인해보면 인자 값을 strcpy 함수로 16byte 크기의 buffer에 복사해주는데, gate 때와 마찬가지로 길이를 검증하는 로직이나 함수를 사용하지 않는다. 따라서 인자 값으로 16byte보다 긴 값을 준다면 overflow가 발생한다. gate와 마찬가지로 buf에 쉘 코드를 삽입한 뒤 ret를 buf의 주소로 조작해 쉘을..
wsl ubuntu에서 telnet을 이용해서 접속해봤다. 1단계 id와 pw는 gate/gate다. ls 명령어로 무슨 파일이 있는지 확인해봤다. gremlin, gremlin.c라는 문제 파일과 그 소스코드가 존재하는 것을 알 수 있다. gremlincp 파일은 풀이 과정에서 디버깅을 위해 gremlin 파일을 복사한 것이다. 권한을 확인해보면 gremlin 파일에는 gremlin 계정으로 setuid가 걸려있다. 이 문제 파일을 공격한다면 gremlin 권한으로 된 쉘을 얻을 수 있을 것이다. int main(int argc, char *argv[]) { char buffer[256]; if(argc < 2){ printf("argv error\n"); exit(0); } strcpy(buffer,..
LOB를 할 때 정상적으로 exploit이 될 만한 코드도 안되는 경우가 있는데, 그 이유는 lob의 bash 버전이 낮기 때문에 \xff를 \x00으로 처리하기 때문이다. 이 말인 즉슨 ret를 \xff가 들어가는 주소로 변조한다 가정하면, 이 \xff는 \x00으로 인식되기 때문에 \xff가 입력되는 순간 더 이상의 입력을 받지 않게 된다. 따라서 정상적인 공격이 힘들어지는 것이다. 해결 방법은 간단하다. root/hackerschoolbof로 로그인한 후 vi /etc/passwd를 입력해 vi 에디터로 진입하고 :를 입력 후 %s/bash/bash2/를 입력해준다면 bash 버전이 2로 바뀌게 되면서 원활한 문제 풀이가 가능해진다. -login- id : root pw : hackerschoolb..
보호되어 있는 글입니다.
level19로 로그인한 후 hint를 확인해보면 소스코드가 나온다. 전 단계에서 많은 양의 코드를 보여줬기에 19 level은 더 많거나 복잡할 줄 알았지만 예상보다 간단했다. 소스코드도 작고 대놓고 gets 함수가 보여서 bof가 일어남을 알 수 있다. 공격은 gets를 통해 overflow를 일으켜 ret를 쉘 코드가 들어간 환경변수의 주소로 변조하면 될 것 같다. 이번 단계는 setuid가 없기 때문에 setuid가 포함된 쉘 코드를 써야겠다. main의 함수 프롤로그 부분과 gets 함수 부분에 bp를 걸고 실행한다면 ret와 buf의 스택 주소를 알 수 있다. ret : 0xbffff45c buf : 0xbffff430 따라서 ret와 buf 사이의 거리는 44byte인 것을 알 수 있다. r..