본문 바로가기

Wargame/Bandit

[ Docker ] Bandit Wargame 만들기 - 20번 문제 ( 21 / 33 )

1. Bandit20 목표

There is a setuid binary in the homedirectory that does the following: 
it makes a connection to localhost on the port you specify as a commandline argument.
It then reads a line of text from the connection and compares it to the password in the previous level (bandit20).
If the password is correct, it will transmit the password for the next level (bandit21).

NOTE: Try connecting to your own network daemon to see if it works as you think

Commands you may need to solve this level
ssh, nc, cat, bash, screen, tmux, Unix ‘job control’ (bg, fg, jobs, &, CTRL-Z, …)

 

2. Bandit20 구현

# 비밀번호 root 입력 접속
ssh -oStrictHostKeyChecking=no root@localhost -p 2220

chown -R root:root /home/bandit20/.[!.]*

cat <<'BANDIT_TMP' > /tmp/suconnect.c
#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>

#define BUFFER_SIZE 1024

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <portnumber>\n", argv[0]);
        printf("This program will connect to the given port on localhost using TCP. If it receives the correct password from the other side, the next password is transmitted back.\n");
        exit(EXIT_FAILURE);
    }

    int port = atoi(argv[1]);
    int sockfd;
    struct sockaddr_in server_addr;
    char buffer[BUFFER_SIZE];
    int bytes_received;

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("Socket creation error");
        exit(EXIT_FAILURE);
    }

    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);

    if (inet_pton(AF_INET, "127.0.0.1", &server_addr.sin_addr) <= 0) {
        perror("Invalid address or address not supported");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        printf("Could not connect\n");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    // printf("Connected to the server. Waiting for response...\n");

    bytes_received = read(sockfd, buffer, BUFFER_SIZE - 1);
    if (bytes_received > 0) {
        buffer[bytes_received] = '\0';
        printf("Read: %s", buffer);

        if (strcmp(buffer, "GbKksEFF4yrVs6il55v6gwY5aVje5f0j\n") == 0) {
            printf("Password matches, sending next password\n");
            const char *response = "gE269g2h3mw3pwgrj0Ha9Uoqen1c9DGr\n";
            write(sockfd, response, strlen(response));
        } else {
            printf("ERROR: This doesn't match the current password!\n");
            const char *response = "FAIL!\n";
            write(sockfd, response, strlen(response));
        }

    } else if (bytes_received < 0) {
        perror("Read error");
    }

    close(sockfd);
    return 0;
}
BANDIT_TMP

gcc -o /home/bandit20/suconnect /tmp/suconnect.c

useradd bandit21 && echo -e "gE269g2h3mw3pwgrj0Ha9Uoqen1c9DGr\ngE269g2h3mw3pwgrj0Ha9Uoqen1c9DGr" | passwd bandit21

chmod 755 /home/bandit21

chown root:root /home/bandit21

chown bandit21:bandit20 /home/bandit20/suconnect

chmod 4750 /home/bandit20/suconnect

echo gE269g2h3mw3pwgrj0Ha9Uoqen1c9DGr > /etc/bandit_pass/bandit21

chmod 400 /etc/bandit_pass/bandit21

chown bandit21:bandit21 /etc/bandit_pass/bandit21

 

3. Bandit20 문제풀의

# bandit20 로 설정한 패스워드를 입력하여 접속한다.
# GbKksEFF4yrVs6il55v6gwY5aVje5f0j
ssh -oStrictHostKeyChecking=no bandit20@localhost -p 2220

# suconnect 파일 확인
ls -la

# screen 진입
# screen : 일반적인 진입
# screen -S [세션이름] : screen세션 이름을 지정하여 실행
# screen -r [세션이름] : 실행중인(Detached) screen 세션으로 재 진입시 실행하는 명령어, screen세션이 하나만 실행중일 경우 세션이름을 입력하지 않아도 진입이 된다.
# screen -x [세션이름] : 실행중인(Attached) screen 세션으로 재 진입시 실행하는 명령어, screen세션이 하나만 실행중일 경우 세션이름을 입력하지 않아도 진입이 된다.
# screen -ls         : 실행중인 screen 확인
# exit               : screen 탈출 및 screen을 종료
# Ctrl+a, c : 새창 띄우기
# Ctrl+a, a : 바로 전 창으로
# Ctrl+a, n : 다음 창으로
# Ctrl+a, p: 이전 창으로
# Ctrl+a, 스페이스 : 다음 창으로
# Ctrl+a, 백스페이스 : 이전 창으로
# Ctrl+a, 0 : 0번째 창으로
# Ctrl+a, 1 : 1번째 창으로
# Ctrl+a, 9 : 10번째 창으로
# Ctrl+a, d : screen 탈출(screen은 계속 실행중이다.)

# 실행중인 screen 세션 모두 종료
screen -ls | awk '/\t/{print $1}' | xargs -I {} screen -S {} -X quit

# screen 생성 및 nc -l -p 9789 를 전달하여 
# 9789 포트가 리스닝 상태로 되도록 함 i.g. 9789는 임의의 포트
# 재접속 했을때 종료가 되지 않도록 bash 명령어도 함께 전달
screen -dmS session1 bash -c 'nc -l -p 9789; exec bash'

# 9789 포트로 접속하도록 하여 이전 문제의 정답을 수신받고 정답을 송신할 수 있도록 함 
screen -dmS session2 /home/bandit20/suconnect 9789

# session1 재접속
screen -r session1

# 이전 패스워드를 전달하여 다음 문제 정답 확인
GbKksEFF4yrVs6il55v6gwY5aVje5f0j