萌新帶你開車上p站(三)


本文作者:萌新

前情回顧:

萌新帶你開車上p站(一)

萌新帶你開車上p站(二)

 

0x08


 

題目給的提示是和運算符優先級有關

 1.png

登錄后直接看源碼

 

mistake@pwnable:~$ ls

flag  mistake  mistake.c  password

mistake@pwnable:~$ cat mistake.c

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

}

}

 

int main(int argc, char* argv[]){

 

 

int fd;

if(fd=open("/home/mistake/password",O_RDONLY,0400) < 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;

}

 

看關鍵:

main調用的xor函數: 

2.png

將長度給len的字符串與1異或

main中的主要邏輯 

3.jpg

從/home/mistake/password讀10個字節數據放到pw_buf,我們手動輸入10字節數據放在pw_buf2,如果pw_buf2與1異或的結果如果與pw_buf相等,則打印flag

那么關鍵就是pw_buf的數據,先直接讀password看看 

4.png

沒有權限

題目的提示是和運算符優先級有關

我們仔細分析源碼,看看問題出在哪里

問題在這里

if(fd=open("/home/mistake/password",O_RDONLY,0400) < 0){

open函數里權限檢查是沒問題的,O_RDONLY表示以只讀方式打開

0400表示文件所有者具有可讀取的權限

由於權限通過檢查,所以open函數返回值為0

有因為0<0不成立

所有比較結果為0

然后賦值給fd

即fd為0,表示標准輸入,也就是說fd現在是我們可控的

結合之前分析,pw_buf也為我們控制

那就很簡單了 

5.png

第一次輸入10個1,存入pw_buf

第二次輸入10個0,存入pw_buf2,與1異或后覆蓋pw_buf2,此時buf2的值也為10個1,滿足打印flag的邏輯

 

0x09shellshock


 

查看權限 

6.png

可以看到shellshock程序的所屬組的權限位上有s,表示sgid,也就是說在執行shellshock時,用戶將獲得shellshcok所屬組的權限,即執行shellshock后將獲得root所在用戶組的權限,而由flag這一行的權限位可知,該權限可以讀取flag

這一點從源碼中也可以看出來

7.png

getegid()返回進程執行有效組識別碼。在這里getegid()返回的就是root所在用戶組的id

setresuid用於設置ruid,euid,seuid,在這里就是統統都設置為進程當前的egid

setresgid用於設置rgid,egid,sgid,這里也是統統設置為進程當前的egid

因為s標志,所以egid實際上是root所在用戶組的id

再根據題目提示的shellshock

這是著名的bash破殼漏洞

直接在網上找到poc修改下即可 

8.png

解釋一下發生了什么

首先在當前環境下定義了X函數,函數體由{}括起來,然后在函數體外加了一條額外的語句/bin/cat ./flag即打印flag的命令,這條語句會在后面執行./shellshock時被調用,由於執行shellshock時會有root權限,所以自然就有權限來打印flag了

 

想知道怎么操作嗎?點擊開始實踐——破殼漏洞實踐http://www.hetianlab.com/expc.do?ec=ECID172.19.105.222014092915250400001

9.jpg

0x10


 

按照要求連接服務器 

0.jpg

這是一個小游戲

大意是一堆貨幣里有真幣假幣,兩者重量不同,真幣10g,假幣9g。給你N個硬幣,C次機會,讓你猜哪一個是假幣。需要在30s的時間里才對100次。

這題其實考的是算法。

分治法解決

舉個例子。

一共100個硬幣,其中1個是假的,先稱重1-49,如果結果整除10,則假幣在50-100.

第二輪稱50-75,如果不整除10,則假幣在其中

第三輪稱50-62.。。。。

其實就是簡單的二分法

編程

import time

from pwn import *

 

conn = remote('0', 9007)

conn.recv(10000)

for _ in range(100)://猜100次

    line = conn.recv(1024).decode('UTF-8').strip().split(' ')

  print(line)

    n = int(line[0].split('=')[1])//讀出給的n,c

    c = int(line[1].split('=')[1])

    left = 0

    right = n//共n個硬幣

 

    for _ in range(c)://二分法猜解

        guess = ' '.join(str(left) for left in range(left, int((left+right)/2)))

        conn.sendline(guess)//給出需要猜測的貨幣

        output = int(conn.recv(1024).decode('UTF-8').strip())//讀取返回稱重的結果

        if (output % 10 == 0)://整除10的情況

            left = int((left+right)/2)

        else://不整除的情況

            right = int((left+right)/ 2)

    conn.sendline(str(left))

    print(conn.recv(1024).decode('UTF-8'))//打印一輪的結果

print(conn.recv(1024).decode('UTF-8'))

conn.close()

 

以上一關的shellshock登錄服務器,在tmp目錄下新建一個python 腳本

按照提示

用pwntools編寫的時候,注意remote(‘0’,9007)

執行如下 

11.png

12.jpg

0x11 blackjack 


 

13.jpg

em...源碼有點長,直接看關鍵部分 

14.png

這里會校驗我們輸入的金額

如果比cash大則會報錯,並要求再次輸入

不過再次輸入的時候不會報錯了

考慮到要賺夠1000000,而輸的幾率比較大

我們可以輸入-的金額,比如-1000000,只要輸了就可以拿到flag

15.jpg

然后選擇y就打印出flag了

16.png


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM