1. 1. 0x00 前言
  2. 2. 0x01 直接查看源代码
    1. 2.1. 题目:http://ctf5.shiyanbar.com/10/main.php
    2. 2.2. 解题方法:
  3. 3. 0x02 查看修改或添加HTTP请求头响应头
    1. 3.1. 题目:http://ctf5.shiyanbar.com/phpaudit/
    2. 3.2. 解题方法:
  4. 4. 0x03 302跳转的中转网页有信息
    1. 4.1. 题目:
    2. 4.2. 解题方法:
  5. 5. 0x04 查看开发者工具控制台
    1. 5.1. 题目:http://ctf5.shiyanbar.com/DUTCTF/1.html
    2. 5.2. 解题方法:
  6. 6. 0x05 js代码,js加解密
    1. 6.1. 题目:
    2. 6.2. 解题方法:
  7. 7. 0x06 使用Burpsuite拦截
    1. 7.1. 题目:http://ctf5.shiyanbar.com/basic/catch/
    2. 7.2. 解题方法:
  8. 8. 0x07 robots.txt
    1. 8.1. 题目:
    2. 8.2. 解题方法:
  9. 9. 0x08 asp,php代码审计
    1. 9.1. 题目一:http://ctf5.shiyanbar.com/web/more.php
    2. 9.2. 解题方法:
  10. 10. 0x09 SQL注入
    1. 10.1. 题目:http://ctf5.shiyanbar.com/web/index_2.php
    2. 10.2. 解题方法:
  11. 11. 0x0A 简单脚本使用
    1. 11.1. 题目:http://ctf5.shiyanbar.com/web/10/10.php
    2. 11.2. 解题方法:
  12. 12. 0x0B 后台登录
    1. 12.1. 题目:http://ctf5.shiyanbar.com/web/pcat/index.php
    2. 12.2. 解题方法:
  13. 13. 0x0C 代码逆向
    1. 13.1. 题目:
    2. 13.2. 解题方法:
  14. 14. 0x0D 上传绕过
    1. 14.1. 题目:http://ctf5.shiyanbar.com/web/upload/
    2. 14.2. 解题方法:
  15. 15. 0x0E hash函数
    1. 15.1. 题目:http://ctf5.shiyanbar.com/web/false.php
    2. 15.2. 解题方法:
  16. 16. 0x0F 备份文件
    1. 16.1. 题目:http://ctf5.shiyanbar.com/10/upload/step1.php
    2. 16.2. 解题方法:
  17. 17. 0x11 验证码
    1. 17.1. 题目:
    2. 17.2. 解题方法:
  18. 18. 0x12 cookie
    1. 18.1. 题目:http://ctf5.shiyanbar.com/web/Session.php
    2. 18.2. 解题方法:
  19. 19. 0x13 MD5碰撞
    1. 19.1. 题目:http://ctf5.shiyanbar.com/web/kzhan.php
    2. 19.2. 解题方法:
  20. 20. 0x14 总结

CTF之web总结

0x00 前言

      身为一只web小白,但也刷了不少CTF方面的web题,趁着今天有时间,坐下来总结一下关于web的解题方法。

0x01 直接查看源代码

题目:http://ctf5.shiyanbar.com/10/main.php

解题方法:


点击右键,查看页面源代码

hidden改为text,value=0改为value=1,点击Enter。出现下图:

这段代码的意思就是,将我们传给PIN的值给a,如果a=-19827747736161128312837161661727773716166727272616149001823847,输出flag。因此,我们直接将该值输入进去,点击Enter即可。

0x02 查看修改或添加HTTP请求头响应头

题目:http://ctf5.shiyanbar.com/phpaudit/

解题方法:


点击View the source code,

从这段代码可以看出,只要IP为1.1.1.1,即可输出flag。
用burpsuite抓包,在请求头中添加X-Forwarded-For:1.1.1.1,

然后GO即可,

0x03 302跳转的中转网页有信息

题目:

解题方法:

0x04 查看开发者工具控制台

题目:http://ctf5.shiyanbar.com/DUTCTF/1.html

解题方法:

进去之后发现是一片乱字符,其实不难发现这是js代码,这就可以用到我们的控制台了,复制代码,按F12,

回车

0x05 js代码,js加解密

题目:

解题方法:

0x06 使用Burpsuite拦截

题目:http://ctf5.shiyanbar.com/basic/catch/

解题方法:


在输入框中随便输入123,发现报错,然后尝试抓包,发现响应头返回一个字符串MTU1MzA5MzkzOA==

然后将该字符串提交,即得flag。

其实该字符串是经过base64加密的,解密后是1553093938

0x07 robots.txt

题目:

解题方法:

0x08 asp,php代码审计

题目一:http://ctf5.shiyanbar.com/web/more.php

解题方法:


点击查看源代码,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
if (isset ($_GET['password'])) {
if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)
{
echo '<p>You password must be alphanumeric</p>';
}
else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999)
{
if (strpos ($_GET['password'], '*-*') !== FALSE)
{
die('Flag: ' . $flag);
}
else
{
echo('<p>*-* have not been found</p>');
}
}
else
{
echo '<p>Invalid password</p>';
}
}
?>

从这段代码中,可以看出要想得到flag,必须满足以下几个条件:

  1. 输入的password必须是“a-zA-Z0-9]+$”中的
  2. password必须长度小于8
  3. password的值必须大于999999999
  4. password必须包含字符串*-*

      对于前三个条件,我们可以用科学计数法password=9e9,最后一个条件,其实ereg()函数有一个截断漏洞,我们可以用%00截断,让password=9e9%00*-*。在提交password的时候我们发现并不会出现flag,这是因为浏览器修改了传进去的参数,我们直接在url后面传参即可。

题目二:http://ctf5.shiyanbar.com/DUTCTF/index.php
解题方法:

出来这么一句话,查看源代码,源代码简单的不能再简单了。

但我们发现了这么一个文件index.php.txt,二话不说放进url试试,哎,出现了php源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
if(eregi("hackerDJ",$_GET[id])) {
echo("<p>not allowed!</p>");
exit();
}

$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "hackerDJ")
{
echo "<p>Access granted!</p>";
echo "<p>flag: *****************} </p>";
}
?>

      这段代码的意思就是说,我们传进去的id经过url解密之后与hackerDJ是一样的,不说废话,行动起来,hackerDJ经url加密之后是%68%61%63%6b%65%72%44%4a,传进去之后依然不行,这是因为浏览器会自动对url进行解码,嗯,所以我们要进行二次加密,再次加密之后变为%25%36%38%25%36%31%25%36%33%25%36%62%25%36%35%25%37%32%25%34%34%25%34%61

0x09 SQL注入

题目:http://ctf5.shiyanbar.com/web/index_2.php

解题方法:


既然是SQL注入,那么我们就要构造注入语句了,这个就要有耐心一个一个去尝试了
输入语句

1'and 1=1 #

1'and/**/1=1/**/#

对比一下,发现是过滤掉了空格,我们用/**/代替空格
下面就要构造找flag的语句了

1'/**/union/**/select/**/flag/**/from/**/flag#

最后就能找到flag了,(其实这里面还有一些步骤,用SQLMap跑啊跑~)

0x0A 简单脚本使用

题目:http://ctf5.shiyanbar.com/web/10/10.php

解题方法:


查看源代码

这句话的意思就是,让我们传一个参数key.
根据前面的提示,看响应头

这个FLAG明显是经过base64加密的,解码之后P0ST_THIS_T0_CH4NGE_FL4G:Lx17DdQma
用脚本跑一下,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import re
import requests
import base64
import io
import sys

r = requests.Session() #因为reqests请求的和post提交的数据要保持一致
sys.stdout = io.TextIOWrapper(sys.stdout.buffer,encoding='utf-8') #改变默认输出的编码
html = r.head('http://ctf5.shiyanbar.com/web/10/10.php')
result = html.headers
results = result['FLAG']
print(results)
de_results = str(base64.b64decode(results.encode('utf-8')))
print(de_results)
data = de_results.split(':',1)[1]
datas = data.replace('\'', '')
print(datas)
flag = {'key':datas}
flags = r.post('http://ctf5.shiyanbar.com/web/10/10.php', data=flag)
print(flags.text)

0x0B 后台登录

题目:http://ctf5.shiyanbar.com/web/pcat/index.php

解题方法:


查看源代码

这点的意思是:原来的程序员在写网页时给自己的一个提醒是源码在这个地方,我们要查看时将source.txt复制到当前地址栏里替换index.php,然后回车
就能看到源码了:

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?php
error_reporting(0);

if (!isset($_POST['uname']) || !isset($_POST['pwd'])) {
echo '<form action="" method="post">'."<br/>";
echo '<input name="uname" type="text"/>'."<br/>";
echo '<input name="pwd" type="text"/>'."<br/>";
echo '<input type="submit" />'."<br/>";
echo '</form>'."<br/>";
echo '<!--source: source.txt-->'."<br/>";
die;
}

function AttackFilter($StrKey,$StrValue,$ArrReq){
if (is_array($StrValue)){
$StrValue=implode($StrValue);
}
if (preg_match("/".$ArrReq."/is",$StrValue)==1){
print "姘村彲杞借垷锛屼害鍙禌鑹囷紒";
exit();
}
}

$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";
foreach($_POST as $key=>$value){
AttackFilter($key,$value,$filter);
}

$con = mysql_connect("XXXXXX","XXXXXX","XXXXXX");
if (!$con){
die('Could not connect: ' . mysql_error());
}
$db="XXXXXX";
mysql_select_db($db, $con);
$sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'";
$query = mysql_query($sql);
if (mysql_num_rows($query) == 1) {
$key = mysql_fetch_array($query);
if($key['pwd'] == $_POST['pwd']) {
print "CTF{XXXXXX}";
}else{
print "浜﹀彲璧涜墖锛�";
}
}else{
print "涓€棰楄禌鑹囷紒";
}
mysql_close($con);
?>

在这代码中有意思的地方是:

1
2
3
4
$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";
foreach($_POST as $key=>$value){
AttackFilter($key,$value,$filter);
}

他将这些sql注入的语句禁止了

1
2
3
4
5
6
7
8
9
10
11
$sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'";
$query = mysql_query($sql);
if (mysql_num_rows($query) == 1) {
$key = mysql_fetch_array($query);
if($key['pwd'] == $_POST['pwd']) {
print "CTF{XXXXXX}";
}else{
print "浜﹀彲璧涜墖锛�";
}
}else{
print "涓€棰楄禌鑹囷紒";

这一部分的语句是说将输入进来的用户名与库里的进行对比,如果正确就输出flag,否则就会报错
那么接下来我们应该怎么做呢?
我们进行SQL注入:

' or 1=1 group by pwd with rollup limit 1 offset 2 #

在这句语句中

' or 1=1 我们都知道这是注入的一个常用语句,异或为真,恒成立

group by pwd with rollup 这句是sql里的添加一行,使得密码为空

limit 1 是查询的意思,查询第一行

offset 2 是从第二条数据开始查询

将这条语句输入到第一个框内,提交查询就可以的出flag,如果输入其他就会报错

0x0C 代码逆向

题目:

解题方法:

0x0D 上传绕过

题目:http://ctf5.shiyanbar.com/web/upload/

解题方法:


随便上传一个1.jpg文件

上传一个1.php文件

显然我们上传的文件被截断了,这就让我们想到了%00截断。%00一般被认为是结束的标志,其后的东西都被认为是不存在的。抓包

将上传的1.php文件改为1.jpg,在/uploads/后面添加1.php .jpg,并且在hex模块将空格所对应的十六进制20改为00,然后GO。

得到flag

0x0E hash函数

题目:http://ctf5.shiyanbar.com/web/false.php

解题方法:


查看源码

1
2
3
4
5
6
7
8
9
10
11
12
<?php
if (isset($_GET['name']) and isset($_GET['password'])) {
if ($_GET['name'] == $_GET['password'])
echo '<p>Your password can not be your name!</p>';
else if (sha1($_GET['name']) === sha1($_GET['password']))
die('Flag: '.$flag);
else
echo '<p>Invalid password.</p>';
}
else{
echo '<p>Login first!</p>';
?>

这段代码的意思就是,输入的namepassword经过sha1()函数加密后相等,但二者不一样。
应该利用false===false,md5 和 sha1 无法处理数组,但是 php 没有抛出异常,直接返回 fasle
payload:?name[]=1&password[]=123

0x0F 备份文件

题目:http://ctf5.shiyanbar.com/10/upload/step1.php

解题方法:


我们先输入一个邮箱试试,发现不行

查看源代码

我们发现了管理员邮箱,也知道了这是用vim写的文件。
哎,我们刚才还发现了一个step2.php,试试。
结果页面一闪而过,嗯,有猫腻,抓包。

抓到一个submit.php,试试,不行。
用过Linux的vim的都知道,vim会产生一个临时文件.submit.php.swp。这是一个隐藏文件。

这段代码是说,我们需要传入tokenemailAddresstoken必须长度为10,大小为0,可令token=0000000000,或用科学计数法,正好,我们刚才发现一个管理员邮箱。

0x11 验证码

题目:

解题方法:

题目:http://ctf5.shiyanbar.com/web/Session.php

解题方法:


查看源代码

1
2
3
4
5
6
7
8
9
10
11
12

<?php
session_start();
if (isset ($_GET['password'])) {
if ($_GET['password'] == $_SESSION['password'])
die ('Flag: '.$flag);
else
print '<p>Wrong guess.</p>';
}

mt_srand((microtime() ^ rand(1, 10000)) % rand(1, 10000) + rand(1, 10000));
?>

这段代码的关键就在于:password = $_session['password']
Cookie与 Session,一般都会认为这是两个独立完全不同的东西,Session采用的是在服务器端保持状态的方案,而Cookie采用的是在客户端保持状态的方案。在PHP配置中的默认情况下,Session是用Session ID来确定当前对话所对应的服务器Session,而Session ID是通过Cookie来传递的,禁用Cookie相当于失去了Session ID,也就得不到Session了。

用Burpsuite抓包

从抓包的内容中我们就能看见在Cookie中已经是包含了Sessid,并且发送的password在URL中以Get的方式传值。

那这里我们就可以以这样的思路来求解。首先我们删除所有的Cookie,将PHPSessid值直接删掉,这样的结果就会使得$_session['password']值为空,接下来我们将URL中的password值清空,这样我们就能达到password = $_session['password']的效果。

0x13 MD5碰撞

题目:http://ctf5.shiyanbar.com/web/kzhan.php

解题方法:


随便输入一些东西,发现什么都没有,抓包

哎,我们发现有一个source=0,改成source=1试试

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
26
27
28
29
30
31
$flag = "XXXXXXXXXXXXXXXXXXXXXXX";
$secret = "XXXXXXXXXXXXXXX"; // This secret is 15 characters long for security!

$username = $_POST["username"];
$password = $_POST["password"];

if (!empty($_COOKIE["getmein"])) {
if (urldecode($username) === "admin" && urldecode($password) != "admin") {
if ($COOKIE["getmein"] === md5($secret . urldecode($username . $password))) {
echo "Congratulations! You are a registered user.\n";
die ("The flag is ". $flag);
}
else {
die ("Your cookies don't match up! STOP HACKING THIS SITE.");
}
}
else {
die ("You are not an admin! LEAVE.");
}
}

setcookie("sample-hash", md5($secret . urldecode("admin" . "admin")), time() + (60 * 60 * 24 * 7));

if (empty($_COOKIE["source"])) {
setcookie("source", 0, time() + (60 * 60 * 24 * 7));
}
else {
if ($_COOKIE["source"] != 0) {
echo ""; // This source code is outputted here
}
}

源代码出来了。
想要获得flag,需要满足几个条件:
1.urldecode($username) === "admin"

2.urldecode($password) != "admin"

3.$COOKIE["getmein"] === md5($secret . urldecode($username . $password))
其中$secret是长度为15的未知字符串,而条件1、2很好满足,条件3则需要进行哈希长度扩展攻击来满足关于什么是哈希长度扩展攻击,怎么进行的可以看下面这个链接:https://github.com/iagox86/hash_extender

cookie中可以看到sample-hash=571580b26c65f306376d4f64e53cb5c7
这是$secret跟两个admin连接后的字符串的哈希值,md5(???????????????adminadmin),新字符串长度为25。我们要提交的username必定为admin,也就是说,我们提交的getmein必须是$secret跟admin以及$password连接后的字符串的哈希值。

0x14 总结

遇到不会的函数可以自己百度