The source and binary releases v3.0 are available for clone and download.
The official version 3.0 has been released yesterday.
Here is a link to the repository: https://asm32.info/fossil/asmbb/timeline?t=v3.0
The binary package
You can download the recent binary package from the permanent link: asmbb.tar.gz
What is AsmBB?
AsmBB is very fast and lightweight web forum engine. (You are reading this article on AsmBB demo forum).
AsmBB is fully written in assembly language and uses SQLite as a database back-end. That is why it can work on really weak hosting and in the same time serve huge amount of visitors without lags and delays.
AsmBB is very secure web application, because of the internal design and the reduced dependencies. But it also supports encrypted databases, for even higher security.
In addition, AsmBB has very few requirements to the running environment:
x86 Linux server.
No matter 32 or 64bit. No need to have any specially preinstalled libraries.
The smallest/cheapest VPS is fine. Shared hosting is fine as well (if supports FastCGI).
A web server supporting FastCGI interface. AsmBB has been tested with Nginx, Apache, Lighttpd, Hiawatha and of course RWASA.
AsmBB is easy for customizing and modifying - it uses pretty powerful template system that allows easy customizing of the forum without actually modifying the code. (which is not so hard though).
Install
The installation instructions are the same as in the older versions:
How to install AsmBB on VPS with Nginx and systemd
or here:
AsmBB how to download, compile and install
The most important changes.
Many new features was added. Direct paste images as an attachments, support for YouTube video embedding, unified post/thread editor (which simplifies the code and the templates), threads ranking.
The skin "Modern" was removed from the project, because of its low quality.
v3.0 introduces incompatibilities with the older versions.Both in database and template structures. How to migrate, see later in this post.
Because of the SQLeet project discontinuation, was added support for SQLite3MultipleCiphers encryption extension. (the binary release package is compiled with it)
All the bugs and vulnerabilities revealed was fixed. The most several bugs was discovered as a result of the hxp CTF event. It is a work of 181 CTF teams.
🥇 justCatTheFish
🥈 idek
🥉 Never Stop Expliting
Katzebin
copy
Blue Water
796f75
Decrypt the database, before modifying. Notice, that the new SQLite3MultipleCiphers library is used in a mode not compatible with the previous SQLeet library. You must decrypt the database before migrating to v3.0 and then you can encrypt it again with the new library.
Make a backup in case something goes wrong.
Execute in the SQLite console the following commands (simply copy and paste, there is no parameters to adjust):
After updating the database scheme you can stop the engine and replace the binary files (
engine
,ld-musl-i386.so
andlibsqlite3.so
)While engine stopped, replace the whole
templates/
directory with the new one.Start the engine again.
Check the updated forum for problems.
If everything seems to works OK, you can encrypt the database again (if you prefer so) from the AsmBB settings page.
Only 7 teams out of 181 solved the challenge and found some vulnerabilities in AsmBB. Кudos to the winners!
(The team Straw Hat solved the task, but found vulnerability in the test bot (in Python), not in AsmBB. So, it is not in the above list.)
Update of the database from v2.9.1 to v3.0:
As long as the database structure was changed, before updating the binaries to v3.0, modify the existing databases:
insert into Params values ('nu_post_interval', 0);
insert into Params values ('nu_post_interval_inc', 0);
insert into Params values ('nu_max_post_length', 0);
alter table Users add column LastPostTime integer default 0;
alter table Users add column PostInterval integer default 0;
alter table Users add column PostIntervalInc integer default 0;
alter table Users add column MaxPostLen integer default 0;
alter table Attachments add column userID integer references Users(id) on delete cascade;
create index idxAttachmentsCombined on Attachments(postID, userID);
create unique index idxAttachmentsUnique2 on Attachments(userID, md5sum);
drop index idxUserLogGroup;
alter table Threads add column Rating integer default 0;
create table ThreadVoters (
threadID integer references Threads(id) on delete cascade on update cascade,
userID integer references Users(id) on delete cascade on update cascade,
Vote integer
);
create unique index idxThreadVoters on ThreadVoters(threadID, userID);
create trigger ThreadVotersAU after update on ThreadVoters begin
update Threads set Rating = Rating - old.Vote + new.Vote where id = new.threadID;
end;
create trigger ThreadVotersAD after delete on ThreadVoters begin
update Threads set Rating = Rating - old.Vote where id = old.threadID;
end;
create trigger ThreadVotersAI after insert on ThreadVoters begin
update Threads set Rating = Rating + new.Vote where id = new.threadID;
end;
drop trigger PostsAI;
drop trigger PostsAD;
CREATE TRIGGER PostsAI AFTER INSERT ON Posts BEGIN
insert into PostFTS(rowid, Content, Caption, slug, user, tags) VALUES (
new.id,
new.Content,
(select Caption from Threads where id=new.threadid),
(select slug from Threads where id = new.threadid),
ifnull((select nick from users where id = new.userid), new.anon),
(select group_concat(TT.Tag, ", ") from ThreadTags TT where TT.threadID = new.threadid)
);
insert into PostCNT(postid,count) VALUES (new.id, 0);
insert or ignore into ThreadPosters(firstPost, threadID, userID) values (new.id, new.threadID, new.userID);
update Users set PostCount = PostCount + 1, LastPostTime = strftime('%s', 'now'), PostInterval = max(0, PostInterval + PostIntervalInc) where Users.id = new.UserID;
update Threads set PostCount = PostCount + 1 where id = new.threadID;
update Counters set val = val + 1 where id = 'posts';
update Tags set PostCnt = PostCnt + 1 where Tags.tag in (select tag from ThreadTags where ThreadID = new.ThreadID);
END;
CREATE TRIGGER PostsAD AFTER DELETE ON Posts BEGIN
delete from PostFTS where rowid = old.id;
delete from ThreadPosters where threadid = old.threadid and userid = old.userid;
insert or ignore into ThreadPosters(firstPost, threadID, userID) select min(id), threadid, userid from posts where threadid = old.threadid and userid = old.userid;
update Users set PostCount = PostCount - 1 where Users.id = old.UserID;
update Threads set PostCount = PostCount - 1, LastChanged = (select max(P.postTime) from posts as P where P.threadID = old.threadID) where id = old.threadID;
update Counters set val = val - 1 where id = 'posts';
update Tags set PostCnt = PostCnt - 1 where Tags.tag in (select tag from threadtags where threadid = old.threadid);
insert or ignore into PostsHistory(postID, threadID, userID, anon, postTime, editUserID, editTime, format, Content) values (
old.id,
old.threadID,
old.userID,
old.anon,
old.postTime,
old.editUserID,
old.editTime,
old.format,
old.Content
);
END;
insert into Messages VALUES ('error_too_early','Simple, deep, and still.
The old masters were patient.
Without desires.','Try to do it later!',NULL);