
과제 중 train, validation loss 모두 nan이 나오는 현상을 확인했다.에러 로그도 없어 골치 아프던 와중 발견한 아래의 코드torch.autograd.set_detect_anomaly(True) autograd 중 어디에서 오류가 발생했는지 감지하고 출력하는 함수로, 코드 첫 줄에 넣어주면 된다. 로그에서 보이듯 backward 중 sqrt(0)의 derivative 계산에서 nan이 나왔다.torch.sqrt(x) 대신 torch.sqrt(x + 1e-8)로 바꾸어 해결하였다.

Overview Phase 5는 phase 3을 ROP를 사용해서 푸는 문제다. Phase 3를 푸는 과정 및 touch3 함수의 구성은 지난 게시물에서 다루었다. typedef struct st { char cookie_str[9]; int cookie_val; } st; 요약하면 위와 같이 cookie값을 char, int로 각각 포함하는 struct st를 만들고, st의 주소값을 %rdi에 넣은 채로 touch3 함수를 call하는 문제다. ROP Phase 5에 쓰이는 gadget은 start_farm 함수와 end_farm 함수 사이에 위치한다. $ objdump -d rtarget > rtarget.d rtarget의 전체 내용을 disassemble한 결과인 rtarget.d를 열어 sta..

Overview Phase 4, 5는 각각 phase 2, 3과 같이 touch2, touch3 함수를 알맞는 argument와 함께 call하는 것이 목표로, 실행하고자 하는 machine code를 직접 input으로 넣어주었던(Code injection) phase 2, 3과 달리 이미 존재하는 machine code의 일부를 gadget으로 사용하는 ROP(Return-Oriented Programming)를 사용해야 한다. touch2 함수의 구성과 해당 phase 2를 푸는 과정은 지난 게시물에서 다루었다. 요약하면 %rdi에 자신의 cookie값이 들어있는 상태에서 touch2 함수를 call하면 된다. ROP Phase 4에 쓰이는 gadget은 start_farm 함수와 mid_farm ..

Overview (gdb) disas touch3 touch3 함수의 구성을 살펴보자. touch3 함수는 argument로 st pointer type을 받는다. 참고로 st는 struct로, 구성은 아래와 같다. typedef struct st { char cookie_str[9]; int cookie_val; } st; cookie_str과 cookie_val은 각각 cookie의 string(0x00000000에서 0x 제외), unsigned value이다. 즉 %rdi에 st의 주소값을 넣는 코드가 필요하다. 물론 touch3, hexmatch, hexmatch 안에서 call되는 strncmp 함수들은 data를 stack에 push하므로 Buffer에 저장되는 우리의 입력값이 overwri..

Overview (gdb) disas touch2 touch2 함수의 구성을 살펴보자. touch2 함수는 argument 하나를 %rdi를 통해 받는다. 에서 %edi와 cookie값을 비교하며, 두 값은 같아야 한다. Buffer의 크기 등은 phase 1과 같다. 그럼 동일하게 buffer overflow를 발생시키고 touch2의 주소로 덮어씌우되, 그 전에 %rdi에 cookie값을 넣어주어야 한다. Code Injection Buffer의 크기는 24B, char로 24자리. getbuf에서는 입력한 string의 각 char를 buffer의 가장 바닥부터 채운다. getbuf에서 ret가 실행되면 buffer 위에 있는 return address로 이동하여 해당 위치부터 instruction..

Attacklab 시스템프로그래밍 Lab3 Attacklab이 나왔다. Bomblab에 이어 assembly를 다루는 과제이다. Bomblab이 gdb로 한 줄 씩 실행하며 폭탄이 터지지 않는 입력값을 찾는 문제였다면, Attacklab에서는 주어진 코드의 취약점을 파악하고 원하는 결과를 내는 입력값을 찾는다. 그 과정에서 Code injection(phase 1, 2, 3)과 return-oriented programming(phase 4, 5) 기법을 사용하게 된다. Overview (gdb) disas getbuf (gdb) disas touch1 getbuf, touch1 함수의 구성을 살펴보자. 우리의 목표는 비정상적으로 긴 길이의 입력값을 이용해 return address를 덮어씌워 touch..
Finding secret phase phase_defused 0x555555557089 : HelloKAIST phase_3 input을 100 -1606 -1601 HelloKAIST 으로 입력하면 4개가 들어간 것으로 저장되지만 phase_3은 통과됨. 마지막 phase_6까지 정답을 입력하면 마지막 phase_defused 실행 중 카운터가 6이 되어 jump함. phase_3에서 넣어준 입력의 마지막 string과 HelloKAIST를 비교하여 같으면 secret phase로 들어감. Overview (gdb) disas secret_phase secret_phase 함수의 구성을 살펴보자. Defusing secret phase 입력한 숫자 a가 hex로 rax에 저장됨 원본 rax ebx에 ..
Overview (gdb) disas phase_6 phase_6 함수의 구성을 살펴보자. Defusing phase 6 입력한 숫자 a b c d e f g h. a가 가장 앞에 오는 순서로 stack에 저장됨. test input : 1 2 3 4 5 6 7 8 r13 0으로 만들고 82로 이동 r12 즉 rsp를 rbp에 저장 eax에 a 저장후 1 빼기 eax는 7 이하. 즉 a는 8 이하 r13에 1 더하고 r13 == 8이면 112로 이동 r13 8 아니면 ebx에 r13 저장 후 60으로 이동 rax에 ebx 저장 stack에서 4 * rax의 index에 있는 값 eax로 이동 eax와 a는 달라야함. 52로 이동 ebx에 1 더하고 7보다 크면 78로 이동 7 이하면 rax에 ebx 저장..
Overview (gdb) disas phase_5 phase_5 함수의 구성을 살펴보자. Defusing phase 5 입력한 숫자 x y. x는 (%rsp), y는 0x4(%rsp)에 저장 test input : 2 3 rax는 x & 0xf. 0xf면 터짐 rdx에 eax 옮기고 eax에 rdi array에서 4 * rdx 위치의 값 넣는다. 14 -> 6 -> 15 esi에 r8 value에서 4 * rdx 위치의 값 더한다. esi는 0에서 시작 8 + 43 + 35 = 86 eax가 0xf가 될때까지 반복. 반복 횟수는 ecx = 3 0x555555556d60 rdi 0x555555556d60 : 10 2 14 7 0x555555556d70 : 8 12 15 11 0x555555556d80 :..