2019河南省“天安杯” wp

总结总结,好多新的知识点以前没学到

你想要越权访问

直接添加XFF头

程序员有点大意

得到.git文件后直接git log查看commit记录即可(当时脑袋里只有git show-_-)

爆破吗

首先题目给出了一些字典:

无疑需要爆破了,但是并不能直接使用burp intruder跑,查看POST的数据包,发现token字段的值如果不设为上次请求返回的token值,就会返回data-requesttoken字段,并且页面中提示你的登录花费时间过长,请重试一次

一共有三种返回信息:

1.如果没有及时使用正确的token发起请求,就会回显你的登录花费时间过长,请重试一次。
2.如果token正确,且密码输入错误,返回的状态码为303 See Other
3.密码和token均输入正确

参考文章,使用burpsuite的宏来绕过token的验证;当配置好宏后,在repeter中每次点go发送数据,token值会自动改变。load题目给的字典进行intruder,得到正确密码:

登录后是一个类似云盘的存储系统,Documents文件夹中有个docker-compose.yml,查看内容,发现数据库密码等信息:

进行远程连接:

mysql -h 192.144.182.32 -P 13306 -pxxxxx6ooooo

最后在owncloud数据库、oc_flags表中找到flag

GitLab是个好地方

题目给了两个链接:

不知道当时怎么想的,以为那个站是真的GitLab-_-就没有测,一直在搞输入url的页面,以后再遇到这种仿站的一定要去扫一下目录。。

扫描得到/explore,访问后在“最多星标”处找到题目源码:

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
49
50
51
52
<?php
session_start();

function get_contents($url) {

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_MAXREDIRS, 0);
curl_setopt($curl, CURLOPT_TIMEOUT, 3);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 3);
curl_setopt($curl, CURLOPT_RESOLVE, array($host . ":" . $port . ":" . $ip));
curl_setopt($curl, CURLOPT_PORT, $port);

$data = curl_exec($curl);

if (curl_error($curl)) {
error(curl_error($curl));
}

$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($status >= 301 and $status <= 308) {
$url = curl_getinfo($curl, CURLINFO_REDIRECT_URL);
} else {
return $data;
}

}

function error($s) {
clear_directory();
die("<h2><b>ERROR</b></h2> " . htmlspecialchars($s));
}

$msg = "";
if (isset($_GET["url"])&&"0769cdd4c5a9d8142a08373826c87baa"==md5($_GET["pass"])) {
$msg = get_contents($_GET["url"]);
}
?>

<html>
<head><title>找flag!</title></head>
<body>
<form>
<h1>猜一猜flags在哪里!</h1>
<p><b>请输入URL:</b></p>
<p><input type="text" size="100" name="url"></p>
<p><input type="submit" value="提交"></p>
</form>
<?php if (!empty($msg)) echo "<hr><p>" . $msg . "</p>"; ?>
</body>
</html>

解密md50769cdd4c5a9d8142a08373826c87baa,得到ctfun,之后进行SSRF,直接访问本地文件系统;那么flag在哪个位置呢?可以发现除了有index.php,还有个dockerfile文件:

FROM ubuntu:16.04

ENV DEBIAN_FRONTEND noninteractive
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list

RUN apt-get -y update && apt-get -y install curl wget zip  apache2 apt-transport-https php php-curl php-pclzip libapache2-mod-php && rm -rf /var/lib/apt/lists/*

ENV WEBROOT /var/www/html

COPY 000-default.conf /etc/apache2/sites-enabled/000-default.conf
COPY index.php /var/www/html/

RUN chown -R www-data /var/www/html/ 

COPY ./start.sh /start.sh
COPY ./flag.txt /flag.txt
RUN chmod 777 /start.sh

CMD ["/start.sh"]

COPY ./flag.txt /flag.txt得出flag在根目录下,构造payload即可:

?url=file:///flag.txt&pass=ctfun

这题有点难

查看页面源码,发现:

<script>
      var spawn_motivation = function() {
        var id = Math.floor(Math.random() * 6);
        document.location = document.location.origin + "/index.php?id=" + id;
      }
</script>

那么尝试构造参数?id=1,显示两个字,就干,那么无疑是sql注入了;

1.构造?id=-1-%23,显示Attack detected
2.构造参数如果不符合sql关键词的语句或使用单双引号,返回状态码500

构造?id=1^2,显示的内容等于?id=3的内容,那么注入类型就是整型注入了;使用order byunion select时显示Attack detected

看wp,发现这道题他喵的也能用POST注入,而且绕过所利用的知识点应该是绕过最大正则回溯限制:

1
2
3
4
5
6
7
8
import requests

url = 'http://192.144.182.32:20007/?id='

payload = {'id': '100' + ' union/*' + 'a'*1000000 + '*/select database()'}

s = requests.post(url, data=payload).text
print(s)

当使用上述payload进行GET注入时,会显示The requested URL's length exceeds the capacity limit for this server.

misc1

challenge.txt:

a  aa a a aa  a a  a a  a a a a a  aa   a a a a a   aa  a aa  a a a      aaaa a a   aa  a aa  a a aa  a  aa  aa a  a a  a a aaa a  aaa   aa  a  a     a  aaaa a a a a   a a a   a a aa  a a a   a  a    a a  aa a a aaa a  aa    aaaa a  aaaa a a a aa  a a aaa a a aa  a  a aa a   a a  aa a a a a  aa a    aa  aaaa a  aaaa a

将a转为1,空格转为0,再转str:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from Crypto.Util.number import long_to_bytes

f = open('challenge.txt', 'r').read()
#print(f)

s = ''
for i in f:
if i == 'a':
s += '1'
elif i == ' ':
s += '0'

h = long_to_bytes(int(s, 2))
print(h)

得到:

MJLFPFYJNATVHW=VVES=YUUY=Y3W2=TTSL=WK5C=

栅栏解密,得到:

MFTVYYTWJYVVU3TKLJHEUWS5FNWSY2LCPA======

base32解码,得到:

ag\bvN+ZnjZNJZ]+m,ibx

ascii移位解密:

ag\b
flag

移动位数为5,脚本:

1
2
3
4
s = r'ag\bvN+ZnjZNJZ]+m,ibx'
for i in s:
i = ord(i)+5
print(chr(i), end='')

misc2

描述:爆破是不存在的

下载下来一个压缩包,压缩包里有三个文件:

flag.txt
sha512.txt
test.pdf

需要密码才能查看里面的内容,猜测伪加密,将三个标志位09 00改为00 00,解压后得到一个test.pdf

在windows下使用word打开,可以发现有张二维码图片被隐藏在了白色画布下面,扫描二维码,得到:

CF4A69845D051155F2D391B3934863D5CD7C1B7F966A6D002076514C143A28D03E1C262CEEC11D84365726E95402CC2EADD4CA09ECB8F596BE368BDB328C5F0D

猜测其内容为sha512.txt文件的内容,之后压缩test.pdfsha512.txt,进行明文攻击,得到flag.txt

misc3

题目给了一个access.log日志文件,仔细观察发现里面有两种看起来有用的记录,一种urldecode后如下:

还有一种解码后如下:

那么第二种应该与flag相关了,查找所有含有dvwa.flag的记录:

1
2
3
4
5
6
7
8
import urllib.parse
import re

f = open('access.log', 'r').readlines()
for i in f:
s = urllib.parse.unquote(i)
if 'dvwa.flag' in s:
print(s)

发先有很多,统计下共有的条数:

1
2
3
4
5
6
7
8
9
10
import urllib.parse

f = open('access.log', 'r').readlines()
n = 0
for i in f:
s = urllib.parse.unquote(i)
if 'dvwa.flag' in s:
n += 1

print(n)

输出384,flag数据当然没有这么多,仔细观察这些数据,发现有的数据中的判断号不是>,而是!=,那么继续查看含有!=的数据条数:

1
2
3
4
5
6
7
8
9
10
import urllib.parse

f = open('access.log', 'r').readlines()
n = 0
for i in f:
s = urllib.parse.unquote(i)
if 'dvwa.flag' and '!=' in s:
n += 1

print(n)

输出39,那么这些数据应该为flag了,最后进行提取:

1
2
3
4
5
6
7
8
9
10
import urllib.parse
import re

f = open('access.log', 'r').readlines()
n = 0
for i in f:
s = urllib.parse.unquote(i)
if 'dvwa.flag' and '!=' in s:
res = re.findall(r"!=(.*?),", s)[0]
print(chr(int(res)), end='')

misc4

压缩包中一共有1024个txt文件,里面内容大都是:

搜索txt中含有{符号的文件,发现有两个:

grep -r '{' ./problem

第一次知道这是键盘加密,将字母转换为拼音九键各字母的位置的坐标:

比如,字母a在数字2的位置的第一个,那么对应的加密就是21;

观察数据,发现第二个文件内容符合flag格式:

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 43 63 31 51 {22 73 92 31 82 42 83 71 31 82 91}00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

将其转换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
s = '43 63 31 51 { 22 73 92 31 82 42 83 71 31 82 91 }'

dic = [[], [], ['', 'a', 'b', 'c'], ['', 'd', 'e', 'f'], ['', 'g', 'h', 'i'], ['', 'j', 'k', 'l'], ['', 'm', 'n', 'o'], ['', 'p', 'q', 'r', 's'], ['', 't', 'u', 'v'], ['', 'w', 'x', 'y', 'z']]

s = s.split(' ')

flag = ''
for i in s:
if i == '{':
flag += '{'
elif i == '}':
flag += '}'
else:
m = int(i[0])
n = int(i[1])
flag += dic[m][n]

print(flag)

得到iodj{brxduhvpduw},进行凯撒解密,得到flag:flag{youaresmart}

crypto1

RSA多素数问题,前段时间总结过了,这里就不再写了

https://www.gtfly.top/2019/08/22/RSA攻击总结/

crypto2

考察费马小定理与多项式展开,同上

crypto3