@@ -12,7 +12,14 @@ type Talk = {
1212 url : string ;
1313} ;
1414
15- const talks : Talk [ ] = [
15+ type TalkSection = {
16+ title : "Workshops" | "General Tradecraft" ;
17+ description : string ;
18+ badge : string ;
19+ talks : Talk [ ] ;
20+ } ;
21+
22+ const workshopTalks : Talk [ ] = [
1623 {
1724 title : "Building Traffic Encoders" ,
1825 description : "From concept to practical encoder strategy in Sliver." ,
@@ -23,11 +30,34 @@ const talks: Talk[] = [
2330 description : "Workflow patterns for payload staging and repeatable ops." ,
2431 url : "https://www.youtube.com/watch?v=vuQ5tG5kelI&feature=youtu.be" ,
2532 } ,
33+ ] ;
34+
35+ const generalTradecraftTalks : Talk [ ] = [
2636 {
2737 title : "Offensive WASM" ,
2838 description : "Applying WebAssembly techniques in offensive tradecraft." ,
2939 url : "https://www.youtube.com/watch?v=RnSLsnP4imQ" ,
3040 } ,
41+ {
42+ title : "The Sliver C2 Framework" ,
43+ description : "General discussion of C2 design." ,
44+ url : "https://www.youtube.com/watch?v=tkjMZuZ_8nw" ,
45+ }
46+ ] ;
47+
48+ const talkSections : TalkSection [ ] = [
49+ {
50+ title : "Workshops" ,
51+ description : "Hands-on workshop recordings focused on Sliver workflows." ,
52+ badge : "Workshop" ,
53+ talks : workshopTalks ,
54+ } ,
55+ {
56+ title : "General Tradecraft" ,
57+ description : "Broader offensive engineering and tradecraft talks." ,
58+ badge : "Tradecraft" ,
59+ talks : generalTradecraftTalks ,
60+ } ,
3161] ;
3262
3363const TalksIndexPage : NextPage = ( ) => {
@@ -45,50 +75,60 @@ const TalksIndexPage: NextPage = () => {
4575 < title > Sliver Talks</ title >
4676 </ Head >
4777 < div className = "mt-6 px-4 pb-8 sm:px-6 lg:px-12" >
48- < div className = "mb-4" >
49- < h1 className = "text-3xl font-semibold" > Talks</ h1 >
50- < p className = "mt-2 text-sm text-default-500" >
51- Talks and demos from the Sliver ecosystem.
52- </ p >
53- </ div >
54- < div className = "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-9" >
55- { talks . map ( ( talk ) => (
56- < div key = { talk . url } className = "sm:col-span-1 lg:col-span-3" >
57- < Card isFooterBlurred className = "relative z-0 overflow-hidden" >
58- < CardHeader className = "absolute z-10 top-1 flex-col items-end" >
59- < p className = "text-xs text-white/70 uppercase font-bold" > Talk</ p >
60- < p className = "text-sm text-right text-white" > { talk . title } </ p >
61- </ CardHeader >
78+ { talkSections . map ( ( section , sectionIndex ) => {
79+ return (
80+ < section
81+ key = { section . title }
82+ className = { sectionIndex === 0 ? "" : "mt-8" }
83+ aria-label = { section . title }
84+ >
85+ < div className = "mb-4" >
86+ < h2 className = "text-3xl font-semibold" > { section . title } </ h2 >
87+ < p className = "mt-2 text-sm text-default-500" > { section . description } </ p >
88+ </ div >
89+ < div className = "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-9" >
90+ { section . talks . map ( ( talk ) => (
91+ < div key = { talk . url } className = "sm:col-span-1 lg:col-span-3" >
92+ < Card isFooterBlurred className = "relative z-0 overflow-hidden" >
93+ < CardHeader className = "absolute z-10 top-1 flex-col items-end" >
94+ < p className = "text-xs text-white/70 uppercase font-bold" >
95+ { section . badge }
96+ </ p >
97+ < p className = "text-sm text-right text-white" > { talk . title } </ p >
98+ </ CardHeader >
6299
63- < Youtube
64- className = "w-full"
65- url = { talk . url }
66- title = { talk . title }
67- onPlay = { ( ) => hideFooterFor ( talk . url ) }
68- />
100+ < Youtube
101+ className = "w-full"
102+ url = { talk . url }
103+ title = { talk . title }
104+ onPlay = { ( ) => hideFooterFor ( talk . url ) }
105+ />
69106
70- { footerHidden [ talk . url ] ? null : (
71- < CardFooter className = "absolute bottom-0 z-10 bg-black/40 border-t-1 border-default-600 dark:border-default-100" >
72- < div className = "flex w-full items-center gap-2" >
73- < p className = "text-xs text-white/80" > { talk . description } </ p >
74- < Button
75- variant = "ghost"
76- color = "warning"
77- size = "sm"
78- className = "ml-auto"
79- onPress = { ( ) => {
80- window . open ( talk . url , "_blank" , "noopener,noreferrer" ) ;
81- } }
82- >
83- Watch < FontAwesomeIcon icon = { faChevronRight } />
84- </ Button >
85- </ div >
86- </ CardFooter >
87- ) }
88- </ Card >
89- </ div >
90- ) ) }
91- </ div >
107+ { footerHidden [ talk . url ] ? null : (
108+ < CardFooter className = "absolute bottom-0 z-10 bg-black/40 border-t-1 border-default-600 dark:border-default-100" >
109+ < div className = "flex w-full items-center gap-2" >
110+ < p className = "text-xs text-white/80" > { talk . description } </ p >
111+ < Button
112+ variant = "ghost"
113+ color = "warning"
114+ size = "sm"
115+ className = "ml-auto"
116+ onPress = { ( ) => {
117+ window . open ( talk . url , "_blank" , "noopener,noreferrer" ) ;
118+ } }
119+ >
120+ Watch < FontAwesomeIcon icon = { faChevronRight } />
121+ </ Button >
122+ </ div >
123+ </ CardFooter >
124+ ) }
125+ </ Card >
126+ </ div >
127+ ) ) }
128+ </ div >
129+ </ section >
130+ ) ;
131+ } ) }
92132 </ div >
93133 </ >
94134 ) ;
0 commit comments