「安全筆記」2019 Hgame week 1-2 writeup

「安全筆記」2019 Hgame week 1-2 writeup

資源介紹參數
資源類別: 代碼筆記
如遇問題: 聯繫客服/留言反饋
釋放雙眼,帶上耳機,聽聽看~!

CTF-SSH-BANNER

H-Game,不是那種。。

WEB

week-1

誰吃了我的flag?

題干提示了vim,沒好好關機,知道了是Linux的vim異常登出
所以訪問 .index.html.swp得到swp,扔到Linux里vim .index.html.swp -r恢復,得到flag,這裡注意前面的.剛開始一直沒出來還在硬掃後台。。。最後dalao前面有個.。。

換頭大作戰

有個搜尋框,隨便輸入一個1,返回了request method is error.I think POST is better那就用hackbar post提交一個want=1(chrome也有hackbar了),然後回顯https://www.wikiwand.com/en/X-Forwarded-For only localhost can get flag 然後用burp改包,用X-Forwarded-For偽造ip,重Q發後返回提示需要水狐瀏覽器訪問,繼續改包,修改User-agent為水狐Waterfox/50.0,繼續重發,提示需要從bilibili來訪問,繼續改,把referer改成bilibili,最後把cookies修改成1,得到flag

very easy web

error_reporting(0);
include("flag.php");

if(strpos("vidar",$_GET['id'])!==FALSE)
  die("<p>乾巴爹</p>");

$_GET['id'] = urldecode($_GET['id']);
if($_GET['id'] === "vidar")
{
  echo $flag;
}
highlight_file(__FILE__);

題目中有個urldecode審計後發現是雙重url編碼就可以繞過
payload

can u find me?

題目提示為什麼不問問神奇的十二姑娘和她的小夥伴呢
F12在元素中找到f12.php訪問,要我們提交一個password,密碼在響應頭中,提交後,回顯aoh,your speed is sososo fast,the flag must have been left in somewhere,查找一番發現沒有什麼結果,看了一眼f12,發現是存在跳轉。開burp比較麻煩,直接用curl獲取相應體curl -i

第一周的web就結束了

week-2

easy_php

題目標題提示where is my robots?直接訪問robots看到裡面的img/index.php訪問得到源碼

error_reporting(0);
$img = $_GET['img'];
if(!isset($img))
    $img = '1';
$img = str_replace('../', '', $img);
include_once($img.".php");
highlight_file(__FILE__);

就是替換了../的文件包含,直接雙寫繞過就好了
payload ,發現得到的竟然不是,思考了下,這裡竟然有文件包含,嘗試利用偽協議讀取源碼得到flag

php trick

//admin.php
highlight_file(__FILE__);
$str1 = (string)@$_GET['str1'];
$str2 = (string)@$_GET['str2'];
$str3 = @$_GET['str3'];
$str4 = @$_GET['str4'];
$str5 = @$_GET['H_game'];
$url = @$_GET['url'];
if( $str1 == $str2 ){
    die('step 1 fail');
}
if( md5($str1) != md5($str2) ){
    die('step 2 fail');
}
if( $str3 == $str4 ){
    die('step 3 fail');
}
if ( md5($str3) !== md5($str4)){
    die('step 4 fail');
}
if (strpos($_SERVER['QUERY_STRING'], "H_game") !==false) {
    die('step 5 fail');
}
if(is_numeric($str5)){
    die('step 6 fail');
}
if ($str5<9999999999){
    die('step 7 fail');
}
if ((string)$str5>0){
    die('step 8 fial');
}
if (parse_url($url, PHP_URL_HOST) !== "www.baidu.com"){
    die('step 9 fail');
}
if (parse_url($url,PHP_URL_SCHEME) !== "http"){
    die('step 10 fail');
}
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
$output = curl_exec($ch);
curl_close($ch);
if($output === FALSE){
    die('step 11 fail');
}
else{
    echo $output;
}

我覺得一道挺好的入門題。。。嗯。。。有很多的PHP特性,一個個來解釋
step1,2 php弱類型特性,md5加密後0e繞過,
step3,4 字符串不相等md5嚴格相等,利用false===false繞過,直接傳入陣列,md5返回false
step5 請求里必須存在H_game這個參數
step6,7,8 要求str5不是數字或數字字符串,並且小於9999999999大於0(這裡有個小tips,php中陣列大於一切數字),str5是通過H_game來獲取的,這樣就與step5矛盾,需要繞過,這裡可以對H使用url編碼繞過,看了大佬的wp後學到了一個新姿勢

在遇到需要在url中請求如:A_A這樣的值的時候,可以通過A.A或者A+A來達到相同的效果。

PHP變數名不能帶有點[.] 和空格,否則在會被轉化為下劃線[_] (+號在url中表示空格)

即在url中使用 H+game 代替。

step9,10 使用curl來訪問,這裡繞過即可,因為parse_urllibcurlurl的解析問題造成ssrf
code>parse_url解析的是host最後一個@符號後的host/code>,但是libcurl解析的是第一個@後的host,所以這裡這樣就可以繞過/http://@localhost@www.baidu.com/admin.php,得到源碼

//flag.php
if($_SERVER['REMOTE_ADDR'] != '127.0.0.1') {
    die('only localhost can see it');
}
$filename = $_GET['filename']??'';

if (file_exists($filename)) {
    echo "sorry,you can't see it";
}
else{
    echo file_get_contents($filename);
}
highlight_file(__FILE__);

看到這裡的file_exists()file_get_contents()明顯衝突,使用php://filter/read=convert.base64-encode/resource=flag.php繞過
最後的payload

PHP Is The Best Language

源碼

include 'secret.php'; 

#echo $flag; 
#echo $secret; 

if (empty($_POST['gate']) || empty($_POST['key'])) { 
    highlight_file(__FILE__); 
    exit; 
} 

if (isset($_POST['door'])){ 
    $secret = hash_hmac('sha256', $_POST['door'], $secret); 
} 

$gate = hash_hmac('sha256', $_POST['key'], $secret); 

if ($gate !== $_POST['gate']) { 
    echo "Hacker GetOut!!"; 
    exit; 
} 

if ((md5($_POST['key'])+1) == (md5(md5($_POST['key'])))+1) { 
    echo "Wow!!!"; 
    echo "</br>"; 
    echo $flag; 
} 
else { 
    echo "Hacker GetOut!!"; 
} 

hash_hmac — 使用 HMAC 方法生成帶有密鑰的哈希值
當第二個參數為陣列的時候返回null,利用這個特性,即使不知道$secret,也可以控制$gate這個參數。
然後就是(md5($_POST['key'])+1) == (md5(md5($_POST['key'])))+1)繞過了,這個可以利用弱類型,構造0e,提供一個字符串V5VDSHva7fjyJoJ33IQl。然後把這個sha256加密後做gate提交,就可以了

Baby_Spider

學到很多東西的一題,題目明確爬蟲+python3來做,開始毫無頭緒,後來看了大佬的wp,知道了這裡有兩個反扒機制,一個是攜程用的css來打亂顯示數字,一個是使用字體替換來反扒。然後做了早就想開坑的selenuim,這次用了requestsselenuim兩種方法來做這道題,可以說是收穫良多了。

# selenuim方法
from selenium import webdriver

url = 'http://111.231.140.29:10000/'

driver = webdriver.Chrome("chromedriver.exe")
driver.get(url)

start_input = driver.find_element_by_name('token') #獲取輸入框
start_button = driver.find_element_by_tag_name('button') #獲取點擊按鈕

start_input.send_keys('your token') #輸入你的token
start_button.click()

def calc(value):
    answer = eval(str(value))
    submit = driver.find_element_by_tag_name('button')
    value_input = driver.find_element_by_name('answer')
    value_input.send_keys(str(answer))
    submit.click()

for i in range(0,30):
    if i <10:
        value = driver.find_element_by_class_name('question-container').text.split('=')[0]
        calc(value)
    if i >= 10 and i < 20:
        cal = driver.find_element_by_class_name('question-container').text.split('=')[0]
        intab = "1234567890"
        outtab = "0269435871"
        trantab = str.maketrans(intab, outtab)
        cal = cal.translate(trantab)
        """
            這裡是開始不知道有翻譯表這個方法的時候想的方法,畢竟也想了那麼久。。。記錄一下
        """
        #    key_values = {
        #   '1':'0',
        #   '2':'2',
        #   '3':'6',
        #   '4':'9',
        #   '5':'4',
        #   '6':'3',
        #   '7':'5',
        #   '8':'8',
        #   '9':'7',
        #   '0':'1',
        # }
        # for j in range(len(cal)):
        #   if key_values.__contains__(cal[j]):
        #       cal = cal[:j] + key_values[cal[j]] + cal[j+1:]
        #   else:
        #       cal = cal[:j] + cal[j] + cal[j+1:]
        calc(cal)
    if i >= 20:
        # 這裡使用js獲取偽元素的content的值
        js = "var h3 = document.querySelector('.question-container');var result= getComputedStyle(h3, '::after').content;return result;"
        result = driver.execute_script(js)
        result = result.replace("=?", "")
        result = result.replace(""", "")
        calc(result)
# requests方法
import requests
import re

url = 'http://111.231.140.29:10000/'
data = {'token' : 'your token'} #輸入你的token

# 這道題目如果你用requests的話,再後面二十題要加請求頭,不然會被強制關機!。。。。。,應該是有個請求頭檢測
headers = {'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36' ,'Referer': 'http://111.231.140.29:10000/question'}

def get_cookie(req):
    Session = req.headers['Set-Cookie'].split(';')[0]
    return Session

def calc(formula):
    result = eval(str(formula))
    return result

def get_formula_(req,i):
    print("正在計算第%s題..."%str(i))
    template = re.compile('<div class="question-container"><span>(.*?)=?</span></div>',re.S)
    formula = template.findall(req.text)[0]
    print(formula)
    return formula

def tran(formula):
    intab = "1234567890"
    outtab = "0269435871"
    trantab = str.maketrans(intab, outtab)
    formula = formula.translate(trantab)
    return formula

def get_css_formula(css):
    template = re.compile('content:"(.*?)=?";',re.S)
    formula = template.findall(css)[0]
    # print(formula)
    return formula

req = requests.req = requests.post(url, data=data, headers=headers) #第一次請求

req = requests.get(
    url,
    headers={'Cookie':get_cookie(req)}
)
# print(req.text)

for i in range(1,31):
    url = 'http://111.231.140.29:10000/solution'
    formula = get_formula_(req, i)
    if i <= 10:
        Session = get_cookie(req)
        # print(result)
    # print(req.text)
    if  20 >= i > 10:
        formula = tran(formula)
        Session = get_cookie(req)
    if i > 20:
        # 這裡要重新獲取session不然請求的是20題的css得不到content
        Session = get_cookie(req)
        css = requests.get(
            'http://111.231.140.29:10000/statics/style.css',
            headers={'Content-Type': 'application/x-www-form-urlencoded', 'Cookie': Session,
                     'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
                     'Referer': 'http://111.231.140.29:10000/question'}
        ).text
        formula = get_css_formula(css)

    result = calc(formula)
    req = requests.post(
        'http://111.231.140.29:10000/solution', data={'answer': result},
        headers={
            'Content-Type': 'application/x-www-form-urlencoded', 'Cookie': Session,
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36',
            'Referer': 'http://111.231.140.29:10000/question'}
    )
    if 'hgame'in req.text:
        print(req.text)
聲明:本文為原創作品,版權歸作者所有。未經許可,不得轉載或用於任何商業用途。如若本站內容侵犯了原著者的合法權益,可聯繫我們進行處理。

給TA打賞
共{{data.count}}人
人已打賞
0 條回復 A文章作者 M管理員
    暫無討論,說說你的看法吧