일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 파이썬
- 딥러닝
- PICO CTF
- 신경망 학습
- sgd
- 아파치
- flag
- Python Challenge
- 책
- CTF
- 리뷰
- 오차역전파법
- picoCTF
- 순전파
- C언어
- 백준
- PostgreSQL
- 신경망
- 기울기
- 우분투
- 소프트맥스 함수
- 코딩
- FastAPI
- Python
- AdaGrad
- Apache2
- PHP
- 설치
- HTML
- 역전파
- Today
- Total
Story of CowHacker
Pwnable_input 본문
pwnable.kr 사이트 문제 중 input이라는 문제를 풀어볼 것이다.
출처 : http://pwnable.kr/play.php
http://pwnable.kr/play.php
pwnable.kr
문제 서버에 접속을 해봤다.
드래그 한 부분에 대충 /tmp 아래에 파일은 언제든 지울 수 있고, /tmp 아래에 나의 디렉터리를 만들라는 소리인 거 같았다.
다음은 문제 서버에 c파일이 있길래 열어 봤다.
c파일의 내용은 엄청 길었다.
중간중간에 Stage 1 clear!라고 위 코드를 만족시키면 클리어를 시켜 주는 듯했다.
총 5개 보였다.
먼저 나는 Stage 1 위에 printf 문을 봤다.
출처 : https://papago.naver.com/
네이버 파파고
번역을 부탁해 파파고
papago.naver.com
프로그램에 입력하는 방법을 아냐는 것과
정확한 입력을 하면 flag를 얻을 수 있다는 말이 있는 걸로 보아
내가 추측한 것처럼 Stage 마다 만족 코드를 입력하면 되는 것 같았다.
이제 첫 번째 Stage를 봤다.
코드 해석을 해보면
1. main함수에 100개의 인자 개수를 전달하라는 것 같았다.
2. argv ['A']가 \x00 이여야 하는 것 같았다.
3. argv ['B']가 \x20\x0a\x0d 이여야 하는 것 같았다.
이제 이걸 어떻게 만족하는 코드를 입력해줘야 할까 하다 구글링을 해봤다.
처음에 봤던 /tmp 파일 밑에 내 파일을 만들어 거기에 파이썬 코드를 짜서 입력을 줘야 되는 걸 알게 되었다.
나는 이 사실을 알고 난 후 " 프로그램에 입력하는 방법을 아냐 "라는 질문을 한 printf 문을 다시 한번 생각하게 됐다.
이것이 바로 프로그램에 입력하는 방법이구나 라고 말이다.
포 너블 서버에서 파일을 실행할 때 from pwn import * 를 명시해둬야 한다고 구글에 나와있어서 명시해놨다.
argvs라는 리스트를 만들고
그 리스트 안에 타입은 문자열로 100개를 넣었다.
그리고 ord라는 함수를 써
argvs ( ' A ' )에 \x00와
argvs ( ' B ' )에 \x20\x0a\x0d를 넣었다.
여기서 사용한 ord는 문자의 아스키코드 값을 돌려주는 함수다.
다음은 stage 2를 봤다.
두 번째 문제는 표준 스트림에 대해 알아야 하는 문제였다.
read ( 0, buf, 4 ); 에서 숫자 0은
표준 스트림에서 stdin을 뜻하고
두 번째 read ( 2, buf, 4 ); 에서 숫자 2는
표준 스트림에서 sterr를 뜻한다.
이제 이것을 해석해보면
stdin에 \x00\x0a\x00\xff을 주고 sterr에 \x00\x0a\x02\xff을 줘야 된다는 걸 알 수 있다.
그런데 여기서는 일단 sterr에만 값을 주기로 한다.
그 이유는 stage 5를 풀떄 나온다.
다음은 Stage 3문제를 봤다.
getenv가 뭔지 구글링을 해보니 환경 변수를 뜻했다.
\xde\xad\xbe\xef라는 환경변수가 strcmp 즉, \xca\xfe\xba\xbe이어야 한다는 말 같았다.
다음은 Stage 4를 봤다.
먼저 \x0a라는 파일을 연다는 걸 볼 수 있었다.
그리고 if ( fread ( buf, 4, 1, fp )!= 1 ) return 0;
에서 보면 첫 번째 값이
if ( memcmp ( buf, "\x00\x00\x00\x00", 4 ) ) return 0;
즉 \x00\x00\x00\x00 이여야 하는 것 같았다.
다음은 Stage 5를 보겠다.
마지막 Stage 5번.... 구글의 힘을 좀 많이 썼다.
atoi(argv ['C'])를 정수형으로 변환한 값을 포트번호로 소켓 서버를 열고
이후에 4바이트 문자열을 입력받아 \xde\xad\xbe\xef 와같으면 stage 5가 클리어 된다.
argvs [ ord ( ' C ' ) ] = '55555'
여기서 정수형으로 변환한 값을 포트 번호로 소켓 서버를 열었다.
target = process (target = process(executable='/home/input2/input', argv=argvs, stderr=open('./stderr'), env=envVal)
여기서는 인자를 argv에 전달해주고 stderr파일을 열고 환경변수도 설정해주는 작업을 한다.
target.sendline('\x00\x0a\x00\xff')
그리고 바로 여기서 Stage 2의 stderr의 값을 넣어준다.
conn = remote('localhost', '55555')
conn.send("\xde\xad\xbe\xef")
target.interactive()
마지막으로 내가 설정한 5555 포트를 열어
\xde\xad\xbe\xef이라는 값을 넘겨줬다.
이제 내가 만든 파일을 실행을 해봤다.
그런데 클리어는 뜨는데 flag는 뜨지 않았다.
머지해서 봤는데 내가 만든 이 파일 안에는 flag가 없었다.
구글링 해보니 내 파일에 flag의 심볼릭 파일을 하나 만들고 실행을 해야 한다는 걸 알았다.
클리어가 뜨고 마지막에 flag가 보였다.
'공부 > Pwnable' 카테고리의 다른 글
Pwnable_Random (2) | 2020.07.24 |
---|---|
Pwnable_Passcode (0) | 2019.12.16 |
Pwnable_Flag (0) | 2019.11.30 |
Pwnable_Bof (0) | 2019.11.29 |
Pwnable_collision (0) | 2019.11.24 |