일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 31 |
Tags
- github
- 김성엽 대표님
- 백준 파이썬
- suninatas 풀이
- 파이썬
- lord of sql injection
- window
- 사칙연산
- document
- 포인터
- jQuery
- object
- 메소드
- 배열
- 백준 알고리즘
- Pwndbg
- IF문
- 자바스크립트
- burp suite
- 객체
- element 조회
- python
- property
- blind sql injection
- sql injection
- xss game 풀이
- 조건문
- 함수
- htmlspecialchars
- xss game
Archives
- Today
- Total
power-girl0-0
[pwnable] input 풀이 본문
728x90
해당 문제는 디컴파일하지 않고, c언어 코드만 보고 풀 수 있는 문제이다.
본 글에서는 간단한 풀이 방법을 작성한다.
1. 공격 code 생성전, 알아가기!
(1) subprocess
새로운 프로세스를 생성하며, 이를 통해 입출력 파이프에 연결하고 반환 코드를 얻을 수 있는 모듈이다.
( 참고 : https://blog.naver.com/sagala_soske/221280201722 )
2. 문제 코드
문제의 c언어 코드이다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int main(int argc, char* argv[], char* envp[]){
printf("Welcome to pwnable.kr\n");
printf("Let's see if you know how to give input to program\n");
printf("Just give me correct inputs then you will get the flag :)\n");
// argv
if(argc != 100) return 0; //입력값이 100이 아니면 종료됨.
if(strcmp(argv['A'],"\x00")) return 0;
if(strcmp(argv['B'],"\x20\x0a\x0d")) return 0;
printf("Stage 1 clear!\n");
// stdio
char buf[4];
read(0, buf, 4); //buf에 저장할 4byte의 입력값을 받아옴.
if(memcmp(buf, "\x00\x0a\x00\xff", 4)) return 0;
read(2, buf, 4);
if(memcmp(buf, "\x00\x0a\x02\xff", 4)) return 0;
printf("Stage 2 clear!\n");
// env
if(strcmp("\xca\xfe\xba\xbe", getenv("\xde\xad\xbe\xef"))) return 0;
printf("Stage 3 clear!\n");
// file
FILE* fp = fopen("\x0a", "r");
if(!fp) return 0;
if( fread(buf, 4, 1, fp)!=1 ) return 0;
if( memcmp(buf, "\x00\x00\x00\x00", 4) ) return 0;
fclose(fp);
printf("Stage 4 clear!\n");
// network
int sd, cd;
struct sockaddr_in saddr, caddr;
sd = socket(AF_INET, SOCK_STREAM, 0);
if(sd == -1){
printf("socket error, tell admin\n");
return 0;
}
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = INADDR_ANY;
saddr.sin_port = htons( atoi(argv['C']) );
if(bind(sd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0){
printf("bind error, use another port\n");
return 1;
}
listen(sd, 1);
int c = sizeof(struct sockaddr_in);
cd = accept(sd, (struct sockaddr *)&caddr, (socklen_t*)&c);
if(cd < 0){
printf("accept error, tell admin\n");
return 0;
}
if( recv(cd, buf, 4, 0) != 4 ) return 0;
if(memcmp(buf, "\xde\xad\xbe\xef", 4)) return 0;
printf("Stage 5 clear!\n");
// here's your flag
system("/bin/cat flag");
return 0;
}
코드를 보면 알 수 있듯이, Stage 5단계까지 가면 flag를 확인할 수 있다.
3. Exploit Code
import socket
import subprocess
import os
import time
with open("\x0a", 'wb') as f:
f.write(b'\x00'*4)
args = []
for i in range(100):
args.append('A')
args[0] = './input'
args[65] = ''
args[66] = '\x20\x0a\x0d'
args[67] = '55000'
r, w = os.pipe()
spr = subprocess.Popen(args, stdin=r, stderr=r, env={b"\xde\xad\xbe\xef":b"\xca\xfe\xba\xbe"})
os.close(r)
time.sleep(1)
os.write(w, b'\x00\x0a\x00\xff')
os.write(w, b'\x00\x0a\x02\xff')
os.close(w)
time.sleep(1)
ip = '127.0.0.1'
port = 55000
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((ip,port))
sock.send(b'\xde\xad\xbe\xef')
sock.close()
4. flag 획득
교훈 : 하나를 하더라도, 꼼꼼히 공부하자.
p.s. 오늘 '브레이킹 루틴'이라는 책을 읽었다. 기억에 남아, 기록해본다.
1. 원하는 인생은 늘 안전지대 밖에 있다. 2. 시도를 안해보는 것보다 실패하는 것이 낫다. 3. 남들 시선보다, 내가 하고자하는 꿈을 바라보고 안전지대를 벗어나 도전하자. |
728x90
'War game > pwnable.kr' 카테고리의 다른 글
[pwnable] flag 풀이 (0) | 2022.02.12 |
---|---|
[pwnable] collision 풀이 (0) | 2022.02.09 |
[pwnable] asm 풀이 (0) | 2022.01.21 |
[pwnable] bof 풀이 (0) | 2022.01.20 |
[pwnable] fd 풀이 (0) | 2021.12.27 |
Comments